本文解析setup.s,主要可以分为5部分:
- 提取机器系统数据(-110)
- 把system搬运到0x00000(-127)
- 赋值IDTR,GDTR,建立GDT(130-134)
- 开启A20地址线(-143)
- 重编程8259A(-179)
- 进入保护模式(-193)
提取机器系统数据
INITSEG = 0x9000 ! we move boot here - out of the way
SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
SETUPSEG = 0x9020 ! this is the current segment
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text
.text
endtext:
.data
enddata:
.bss
endbss:
数据初始化
mov ax,#INITSEG ! this is done in bootsect already, but...
mov ds,ax
mov ah,#0x03 ! read cursor pos
xor bh,bh
int 0x10 ! save it in known place, con_init fetches
mov [0],dx ! it from 0x90000.
读取光标位置,并将光标位置存储在ds内存储的0x9000+[0]处,即0x90000
! Get memory size (extended mem, kB)
mov ah,#0x88
int 0x15
mov [2],ax
获取内存信息
! Get video-card data:
mov ah,#0x0f
int 0x10
mov [4],bx ! bh = display page
mov [6],ax ! al = video mode, ah = window width
获取显卡信息
! check for EGA/VGA and some config parameters
mov ah,#0x12
mov bl,#0x10
int 0x10
mov [8],ax
mov [10],bx
mov [12],cx
获取EGA/VGA和配置参数(检查显示方式并取参数)
! Get hd0 data
mov ax,#0x0000
mov ds,ax
lds si,[4*0x41]
mov ax,#INITSEG
mov es,ax
mov di,#0x0080
mov cx,#0x10
rep
movsb
获取首磁盘信息,从ds(0x0000):si(0x0104)拷贝到es(0x9000):di(0x0080),重复16次
! Get hd1 data
mov ax,#0x0000
mov ds,ax
lds si,[4*0x46]
mov ax,#INITSEG
mov es,ax
mov di,#0x0090
mov cx,#0x10
rep
movsb
获取第二块磁盘信息,从ds(0x0000):si(0x0118)拷贝到es(0x9000):di(0x0090),重复16次
从设备获取及存储的信息如下:
内存地址 | 长度 | 名称 |
---|---|---|
0x90000 | 2 | 光标位置 |
0x90002 | 2 | 扩展内存数 |
0x90004 | 2 | 显示页面 |
0x90006 | 1 | 显示模式 |
0x90007 | 1 | 字符列数 |
0x90008 | 2 | 未知2 |
0x9000A | 1 | 显示内存 |
0x9000B | 1 | 显示状态 |
0x9000C | 2 | 显卡特性参数 |
0x9000E | 1 | 屏幕行数 |
0x9000F | 1 | 屏幕列数 |
0x90080 | 16 | 硬盘1参数列表 |
0x90090 | 16 | 硬盘2参数列表 |
0x901FC | 2 | 根设备号 |
! Check that there IS a hd1 :-)
mov ax,#0x01500
mov dl,#0x81
int 0x13
jc no_disk1
cmp ah,#3
je is_disk1
no_disk1:
mov ax,#INITSEG
mov es,ax
mov di,#0x0090
mov cx,#0x10
mov ax,#0x00
rep
stos