[org 0x7C00]
[bits 16]
mov bp, 0x0500
mov sp, bp
[bits 16]
load_bios:
; Save the number of registers to load for later
push cx
; For the ATA Read bios utility, the value of ah must be 0x02
; See the BIOS article from Chapter 1.2 for more info
mov ah, 0x02
mov al, 0x01
mov cl, 0x02
mov bx, 0x7e00
mov ch, 0x00 ; Cylinder goes in ch
mov dh, 0x00 ; Cylinder head goes in dh
; dl is already stored in dl
int 0x13
; And elevate our CPU to 32-bit mode
;call elevate_bios
elevate_bios:
cli
lgdt [gdt_32_descriptor]
mov eax, cr0
or eax, 0x00000001
mov cr0, eax
jmp 0x8:init_pm ;code segment is the second segment
;
jmp $
[bits 16]
gdt_32_descriptor:
dw gdt_32_end - gdt_32_start - 1 ; Size of GDT, one byte less than true size
dd gdt_32_start ; Start of the 32 bit gdt
gdt_32_start:
; Define the null sector for the 32 bit gdt
; Null sector is required for memory integrity check
gdt_32_null:
dd 0x00000000 ; All values in null entry are 0
dd 0x00000000 ; All values in null entry are 0
; Define the code sector for the 32 bit gdt
gdt_32_code:
dw 0xFFFF ; Limit (bits 0-15)
dw 0x0000 ; Base (bits 0-15)
db 0x00 ; Base (bits 16-23)
db 0b10011010 ; 1st Flags, Type flags
db 0b11001111 ; 2nd Flags, Limit (bits 16-19)
db 0x00 ; Base (bits 24-31)
; Define the data sector for the 32 bit gdt
gdt_32_data:
dw 0xFFFF ; Limit (bits 0-15)
dw 0x0000 ; Base (bits 0-15)
db 0x00 ; Base (bits 16-23)
db 0b10010010 ; 1st Flags, Type flags
db 0b11001111 ; 2nd Flags, Limit (bits 16-19)
db 0x00 ; Base (bits 24-31)
gdt_32_end:
; Define helpers to find pointers to Code and Data segments
code_seg: equ gdt_32_code - gdt_32_start
data_seg: equ gdt_32_data - gdt_32_start
; Infinite Loop
bootsector_hold:
jmp $ ; Infinite loop
[bits 32]
init_pm:
;segment register contains the gdt sectors (it states where the sgment starts and sizw)
; when we address it takes an offset from the address that the current sector
;starts )
mov ax, data_seg
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
; Since the stack pointers got messed up in the elevation process, and we
; want a fresh stack, we need to reset them now.
mov ebp, 0x90000
mov esp, ebp
; Go to the second sector with 32-bit code
jmp begin_protected
times 510 - ($ - $$) db 0x00
; Magic number
dw 0xAA55
; BEGIN SECOND SECTOR. THIS ONE CONTAINS 32-BIT CODE ONLY
bootsector_extended:
begin_protected:
;routine
;;;;;;;;;;;;;;;;;;;;;;;;;
mov ebx , 0x8b000 ;;; start ;;;;;;;;;;;;;;;;;;;;;;;;;
mov ah , style_wb
loop1:
mov al , 0x43
mov [ebx] , ax
add ebx , 2
cmp ebx , 0xb8000 + 80*2 ;;;;;; end ;;;;;;;;;;;;;;;;;;
jl loop1
;;;;;;;;;;;;;;;;;;;;;;;;
;routine
jmp $ ; Infinite Loop
[bits 32]
; Fill with zeros to the end of the sector
times 512 - ($ - bootsector_extended) db 0x00
在这个 gdt 中,我将代码和数据段设置为从地址 0 开始并占用整个 4gb 的内存。我猜该表存在于这个内存中的某个地方(我不太确定,但我猜它存储在前 512+0x7c00 个字节中,在我更改为 32 位模式之前由 bios 加载)。如果这是真的,我可以达到此地址(因为数据段设置为从地址 0 开始)