linux0.11 - setup.s第一阶段(获取系统信息)

通过BIOS中断功能获取各类信息,并将这些数据存储在内存地址0x90000起始的区域。

一、获取参数

1.1 设置data segment

将数据段设置为0x9000,后续参数从0x90000地址开始依次存储。

复制代码
INITSEG  = 0x9000
...

 # set data segment
    mov $INITSEG,%ax
    mov %ax,%ds

1.2 获取游标位置

通过BIOS的0x10中断的0x03号功能获取游标位置,结果存储在[0x90000,0x90002)

复制代码
 # get cursor position
    mov $0x03,%ah
    mov $0x00,%bh
    int $0x10

    # save cursor position
    mov %dx,[0]

从图中可以手动数出来,row(0,1,2,...,19),col(0,1,2,...,22)和获取的结果一致

1.3 获取内存大小

通过BIOS的0x15中断的0x88号功能获取内存大小,结果存储在[0x90002,0x90004)

复制代码
    # get memory size (extended mem, kB)
    mov $0x88,%ah
    int $0x15

    # save memory size
    mov %ax,[2]

具体调用方式:
https://www.ctyme.com/intr/rb-1529.htm

复制代码
AH = 88h

Return:
CF clear if successful
AX = number of contiguous KB starting at absolute address 100000h
CF set on error
AH = status
80h invalid command (PC,PCjr)
86h unsupported function (XT,PS30)

从结果看0x7c00KB=>31MB,而通过此功能获取的大小是0x100000(1MB)以外的大小,加上则刚好32MB,而bochsrc配置如下,正好32MB的内存。

复制代码
megs: 32

1.4 获取视频卡数据

通过BIOS的0x10中断的0x0f号功能获取视频卡数据,存储在[0x90004,0x90008)

复制代码
    # get video-card data
    mov $0x0f,%ah
    int $0x10

    # save video-card data
    mov %bx,[4]
    mov %ax,[6]

具体使用方式:
https://www.ctyme.com/intr/rb-0108.htm

复制代码
AH = 0Fh

Return:
AH = number of character columns
AL = display mode (see #00010 at AH=00h)
BH = active page (see AH=05h)
Notes: If mode was set with bit 7 set ("no blanking"), the returned mode will also have bit 7 set. EGA, VGA, and UltraVision return either AL=03h (color) or AL=07h (monochrome) in all extended-row text modes. HP 200LX returns AL=07h (monochrome) if mode was set to AL=21h and always 80 resp. 40 columns in all text modes regardless of current zoom setting (see AH=D0h).

从结果看

寄存器 说明
al 0x03 彩色显示
ah 0x50 每行80字符
bh 0x00 page0 激活
bl 0x00

1.5 获取EGA信息

通过BIOS的0x10中断的AH12h/BL10h功能号获取EGA信息,结果存储在[0x90008,0x9000e)

复制代码
# get EGA info
    mov $0x12,%ah
    mov $0x10,%bl
    int $0x10

    # save EGA info
    mov %ax,[8]
    mov %bx,[10]
    mov %cx,[12]

具体使用方式:
https://www.ctyme.com/intr/rb-0162.htm

复制代码
AH = 12h
BL = 10h

Return:
BH = video state
00h color mode in effect (I/O port 3Dxh)
01h mono mode in effect (I/O port 3Bxh)
BL = installed memory (00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K)
CH = feature connector bits (see #00022)
CL = switch settings (see #00023,#00024)
AH destroyed (at least by Tseng ET4000 BIOS v8.00n)

从结果看,

寄存器 说明
bh 0x00 彩色模式
bl 0x03 256K显示内存
ch 0x00
cl 0x09
ah 0x12
al 0x03

1.6 获取磁盘参数

获取第一块磁盘参数

直接读取BIOS中断向量表中的第0x41项对应的16字节内容,即为第一块磁盘参数,并存储在[0x90080,0x90090)

中断向量表实际上是从0x00000开始的一个索引,每个索引为4字节的地址(2字节段基址+2字节偏移),LDS [4*0x41] %si通过LDS指令将对应的ds:0x104的内容加载到ds:si中,当前已经将ds设置为0x0000,因此加载的是0x00104的值到ds:si,然后读取16字节到es:di(0x9000:0x0080)

复制代码
 # get hd0 data
    mov $0x0000,%ax
    mov %ax,%ds
    lds [4*0x41],%si
    mov $INITSEG,%ax
    mov %ax,%es
    mov $0x0080,%di
    mov $0x10,%cx
    cld
    rep movsb

获取第二块磁盘参数

直接读取BIOS中断向量表中的第0x46项对应的16字节内容,即为第一块磁盘参数,并存储在[0x90090,0x900a0)

复制代码
# get hd1 data
    mov $0x0000,%ax
    mov %ax,%ds
    lds [4*0x46],%si
    mov $INITSEG,%ax
    mov %ax,%es
    mov $0x0090,%di
    mov $0x10,%cx
    cld
    rep movsb

1.7 判断是否是第一块磁盘

复制代码
 # check that there is a hd1
    mov $0x1500,%ax
    mov $0x81,%dl
    int $0x13
    jc no_disk1
    cmp $3,%ah
    je is_disk1
no_disk1:
    mov $INITSEG,%ax
    mov %ax,%es
    mov $0x0090,%di
    mov $0x10,%cx
    mov $0x00,%ax
    cld
    rep stosb
is_disk1:

判断当前是否是第一个磁盘,当前dl设置0x81(10000001b), bit7设置1表示硬盘,0~6位表示硬盘编号,表示硬盘1,当没有disk1时将清空[0x90090,0x900a0)的空间。

具体使用方式:
https://www.ctyme.com/intr/rb-0639.htm

复制代码
AH = 15h
DL = drive number (bit 7 set for hard disk)
(AL = FFh, CX = FFFFh, see Note)

Return:
CF clear if successful
AH = type code
00h no such drive
(SpeedStor) AL = 03h hard disk
CX:DX = number of 512-byte sectors
01h floppy without change-line support
02h floppy (or other removable drive) with change-line support
03h hard disk
CX:DX = number of 512-byte sectors
CF set on error
AH = status (see #00234 at AH=01h)

Note: SyQuest can report type 01h or 02h for 'hard disks', since its media is removable

1.8 小结

setup.s第一阶段通过BIOS获取游标位置,内存大小,视频卡信息,EGA信息,磁盘参数等,并将这些内容在原bootsect地址0x90000依次存储,接下来将进行保护模式的准备以及切换。

相关推荐
怀旧,1 小时前
【Linux网络编程】2. Socket编程 UDP
linux·网络·udp
徒劳爱学仙1 小时前
全志 V821 韦东山 Avaota-F1-B ubuntu开发环境搭建
linux·运维·ubuntu
z200509302 小时前
【linux学习】linux的基本指令
linux·学习
迷枫7122 小时前
Linux 磁盘管理全攻略:从物理硬件到在线扩容
linux
java_logo3 小时前
轻量AI接口网关一键部署|calciumion/new-api Windows/Linux Docker 部署全教程
linux·人工智能·windows·one api·calciumion·ai网关部署·one api 部署
原来是猿3 小时前
Linux - 【理解进程组、会话与作业控制】
linux·运维·服务器
怀旧,3 小时前
【Linux网络编程】1. 网络基础概念
linux·网络
怀旧,4 小时前
【Linux网络编程】5. 应用层协议 HTTP
linux·网络·http