linux0.11学习1之bootsect

        前段时间参考《自己动手写操作系统》来写操作系统,对操作系统有了更加深刻的认识。现在打算研读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.用虚拟机启动虚拟软盘

结果图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值