📄 setup.asm
字号:
[BITS 16]
[ORG 0x0000]
;--------------------------------------------------------------------------------------------------------
jmp main
;--------------------------------------------------------------------------------------------------------
;;数据区说明(基址)
;;0x0000 boot 程序
;;0x1000 setup 程序
;;0x2000 登陆图 3
;;0x3000 字库
;;0x4000 光标
;;0x5000 登陆图 1
;;0x6000 登陆图 2
;;0x7000 应用程序图标
;;0x8000 系统数据及堆栈区
;;0x9000 kernel 程序
;;把 kernel 读到 0x9000 的意义在于可以让它访问更大的空间,全局变量并不在程序中分配空间,而只分配它的指针
;-------------------------------------------------------------------------------------------------------
BOOT_DRIVER db 0
VESA: times 512 db 0 ;;分配一块区域存放 vesa 返回的信息
;---------------------------------------------------------------------------------------------------------
;;下面定义临时 GDT 表描述符
;;总共定义三个段,一个空段由 intel 保留,一个代码段,一个数据段
gdt_descriptor:
dw 0xffff ;;GDT 表的大小
dw gdt ;;GDT 表的位置
dw 0x0001 ;;此处的 1 是由于段基址为 0x1000
;;如果 SETUP_SEG 不是 0x1000 则更换此值
gdt:
gdt_null:
dw 0x0000
dw 0x0000
dw 0x0000
dw 0x0000
gdt_kernel_code: ;;内核代码段,把整个内存空间做为一个整段
dw 0xffff
dw 0x0000
dw 0x9a00 ;;非一致代码段
dw 0x00cf
gdt_system_data:
dw 0xffff
dw 0x0000
dw 0x9200 ;;非一致数据段
dw 0x00cf
;---------------------------------------------------------------------------------------------------------
get_boot_driver: ;;取得启动驱动器号,此号由 boot 程序保留
push fs
mov ax , 0x8000
mov fs , ax
mov al , [ fs:0 ]
mov [ BOOT_DRIVER ] ,al
pop fs
ret
;---------------------------------------------------------------------------------------------------------
set_vesa_model: ;;设置显卡模式
push es
push fs
;;设置显卡模式
mov ax , 0x4f02
mov bx , 0x4114 ;;800 * 600 ( 5:6:5 ) ;虚拟机不支持高色
int 0x10
;;取得该模式下显存线性地址
mov bx , 0x1000
mov es , bx
mov bx , 0x8000
mov fs , bx
mov di , VESA
mov ax , 0x4f01
mov cx , 0x114
int 0x10
mov eax , [ es:VESA + 40 ]
mov [ fs:1 ] , eax
pop es
pop fs
ret
;--------------------------------------------------------------------------------------------------------
read_login_bmp1:
;;下面继续读入第 0 面的第 2 磁道,共18扇区,(login.bmp ),存入 0x5000:0000 处
mov ax , 0x5000
mov di , 7 ;;欲读入的磁道总数(0.2 , 1.2 , 0.3 , 1.3 , 0.4 , 1.4 , 0.5)
mov dh , 0
mov ch , 2
call read_disk_length_less_64K
ret
;---------------------------------------------------------------------------------------------------
read_application_bmp
;;下面继续读入第 1 面的第 11 磁道,共18扇区,(login.bmp ),存入 0x7000:0000 处
mov ax , 0x7000
mov di , 4 ;;欲读入的磁道总数(1.11 , 0.12 , 1.12 , 0.13)
mov dh , 1
mov ch , 11
call read_disk_length_less_64K
ret
;---------------------------------------------------------------------------------------------------
read_login_bmp2:
;;下面继续读入第 1 面的第 5 磁道,共18扇区,(login.bmp ),存入 0x6000:0000 处
mov ax , 0x6000
mov di , 7 ;;欲读入的磁道总数(1.5 , 0.6 , 1.6 , 0.7 , 1.7 , 0.8 , 1.8)
mov dh , 1
mov ch , 5
call read_disk_length_less_64K
ret
;---------------------------------------------------------------------------------------------------
read_logout_bmp:
;;下面继续读入第 1 面的第 12 磁道,共18扇区,(login.bmp ),存入 0x2000:0000 处
mov ax , 0x2000
mov di , 6 ;;欲读入的磁道总数(1.13 , 0.14 , 1.14 , 0.15 , 1.15 , 0.16)
mov dh , 1
mov ch , 13
call read_disk_length_less_64K
ret
;---------------------------------------------------------------------------------------------------
read_cursor:
;;下面继续读入第 0 面的第 9 磁道,共18扇区,(login.bmp ),存入 0x4000:0000 处
mov ax , 0x4000
mov di , 4 ;;欲读入的磁道总数(0.9 , 1.9 , 0.10 , 1.10)
mov dh , 0
mov ch , 9
call read_disk_length_less_64K
ret
;---------------------------------------------------------------------------------------------------
read_font_lib:
push es
;;读入中文,起始 0.11.1
mov di , 2 ;;读的总扇区数( 0.11.1 , 0.11.2 )
mov ax , 0x3000
mov es , ax
mov bx , 0
mov dh , 0
mov ch , 11
mov cl , 1 ;;启始 1 扇区
.read_font_lib_1:
mov ah , 2 ;;功能号 2 表示读磁盘扇区
mov dl , [ BOOT_DRIVER ] ;;驱动器号
mov al , 1 ;;读入扇区数
int 0x13
jc .read_font_lib_1
dec di
cmp di , 0
je .read_font_lib_end
inc cl
add bx , 512
jmp .read_font_lib_1
.read_font_lib_end:
pop es
ret
;--------------------------------------------------------------------------------------------------------
read_kernel: ;;读入 kernel 程序
push es
.read_kernel_1:
mov ax , 0x9000
mov es , ax
mov bx , 0
mov ah , 2
mov dl , [ BOOT_DRIVER ]
mov dh , 0
mov ch , 0
mov cl , 4
mov al , 15
int 0x13
jc .read_kernel_1
add bx , 15 * 512
.read_kernel_2:
mov dh , 1
mov dl , [ BOOT_DRIVER ]
mov ch , 0
mov cl , 1
mov ah , 2
mov al , 18
int 0x13
jc .read_kernel_2
pop es
ret
;------------------------------------------------------------------------------------------------------
;;存入的段起始位置放在 ax 中
;;欲读入的磁道总数放在 di 中
;;起始面放入 dh 中
;;起始磁道放入 ch 中
read_disk_length_less_64K:
push es
mov es , ax
mov bx , 0
.read_disk_length_less_64K_1:
mov ah , 2 ;;功能号 2 表示读磁盘扇区
mov dl , [ BOOT_DRIVER ] ;;驱动器号
mov cl , 1 ;;启始扇区1扇区
mov al , 18 ;;读入扇区数
int 0x13
jc .read_disk_length_less_64K_1
dec di
cmp di , 0
je .read_disk_length_less_64K_end
add bx , 18 * 512
xor dh , 1
cmp dh , 0
jne .read_disk_length_less_64K_1
inc ch
jmp .read_disk_length_less_64K_1
.read_disk_length_less_64K_end:
pop es
ret
;---------------------------------------------------------------------------------------------------
read_top_bmp:
push es
mov ax , 0x3000
mov di , 2
mov dh , 1
mov ch , 16
mov es , ax
mov bx , 1024
.read_top_bmp_1:
mov ah , 2 ;;功能号 2 表示读磁盘扇区
mov dl , [ BOOT_DRIVER ] ;;驱动器号
mov cl , 1 ;;启始扇区1扇区
mov al , 18 ;;读入扇区数
int 0x13
jc .read_top_bmp_1
dec di
cmp di , 0
je .read_top_bmp_end
add bx , 18 * 512
xor dh , 1
cmp dh , 0
jne .read_top_bmp_1
inc ch
jmp .read_top_bmp_1
.read_top_bmp_end:
pop es
ret
;;-----------------------------------------------------------------------------------------------
main:
;;初始化寄存器,因为 Bios 中断及 call 会用到堆栈或 ss 寄存器
;;在 CPU 启动或复位时是由 BIOS 初始化的,而现在进行了段转移,需要我们重新设置
mov ax , 0x1000
mov ds , ax
mov ax , 0x8000
mov ss , ax
mov sp , 0xffff
;;取得启动驱动器号
call get_boot_driver
;;设置显示模式
call set_vesa_model
;;读入图片
call read_login_bmp1
call read_login_bmp2
call read_cursor
call read_application_bmp
call read_logout_bmp
;;读入字库
call read_font_lib
call read_top_bmp
;;读入 kernel 程序
call read_kernel
;;下面开始为进入保护模式而进行初始化工作
lgdt [ gdt_descriptor ] ;;载入gdt的描述符
;;下面设置进入32位保护模式运行
cli ;;关中断
mov eax , cr0
or eax , 1
mov cr0 , eax
jmp dword 0x8:0x90000
;-------------------------------------------------------------------------------------
times 1024-($-$$) db 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -