X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=bootcensus;a=blobdiff_plain;f=src%2Fboot%2Fboot2.s;h=f782d7ef50aca782b0cb16a80bb692e89d3b02dd;hp=59096acd2b5ce7db337e718d5607b451dc730b9b;hb=6e5ec45bc9c248586ec797646158b4caa3aa9d68;hpb=f03c64c0d3c22faa867aaad9243b679f5d1d7819 diff --git a/src/boot/boot2.s b/src/boot/boot2.s index 59096ac..f782d7e 100644 --- a/src/boot/boot2.s +++ b/src/boot/boot2.s @@ -15,6 +15,8 @@ # along with this program. If not, see . # this is the second-stage boot loader +# plus some other code that needs to run below 1mb (int86 implementation). + .code16 .section .boot2,"ax" @@ -613,16 +615,20 @@ e820_looptop: cmp $0x534d4150, %eax jnz e820_fail + # skip areas starting above 4GB as we won't be able to use them + cmpl $0, 4(%edi) + jnz e820_skip + + # only care for type 1 (usable ram), otherwise ignore + cmpl $1, 16(%edi) + jnz e820_skip + mov buffer, %eax mov $boot_mem_map, %esi mov boot_mem_map_size, %ebp # again, that's [ebp * 8 + esi] mov %eax, (%esi,%ebp,8) - # only care for type 1 (usable ram), otherwise ignore - cmpl $1, 16(%edi) - jnz e820_skip - # skip areas with 0 size (also clamp size to 4gb) # test high 32bits cmpl $0, 12(%edi) @@ -683,15 +689,21 @@ detect_mem_e801: movzx %cx, %eax # first size is in KB, convert to bytes shl $10, %eax - mov %eax, 4(%esi) - cmp $0, %dx + jnc 0f + # overflow means it's >4GB, clamp to 4GB + mov $0xffffffff, %eax +0: mov %eax, 4(%esi) incl boot_mem_map_size + cmp $0, %dx jz e801_done movl $0x1000000, 8(%esi) movzx %dx, %eax # second size is in 64kb blocks, convert to bytes shl $16, %eax - mov %eax, 12(%esi) + jnc 0f + # overflow means it's >4GB, clamp to 4GB + mov $0xffffffff, %eax +0: mov %eax, 12(%esi) incl boot_mem_map_size e801_done: clc @@ -751,6 +763,10 @@ rmidt: .short 0x3ff saved_esp: .long 0 saved_ebp: .long 0 +saved_eax: .long 0 +saved_es: .word 0 +saved_ds: .word 0 +saved_flags: .word 0 # drop back to unreal mode to call 16bit interrupt .global int86 @@ -763,7 +779,7 @@ int86: sidt (saved_idtr) lidt (rmidt) - # modify the int instruction do this here before the + # modify the int instruction. do this here before the # cs-load jumps, to let them flush the instruction cache mov $int_op, %ebx movb 8(%ebp), %al @@ -787,21 +803,34 @@ int86: nop # load registers from the int86regs struct + # point esp to the regs struct to load registers with popa/popf mov %esp, saved_esp mov %ebp, saved_ebp mov 12(%ebp), %esp popal + popfw + pop %es + pop %ds + # ignore fs and gs for now, don't think I'm going to need them mov saved_esp, %esp + # move to the real-mode stack, accessible from ss=0 + # just in case the BIOS call screws up our unreal mode + mov $0x7be0, %esp + # call 16bit interrupt int_op: int $0 + # BIOS call might have enabled interrupts, cli for good measure + cli - mov saved_ebp, %ebp - mov 12(%ebp), %esp - add $34, %esp + # save all registers that we'll clobber before having the + # chance to populate the int86regs structure + mov %eax, saved_eax + mov %ds, saved_ds + mov %es, saved_es pushfw - pushal - mov saved_esp, %esp + pop %ax + mov %ax, saved_flags # re-enable protection mov %cr0, %eax @@ -818,6 +847,20 @@ int_op: int $0 mov %ax, %ss nop + # point the esp to our regs struct, to fill it with pusha/pushf + mov saved_ebp, %ebp + mov 12(%ebp), %esp + add $38, %esp + mov saved_ds, %ax + pushw %ax + mov saved_es, %ax + pushw %ax + mov saved_flags, %ax + pushw %ax + mov saved_eax, %eax + pushal + mov saved_esp, %esp + # restore 32bit interrupt descriptor table lidt (saved_idtr) sti @@ -829,3 +872,5 @@ int_op: int $0 # buffer used by the track loader ... to load tracks. .align 16 buffer: + .global low_mem_buffer +low_mem_buffer: