您的位置:首页 > 运维架构 > Linux

linux0.11学习1之bootsect

2012-05-12 18:01 288 查看
前段时间参考《自己动手写操作系统》来写操作系统,对操作系统有了更加深刻的认识。现在打算研读linux 0.11的源代码(参考书目:《Linux内核完全注释(修正版v1.9.5)》,《Linux_内核设计的艺术》)。由于linux 0.11源代码的汇编部分,有类似于intel的汇编还有AT&T汇编,本人对nasm比较熟悉,所以打算把汇编部分全部改为nasm汇编来实现。

现在给出linux0.11的bootsect部分的源代码

bootsect.asm 的源代码。 至于代码的具体意思请参考《Linux内核完全注释》

;;nasm -o bootsect.bin bootsect.asm
;fat12 文件头
jmp short start		; Start to boot.
nop				;
BS_OEMName	DB 'ForrestY'	; OEM String, 必须 8 个字节

BPB_BytsPerSec	DW 512		; 每扇区字节数
BPB_SecPerClus	DB 1		; 每簇多少扇区
BPB_RsvdSecCnt	DW 1		; Boot 记录占用多少扇区
BPB_NumFATs	DB 2		; 共有多少 FAT 表
BPB_RootEntCnt	DW 224		; 根目录文件数最大值
BPB_TotSec16	DW 2880		; 逻辑扇区总数
BPB_Media	DB 0xF0		; 媒体描述符
BPB_FATSz16	DW 9		; 每FAT扇区数
BPB_SecPerTrk	DW 18		; 每磁道扇区数
BPB_NumHeads	DW 2		; 磁头数(面数)
BPB_HiddSec	DD 0		; 隐藏扇区数
BPB_TotSec32	DD 0		; 如果 wTotalSectorCount 是 0 由这个值记录扇区数

BS_DrvNum	DB 0		; 中断 13 的驱动器号
BS_Reserved1	DB 0		; 未使用
BS_BootSig	DB 29h		; 扩展引导标记 (29h)
BS_VolID	DD 0		; 卷序列号
BS_VolLab	DB 'linux0.11  '; 卷标, 必须 11 个字节
BS_FileSysType	DB 'FAT12   '	; 文件系统类型, 必须 8个字节
;------------------------------------------------------------------------
[section .data]
SYSSIZE equ 0x3000
SETUPLEN equ 4
BOOTSEG equ 0x07c0
INITSEG equ 0x9000
SETUPSEG equ 0x9020
SYSSEG equ 0x1000
ENDSEG equ SYSSEG + SYSSIZE
ROOT_DEV equ 0x306      ;根设备号

[section .text]

start:

mov ax,BOOTSEG   ;将bootsect从0x07c00复制到0x90000
mov ds,ax
mov ax,INITSEG
mov es,ax
mov cx,256
sub si,si
sub di,di
rep
movsw
jmp INITSEG:go

go:
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0xFF00

load_setup:      ;把setup.bin从软盘读到内存的0x90200处
mov dx,0x0000
mov cx,0x0002
mov bx,0x0200
mov ax,0x0200 +SETUPLEN
int 0x13
jnc ok_load_setup
mov dx,0x0000
mov ax,0x0000
int 0x13
jmp load_setup

ok_load_setup:

mov dl,0x00
mov ah,0x08
int 0x13
mov ch,0x00
mov [sectors],cx ;保存扇区数
mov ax,INITSEG
mov es,ax

mov ax,0x03  ;读光标位置
xor bh,bh
int 0x10

mov cx,24    ;显示字符
mov bx,0x0007
mov bp,msg1
mov ax,0x1300
int 0x10

mov ax,SYSSEG   ;把system.bin从软盘加载到内存的0x1000处
mov es,ax
call read_it
call kill_motor

mov ax,[root_dev]
cmp ax,0
jne root_defined
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:
mov [root_dev],ax

jmp SETUPSEG:0

sread: dw 1+SETUPLEN
head:  dw 0
track: dw 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:
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]
cmp ax,[sectors]
jne ok3_read
mov ax,1
sub ax,[head]
jne ok4_read
inc word [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
out dx,al
pop dx
ret

sectors: dw 0
msg1:
db 13,0
db "loading system ..."
db 13,10,13,10

times 508-($-$$) db 0

root_dev:
dw ROOT_DEV

boot_flag:
dw 0xaa55
setup.asm 用于测试bootsect的代码(即看bootsect是否将setup加载到内存)。

[section .data]
INITSEG equ 0x9000
SYSSEG equ 0x1000
[section .text]
mov ax,INITSEG
mov ds,ax
mov ax,cs
mov es,ax

mov dx,0x0200;在第3行显示
mov cx,13   ;显示字符串“this is setup”
mov bx,0x0007
mov bp,msg2
mov ax,0x1300
int 0x10

jmp SYSSEG:0

msg2:
db "this is setup"


system.asm 用于测试bootsect的代码(即看bootsect是否将system加载到内存)。

[section .text]
mov ax,cs
mov es,ax

mov dx,0x0300
mov cx,14   ;显示字符串“this is system”
mov bx,0x0007
mov bp,msg3
mov ax,0x1300
int 0x10

jmp $

msg3:
db "this is system"


bootsect的主要作用是把setup(4个扇区的大小)加载到内存0x90200处,把system(240个扇区的大小)加载到内存0x10000处。

bootsect.bin,setup.bin,system.bin都是放在软盘(这里用的是1.44M的)上的。bootsect.bin放在磁头0,柱面0,扇区1,setup.bin放在磁头0,柱面0,扇区2-5,system.bin放在磁头0,柱面0,扇区6到后面的共240个扇区。1.44M软盘的结构:2面、80道/面、18扇区/道、512字节/扇区。

由于要将bootsect.bin,setup.bin,system.bin这些文件写到指定的扇区,所以要用到相应的工具,请到网上下载。http://download.csdn.net/detail/liuqizealot/1019735

执行步骤:

1.先将bootsect.asm,setup.asm,system.asm编译成.bin文件

2.准备一个虚拟软盘

3.将bootsect.bin,setup.bin,system.bin写到软盘的相应扇区。

4.用虚拟机启动虚拟软盘

结果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: