📄 复件 boot.asm
字号:
; myboot.asm bootstrap for real mode loader
;Aug,01,2005
%define IMAGE_SEG 0x9000
%if IMAGE_SEG & 31
%error "IMAGE_SEG must be divisible by 0x20"
%endif
[org 0x7C00]
entry:
jmp short begin
;reserved as my own param area
gdt:
gdt_null:
dd 0
dd 0
gdt_data_addr equ $-gdt
gdt_data:
dw 0xffff
dw 0x0000
db 0 ;we got baseaddr=0x90000
db 10010010b ;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,2:data seg,read and write.
db 11001111b ;(7)limit len,0:1 byte,1:4K,(6)B bit,control stack,B=1,use esp,B=0,use sp,(5-4) reserved,(3-0)seg limit 19-16.
db 0
gdt_code_addr equ $-gdt
gdt_code:
dw 0xffff
dw 0x0000
db 0 ;we got baseaddr=0x90000
db 10011010b ;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,10:code seg,execute and read.
db 11001111b
db 0
gdt_loader_data_addr equ $-gdt
gdt_loader_data:
dw 0xffff
dw 0x0000
db 0
db 10010010b ;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,2:data seg,read and write.
db 11001111b ;(7)limit len,0:1 byte,1:4K,(6)B bit,control stack,B=1,use esp,B=0,use sp,(5-4) reserved,(3-0)seg limit 19-16.
db 0
gdt_loader_code_addr equ $-gdt
gdt_loader_code:
dw 0xffff
dw 0x0000
db 0
db 10011010b ;(7)seg exist,(6-5)privileg,(4)0:sys seg,1:data or code seg,(3-0)seg attr,10:code seg,execute and read.
db 11001111b
db 0
gdt_end:
gdt_addr:
dw gdt_end - gdt - 1 ;gdt total length,here it contains 3 item
dd gdt ;gdt start address
begin:
xor ax, ax
mov ds, ax
cli
mov ss, ax
mov sp, 0x7C00
mov bp, sp
call read
eof:
mov ax,sucmsg ;Leaving boot
mov si,ax
call disps
enter_pm:
lgdt [gdt_addr]
open_A20:
in al,92h
or al,00000010b
out 92h,al
set_PM_bit:
mov eax,cr0
or eax,1
mov cr0,eax
jmp gdt_loader_code_addr:mode_32
[bits 32]
mode_32:
mov ax,gdt_data_addr
mov ds,ax ;set data segment base at 0x90000
jmp dword 0x10:0x10000 ;0x10=10 000 b ,now CS was pointing to gdt[2]
; jmp IMAGE_SEG:0 ;jump to 0x9000
;===================================================================
[bits 16]
error:
add al,'0'
call disp
mov ax,errmsg ;Leaving boot
mov si,ax
call disps
xor ah, ah
int 16h ;Wait for a key
int 19h ;Try to reboot
;===================================================================
;功能描述: 读扇区
;入口参数: AH=02H
;AL=扇区数
;CH=柱面
;CL=扇区
;DH=磁头
;DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
;ES:BX=缓冲区的地址
;出口参数:
;CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码,参见功能号01H中的说明
;===================================================================
read:
mov ax,loadmsg ;Leaving boot
mov si,ax
call disps
mov ch,0
mov cl,2 ;we write our kernel to disk start from sector two
mov dh,0
mov dl,0 ;DL = Drive number
xor bx,bx
mov ax,IMAGE_SEG ;ES:BX = address
mov es,ax
mov al,0x35 ;read 35h sectors
mov ah, 2 ;AH = Read command
int 13h ;Do it
jc error
ret
disp:
mov ah, 0x0e ;打字机模式,告诉BIOS,把字符输出到屏幕上
mov bh ,0x00 ;页码
mov bl,7 ; 文字属性
int 10h
ret
;In: DS:SI points to the string to be displayed.
;Out: None
disps:
mov ax, 0x0e0D ;打字机模式,告诉BIOS,把字符输出到屏幕上
mov bh ,0x00 ;页码
mov bl,7 ; 文字属性
.1 int 10h
lodsb
test al,al
jnz .1
ret
errmsg db 10,"Error Executing bootsector",13
db 10,"Press any key to reboot",13,10,0
loadmsg db 10,"Loading kernel...",13,10,0
sucmsg db 10,"Ready to jump to kernel",13,10,0
size equ $ - entry
%if size+11+2 > 512
%error "code is too large for boot sector"
%endif
times (512 - size - 2) db 0
db 0x55, 0xAA ;2 byte boot signature
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -