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内核完全注释》
system.asm 用于测试bootsect的代码(即看bootsect是否将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.用虚拟机启动虚拟软盘
结果图:
现在给出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 0xaa55setup.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.用虚拟机启动虚拟软盘
结果图:
相关文章推荐
- Linux 0.11 bootsect.s 学习笔记
- bootsect.s 分析—— Linux-0.11 学习笔记(一)
- linux 0.11 内核学习 -- bootsect.s, 万里长征第一步
- linux 0.11 内核学习 -- bootsect.s, 万里长征第一步
- Linux1.0 kernel bootsect.S 学习日记
- linux0.11启动第一步:bootsect.s
- linux0.11内核代码之bootsect.s
- 用nasm语言重新实现linux-0.11 bootsect.s(博古以通今)
- Linux0.11内核--启动引导代码分析bootsect.s
- linux 0.11 version 启动代码分析(bootsect.s)
- Linux0.11内核--启动引导代码分析bootsect.s
- Linux 0.11/boot/bootsect.s
- linux0.11源码阅读笔记1-启动流程-bootsect.s
- linux-0.11调试教程,bootsect.s文件调试,Loading system ...
- linux-0.11中bootsect.s分析
- Linux 0.11内核bootsect.s和loader.s的移植为AT&T汇编
- Linux0.11内核--启动引导代码分析bootsect.s
- linux0.11 bootsect.s 分析
- linux 0.11 bootsect.s中的BIOS部分解读
- Linux0.11 引导程序Boot学习