Before I assumed that bootloaders loaded the kernel at physical address 0, but this patch kinda allows loading to different addresses. This still doesn't fully work as kernel bootstrap paging relies on kernel being loaded at 0
177 lines
2.6 KiB
ArmAsm
177 lines
2.6 KiB
ArmAsm
.include "common.S"
|
|
|
|
.code16
|
|
|
|
#########################################
|
|
#
|
|
# STAGE 1 BOOTLOADER
|
|
#
|
|
# its sole purpose is to load stage2 from
|
|
# bios boot partition
|
|
#
|
|
#########################################
|
|
|
|
.section .stage1
|
|
|
|
.global stage1_main
|
|
stage1_main:
|
|
# setup segments and stack
|
|
xorw %ax, %ax
|
|
movw %ax, %ds
|
|
movw %ax, %es
|
|
movw %ax, %ss
|
|
movl $0x7C00, %esp
|
|
|
|
# save boot disk number
|
|
call read_stage2_into_memory
|
|
|
|
jmp stage2_main
|
|
|
|
.global print_and_halt
|
|
print_and_halt:
|
|
call puts
|
|
halt:
|
|
hlt
|
|
jmp halt
|
|
|
|
|
|
#########################################
|
|
#
|
|
# STAGE 2 BOOTLOADER
|
|
#
|
|
#########################################
|
|
|
|
.section .stage2
|
|
|
|
stage2_main:
|
|
# clear screen and enter 80x25 text mode
|
|
movb $0x03, %al
|
|
movb $0x00, %ah
|
|
int $0x10
|
|
|
|
# print hello message
|
|
movw $hello_msg, %si
|
|
call puts; call print_newline
|
|
|
|
lgdt gdtr
|
|
|
|
call enter_unreal_mode
|
|
movw $unreal_enter_msg, %si
|
|
call puts; call print_newline
|
|
|
|
call enable_a20
|
|
|
|
call get_memory_map
|
|
|
|
call print_newline
|
|
call read_user_command_line
|
|
|
|
call print_newline
|
|
|
|
movw $start_kernel_load_msg, %si
|
|
call puts; call print_newline
|
|
|
|
call print_memory_map
|
|
|
|
call find_root_disk
|
|
call find_root_partition
|
|
|
|
call print_root_partition_info
|
|
call print_newline
|
|
|
|
call has_ext2_filesystem
|
|
testb %al, %al
|
|
jz print_and_halt
|
|
|
|
call ext2_find_kernel
|
|
movl $ext2_inode_read_bytes, %esi
|
|
|
|
call elf_read_kernel_to_memory
|
|
|
|
call vesa_set_video_mode
|
|
|
|
cli
|
|
|
|
# kernel entry point
|
|
movl %eax, %ecx
|
|
|
|
# setup kernel parameters
|
|
movl $0xD3C60CFF, %eax
|
|
movl $banan_boot_info, %ebx
|
|
|
|
# setup protected mode
|
|
movl %cr0, %edx
|
|
orb $1, %dl
|
|
movl %edx, %cr0
|
|
|
|
# jump to protected mode
|
|
ljmpl $GDT_CODE32, $protected_mode
|
|
|
|
.code32
|
|
protected_mode:
|
|
# setup protected mode segments
|
|
movw $GDT_DATA32, %dx
|
|
movw %dx, %ds
|
|
movw %dx, %es
|
|
movw %dx, %fs
|
|
movw %dx, %gs
|
|
movw %dx, %ss
|
|
|
|
# jump to kernel entry
|
|
jmp *%ecx
|
|
|
|
|
|
.code16
|
|
enter_unreal_mode:
|
|
cli
|
|
pushw %ds
|
|
|
|
movl %cr0, %eax
|
|
orb $1, %al
|
|
movl %eax, %cr0
|
|
ljmpl $GDT_CODE16, $.enter_unreal_mode_pmode
|
|
|
|
.enter_unreal_mode_pmode:
|
|
movw $GDT_DATA32, %bx
|
|
movw %bx, %ds
|
|
|
|
andb $0xFE, %al
|
|
movl %eax, %cr0
|
|
ljmpl $0x00, $.enter_unreal_mode_unreal
|
|
|
|
.enter_unreal_mode_unreal:
|
|
popw %ds
|
|
sti
|
|
|
|
ret
|
|
|
|
.section .data
|
|
|
|
hello_msg:
|
|
.asciz "This is banan-os bootloader"
|
|
|
|
unreal_enter_msg:
|
|
.asciz "Entered unreal mode"
|
|
|
|
start_kernel_load_msg:
|
|
.asciz "Starting to load kernel"
|
|
|
|
gdt:
|
|
.quad 0x0000000000000000
|
|
.quad 0x008F9A000000FFFF # 16-bit code
|
|
.quad 0x00CF92000000FFFF # 32-bit data
|
|
.quad 0x00CF9A000000FFFF # 32-bit code
|
|
gdtr:
|
|
.short . - gdt - 1
|
|
.long gdt
|
|
|
|
banan_boot_info:
|
|
boot_command_line:
|
|
.long command_line
|
|
boot_framebuffer:
|
|
.long framebuffer
|
|
boot_memory_map:
|
|
.long memory_map
|
|
boot_kernel_paddr:
|
|
.long 0
|