.section .mbr .code16 move_mbr: xor %ax, %ax mov %ax, %ds mov %ax, %es mov %ax, %ss # move the MBR to 0xe00 mov $128, %cx # 512 bytes mov $0x7c00, %si mov $0x0e00, %di rep movsl ljmp $0x00, $2f 2: # read the kernel stage1 mov $.Lread_data_packet, %si mov $0x42, %ah mov $0x80, %dl int $0x13 jc .Lhalt # get memory size info and storage it mov $0xe801, %ax int $0x15 jc .Lhalt cmp $0x86, %ah # unsupported function je .Lhalt cmp $0x80, %ah # invalid command je .Lhalt jcxz 2f mov %cx, %ax mov %dx, %bx 2: mov $E820_MEM_MAP_DATA, %esp movzw %ax, %eax mov %eax, 8(%esp) # 1k blocks movzw %bx, %ebx mov %ebx, 12(%esp) # 64k blocks # save the destination address to es:di mov %sp, %di add $16, %di # buffer is 1024 - 16 bytes # set default entry size movl $20, 4(%esp) # clear %ebx, len xor %ebx, %ebx mov %ebx, (%esp) 2: # set the magic number to edx mov $0x534D4150, %edx # set function number to eax mov $0xe820, %eax # set default entry size mov $24, %ecx int $0x15 incl (%esp) add $24, %edi jc .Lsave_mem_fin cmp $0, %ebx jz .Lsave_mem_fin cmp $24, %ecx cmovnz 4(%esp), %ecx mov %ecx, 4(%esp) jmp 2b .Lsave_mem_fin: mov $0x3ff, %ax mov $BIOS_IDT_DESCRIPTOR, %di mov %ax, (%di) xor %eax, %eax mov %eax, 2(%di) lgdt .Learly_gdt_descriptor cli # IDT descriptor is 6 0's. borrow the null gdt entry lidt .Learly_gdt # enable protection mode mov %cr0, %eax or $1, %eax mov %eax, %cr0 ljmp $0x08, $start_32bit .Lhalt: hlt jmp . .align 16 .Learly_gdt: .8byte 0x0 # null selector .8byte 0x00cf9a000000ffff # 32bit code selector .8byte 0x00cf92000000ffff # 32bit data selector .align 4 .Learly_gdt_descriptor: .word 0x17 # size .long .Learly_gdt # address .align 16 .Lread_data_packet: .long 0x00080010 # .stage1 takes up 4K, or 8 sectors .long 0x00007000 # read to 0000:7000 .8byte 1 # read from LBA 1