linux引导扇区bootsect注释

//计算机启动时CS=0xf000,IP=0xfff0,属于BIOS的地址范围,执行BIOS ROM中的代码
//BIOS程序检查硬件(POST),设置实模式下的中断向量表,指向BIOS芯片自身提供的BIOS中断调用的代码
//最后,BIOS把bootsect加载到内存中的0000:7c00处
//此时CS=0x0000,IP=0x7c00,SS、SP不变,仍然使用和BIOS程序使用的堆栈段
//引导扇区bootsect的作用:移动bootsect自身到0x90000,加载setup模块到0x90200,加载system模块到0x10000

SYSSIZE=0x3000	//默认内核的最大长度
.globl begtext, begdata, begbss, endtext, enddata, endbss
.text
begtext:
.data
begdata:
.begbss
begbss:
.text

SETUPLEN = 4 //setup程序所占的扇区数
BOOTSEG = 0x7c00
//bootsect的初始段地址,其实此时CS=0x0000,IP=0x7c00,但bootsect程序认为CS=0x7c00,IP=0;表示的地址是一样的
//在移到INITSEG之前只要不使用label表示的偏移地址就不会出错,因为编译器认为编译地址的起始偏移量为0
INITSEG = 0x9000	//移动bootsect的新段地址
SETUPSEG = 0x9020
SYSSEG = 0x1000
ENDSEG = SYSSEG + SYSSIZE

ROOT_DEV = 0x306 //指定root文件系统是第2个硬盘的第一个分区

entry start
start:
	//移动bootsect自身到0x9000
	mov ax, #BOOTSEG
	mov ds, ax
	mov ax, #INITSEG
	mov es, ax
	mov cx, #256
	sub si, si
	sud di, di
	rep
	movw
	//移动bootsect自身到0x9000
	jmpi go, INITSEG
go:	mov ax, cs
	mov ds, ax
	mov es, ax
	mow ss, ax
	mov sp, #0xff00
load_setup:
	mov dx, #0x0000	//驱动器0,磁头0
	mov cx, #0x0002	//扇区2,磁道0
	mov bx, #0x0200	//INITSEG端512偏移处
	mov ax, #0x0200+SETUPLEN	//服务号2,扇区数4
	int 0x13
	jnc ok_load_setup
	mov dx, #0x0000
	mov ax, #0x0000	//复位磁盘
	int 0x13
	j load_setup
ok_load_setup:
	mov dl,#0x00
	mov ax,#0x0800 //服务号8,获取磁盘参数
	int 0x13
	mov ch,#0x00
	seg cs
	mov sectors,cx	//保存每磁道扇区数。
	mov ax,#INITSEG
	mov es,ax
	//显示信息'Loading system ...'
	mov ah,#0x03
	xor bh,bh
	int 0x10
	mov cx,#24 ! 共24 个字符。
	mov bx,#0x0007 ! page 0, attribute 7 (normal)
	mov bp,#msg1
	mov ax,#0x1301 ! write string, move cursor
	int 0x10
	//现在开始将system 模块加载到0x10000(64k)处。
	mov ax,#SYSSEG
	mov es,ax
	call read_it 	//读磁盘上system模块
	call kill_motor //关闭驱动器马达
	seg cs
	mov ax,root_dev
	cmp ax,#0
	jne root_defined
	seg cs
	mov bx,sectors
	mov ax,#0x0208
	cmp bx,#15
	je root_defined
	mov ax,#0x021c
	cmp bx,#18
	je root_defined
undef_root:
	jmp undef_root
root_defined:
	seg cs
	mov root_dev,ax
	//所有程序都加载完毕,跳转到setup程序去
	jmpi 0,SETUPSEG
	
sread: .word 1+SETUPLEN
head: .word 0
track: .word 0
read_it:
	mov ax,es
	test ax,#0x0fff
die:
	jne die
	xor bx,bx
rp_read:
	mov ax,es
	cmp ax,#ENDSEG
	jb ok1_read
	ret
ok1_read:
	seg cs
	mov ax,sectors
	sub ax,sread
	mov cx,ax
	shl cx,#9
	add cx,bx 
	jnc ok2_read
	je ok2_read
	xor ax,ax
	sub ax,bx
	shr ax,#9
ok2_read:
	call read_track
	mov cx,ax
	add ax,sread
	seg cs
	cmp ax,sectors
	jne ok3_read
	mov ax,#1
	sub ax,head
	jne ok4_read
	inc track
ok4_read:
	mov head,ax
	xor ax,ax
ok3_read:
	mov sread,ax
	shl cx,#9
	add bx,cx
	jnc rp_read
	mov ax,es
	add ax,#0x1000
	mov es,ax
	xor bx,bx
	jmp rp_read
read_track:
	push ax
	push bx
	push cx
	push dx
	mov dx,track
	mov cx,sread
	inc cx
	mov ch,dl
	mov dx,head
	mov dh,dl
	mov dl,#0
	and dx,#0x0100
	mov ah,#2
	int 0x13
	jc bad_rt
	pop dx
	pop cx
	pop bx
	pop ax
	ret
bad_rt:
	mov ax,#0
	mov dx,#0
	int 0x13
	pop dx
	pop cx
	pop bx
	pop ax
	jmp read_track
kill_motor:
	push dx
	mov dx,#0x3f2 ! 软驱控制卡的驱动端口,只写
	mov al,#0 ! A 驱动器,关闭FDC,禁止DMA和中断请求,关闭马达
	outb ! 将al 中的内容输出到dx 指定的端口去
	pop dx
	ret
sectors:
.word 0 ! 存放当前启动软盘每磁道的扇区数
msg1:
.byte 13,10 ! 回车、换行的ASCII 码
.ascii "Loading system ..."
.byte 13,10,13,10 ! 共24 个ASCII 码字符

.org 508 ! 表示下面语句从地址508(0x1FC)开始,所以root_dev
! 在启动扇区的第508 开始的2 个字节中
root_dev:
.word ROOT_DEV ! 这里存放根文件系统所在的设备号(init/main.c 中会用)
boot_flag:
.word 0xAA55 ! 硬盘有效标识
.text
endtext:
.data
enddata:
.bss
endbss:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值