最近在研究赵炯老师的《Linux 内核 0.11 详细注释》,将自己的粗浅理解做个简单的注记,以供有相同兴趣爱好的朋友查阅。
一、程序说明
setup 程序的作用是利用 ROM BIOS 中断读取机器系统数据,并将这些数据保存到 0x90000 开始的
位置(覆盖掉了 bootsect 程序所在的地方),加载中断描述符表到中断描述符表寄存器(IDTR),加载全局描述符表到全局描述符表寄存器(GDTR)寄存器,将system从0x10000的位置移动到0x0000覆盖掉中断向量表、BIOS数据及中断服务程序,并开启A20地址线,设置PE为为1,开启保护模式,跳转至system代码段(选择子为0x0008)偏移地址为0x0000的地方开始执行。
二、代码注释
INITSEG = 0x9000 ! 将bootsect程序移动到了0x9000段地址
SYSSEG = 0x1000 ! system装载到了0x10000(64kb的位置)
SETUPSEG = 0x9020 ! setup所在的代码段地址
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.bss
begbss:
.text
entry start
start:
! 设置ss sp寄存器的值
mov ax, #INITSEG !0x9000
mov ss, ax
mov sp, #0xFF00
! 输出字符串
mov ax, #SETUPSEG !0x1000
mov es, ax
call read_cursor
mov cx, #14 !长度为14
mov bx, #0x0007 ! 黑底白字 (7 normal, white color)
mov bp, #msg
mov ax, #0x1301 ! 写字符串并移动光标
int 0x10
call read_cursor
mov cx, #5
mov bx, #0x000a ! 黑底绿字(10 bright green)
mov bp, #msg+14
mov ax, #0x1301
int 0x10
call print_nl
call print_nl
mov ax,#INITSEG ! 将 ds 置成#INITSEG(0x9000)
mov ds,ax
mov ah,#0x03 ! 读取光标位置
xor bh,bh
int 0x10 ! 光标位置信息存放在 0x90000 处,控制台初始化时会来取
mov [0],dx ! dh = 行号(0x00 是顶端),dl = 列号(0x00 是左边)。存储在 0x90000.
! 调用中断 0x15,功能号 ah = 0x88
! 返回:ax = 从 0x100000(1M)处开始的扩展内存大小(KB)。
! 若出错则 CF 置位,ax = 出错码。
mov ax, #INITSEG !0x9000
mov ds, ax
mov ah,#0x88
int 0x15
mov [2],ax
! 取显示卡当前显示模式。
! 调用 BIOS 中断 0x10,功能号 ah = 0x0f
! 返回:ah = 字符列数,al = 显示模式,bh = 当前显示页。
! 0x90004(1 字)存放当前页,0x90006 显示模式,0x90007 字符列数。
mov ah,#0x0f
int 0x10
mov [4],bx
mov [6],ax
! 检查显示方式(EGA/VGA)并取参数。
! 调用 BIOS 中断 0x10,附加功能选择 -取方式信息
! 功能号:ah = 0x12,bl = 0x10
! 返回:bh = 显示状态
! (0x00 - 彩色模式,I/O 端口=0x3dX)
! (0x01 - 单色模式,I/O 端口=0x3bX)
! bl = 安装的显示内存
! (0x00 - 64k, 0x01 -