ret
+ # this part is placed at the very end of all low memory sections
+ .section .bootend,"ax"
.global boot_mem_map_size
boot_mem_map_size: .long 0
.global boot_mem_map
boot_mem_map: .space 128
-
-# this is not boot loader code. It's called later on by the main kernel
-# code in 32bit protected mode. It's placed here because it needs to be
-# located in base memory as it returns and runs in real mode.
- .code32
- .align 4
- # place to save the protected mode IDTR pseudo-descriptor
- # with sidt, so that it can be restored before returning
- .short 0
-saved_idtr:
-idtlim: .short 0
-idtaddr:.long 0
- # real mode IDTR pseudo-descriptor pointing to the IVT at addr 0
- .short 0
-rmidt: .short 0x3ff
- .long 0
-
-saved_esp: .long 0
-saved_ebp: .long 0
-saved_eax: .long 0
-saved_es: .word 0
-saved_ds: .word 0
-saved_flags: .word 0
-saved_pic1_mask: .byte 0
-saved_pic2_mask: .byte 0
-
- # drop back to unreal mode to call 16bit interrupt
- .global int86
-int86:
- push %ebp
- mov %esp, %ebp
- pushal
- cli
- # save protected mode IDTR and replace it with the real mode vectors
- sidt (saved_idtr)
- lidt (rmidt)
-
- # save PIC masks
- pushl $0
- call get_pic_mask
- add $4, %esp
- mov %al, saved_pic1_mask
- pushl $1
- call get_pic_mask
- add $4, %esp
- mov %al, saved_pic2_mask
-
- # 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
- movb %al, 1(%ebx)
-
- # long jump to load code selector for 16bit code (6)
- ljmp $0x30,$0f
-0:
- .code16
- # disable protection
- mov %cr0, %eax
- and $0xfffe, %ax
- mov %eax, %cr0
- # load cs <- 0
- ljmp $0,$0f
-0: # zero data segments
- xor %ax, %ax
- mov %ax, %ds
- mov %ax, %es
- mov %ax, %ss
- 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
-
- # 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
-
- # 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
- popw %ax
- mov %ax, saved_flags
-
- # re-enable protection
- mov %cr0, %eax
- or $1, %ax
- mov %eax, %cr0
- # long jump to load code selector for 32bit code (1)
- ljmp $0x8,$0f
-0:
- .code32
- # set data selector (2) to all segment regs
- mov $0x10, %ax
- mov %ax, %ds
- mov %ax, %es
- 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
- # grab the flags and replace the carry bit from the saved flags
- pushfw
- popw %ax
- and $0xfffe, %ax
- or saved_flags, %ax
- pushw %ax
- mov saved_eax, %eax
- pushal
- mov saved_esp, %esp
-
- # restore 32bit interrupt descriptor table
- lidt (saved_idtr)
-
- # restore PIC configuration
- call init_pic
-
- # restore IRQ masks
- movzbl saved_pic1_mask, %eax
- push %eax
- pushl $0
- call set_pic_mask
- add $8, %esp
-
- movzbl saved_pic2_mask, %eax
- push %eax
- pushl $1
- call set_pic_mask
- add $8, %esp
-
- # keyboard voodoo: with some BIOS implementations, after returning from
- # int13, there's (I guess) leftover data in the keyboard port and we
- # can't receive any more keyboard interrupts afterwards. Reading from
- # the keyboard data port (60h) once, seems to resolve this. And it's
- # cheap enough, so why not... I give up.
- push %eax
- in $0x60, %al
- pop %eax
-
- sti
- popal
- pop %ebp
- ret
-
-
.align 4
.global boot_drive_number
boot_drive_number: