读书笔记《30天自制操作系统》day03
2012-12-13 22:59
337 查看
0. 自己试着在win7下用NASM和minGW改写汇编和C混合编程,结果受挫了。还是先使用作者提供的工具构建吧。
1. 通过前2天的工作已经能使用NASM制作一个映像了,并且编写的汇编代码可以成为引导扇区代码。
2. 引导扇区代码中可以调用BIOS中断,读取软盘上其它扇区到内存中,根据FAT12文件系统格式得知,保存到软盘内的第一个文件的文件名一定从19逻辑扇区开始,且该文件的内容从逻辑扇区33开始(见day01,图一)。
3. 引导扇区可以将第一个保存的文件(asmhead.nas,功能是跳入保护模式并调用C语言编写的函数代码)读入内存并使之执行,找这个文件用到了一个技巧(如2描述),不然通过文件系统结构分析出文件位置,并加载码就太复杂了。
4. 引导扇区代码如下ipl10.asm
BIOS 13中断说明(功能有磁盘的读、写、扇区校验、寻道)
AH=0x02 读盘/0x03写盘/0x04校验/0x0c寻道
AL=处理连续扇区数
CH=柱面号&0xff
CL=扇区号(0~5位)|(柱面号&0x300)>>2
DH=磁头号
DL=驱动器号
ES:BX=缓冲地址
返回值:FLAGS=0没有错误AH=0,FLAGS=1有错误AH保存错误码
5. 跳入保护模式代码如下asmhead.nas(1)准备GDT(2)用LGDT加载gdtr(3)打开A20(4)设置CR0的PE位(5)跳转进入保护模式
6. C语言代码如下bootpack.c
7. C语言中调用的io_hlt和write_mem8函数放到了如下代码中func.asm
8. 在toolset文件夹内建立一个新文件夹,将上面所有的文件放在里边,编译链接接上面的文件,写个bat文件如下
9.这样除了中间文件外,生成img.img文件和kernel.sys文件。使用winImage打开img.img文件将kernel.sys文件加入到该img文件中。
10. 启动Bochs,呵呵看见屏幕白了,这可是从C代码里控制的啊!
11. asmhead中跳入保护模式的代码慢慢在深入掌握,不然会掉入细节里不能自拔了。
12. (这句很经典)asmhead和C代码是通过copy /B进行链接的其中asmhead代码最后留了个标号bootpack,在这个标号后面C的目标代码被砍去文件头直接将代码链接到了这里,所以能实现从汇编跳转到C语言的目的。
1. 通过前2天的工作已经能使用NASM制作一个映像了,并且编写的汇编代码可以成为引导扇区代码。
2. 引导扇区代码中可以调用BIOS中断,读取软盘上其它扇区到内存中,根据FAT12文件系统格式得知,保存到软盘内的第一个文件的文件名一定从19逻辑扇区开始,且该文件的内容从逻辑扇区33开始(见day01,图一)。
3. 引导扇区可以将第一个保存的文件(asmhead.nas,功能是跳入保护模式并调用C语言编写的函数代码)读入内存并使之执行,找这个文件用到了一个技巧(如2描述),不然通过文件系统结构分析出文件位置,并加载码就太复杂了。
4. 引导扇区代码如下ipl10.asm
CYLS EQU 10 ORG 0x7c00 JMP entry DB 0x90 DB "HARIBOTE" DW 512 DB 1 DW 1 DB 2 DW 224 DW 2880 DB 0xf0 DW 9 DW 18 DW 2 DD 0 DD 2880 DB 0,0,0x29 DD 0xffffffff DB "HARIBOTEOS " DB "FAT12 " RESB 18 entry: MOV AX,0 MOV SS,AX MOV SP,0x7c00 MOV DS,AX MOV AX,0x0820 ;目的地址 MOV ES,AX MOV CH,0 ;柱面号 MOV DH,0 ;磁头号 MOV CL,2 ;扇区号 readloop: MOV SI,0 retry: MOV AH,0x02 ;读磁盘 MOV AL,1 ;读1个扇区 MOV BX,0 ;目的地址 MOV DL,0x00 ;驱动器号 INT 0x13 ;来BIOS中断 JNC next ADD SI,1 CMP SI,5 JAE error ;读五次还失败就放弃 MOV AH,0x00 ;重置驱动器功能号 MOV DL,0x00 ;驱动器号 INT 0x13 JMP retry next: MOV AX,ES ADD AX,0x0020 ;保存位置向后移动512字节,0x0020是段地址加偏移量后成为0x0200了 MOV ES,AX ADD CL,1 CMP CL,18 ;读18个扇区 JBE readloop MOV CL,1 ADD DH,1 CMP DH,2 JB readloop MOV DH,0 ADD CH,1 CMP CH,CYLS JB readloop MOV [0x0ff0],CH JMP 0xc200 ;跳到软盘kernel.sys(asmhead.nas+bootpack.c)文件内部执行 ;该文件在加载软盘文件基址0x8000+Fat12文件系统中文件出现位置0x004200处=0xc200H error: MOV SI,msg putloop: MOV AL,[SI] ADD SI,1 CMP AL,0 JE fin MOV AH,0x0e MOV BX,15 INT 0x10 JMP putloop fin: HLT JMP fin msg: DB 0x0a, 0x0a DB "load error" DB 0x0a DB 0; RESB 0x7dfe-$ times 510-($-$$) db 0 DB 0x55, 0xaa
BIOS 13中断说明(功能有磁盘的读、写、扇区校验、寻道)
AH=0x02 读盘/0x03写盘/0x04校验/0x0c寻道
AL=处理连续扇区数
CH=柱面号&0xff
CL=扇区号(0~5位)|(柱面号&0x300)>>2
DH=磁头号
DL=驱动器号
ES:BX=缓冲地址
返回值:FLAGS=0没有错误AH=0,FLAGS=1有错误AH保存错误码
5. 跳入保护模式代码如下asmhead.nas(1)准备GDT(2)用LGDT加载gdtr(3)打开A20(4)设置CR0的PE位(5)跳转进入保护模式
BOTPAK EQU 0x00280000 DSKCAC EQU 0x00100000 DSKCAC0 EQU 0x00008000 CYLS EQU 0x0ff0 LEDS EQU 0x0ff1 VMODE EQU 0x0ff2 SCRNX EQU 0x0ff4 SCRNY EQU 0x0ff6 VRAM EQU 0x0ff8 ORG 0xc200 ;让引导扇区加载后从这里开始运行,认为它们在一个段中所以能直接跳转过来 MOV AL,0x13 ;保存信息 MOV AH,0x00 INT 0x10 MOV BYTE [VMODE],8 MOV WORD [SCRNX],320 MOV WORD [SCRNY],200 MOV DWORD [VRAM],0x000a0000 MOV AH,0x02 INT 0x16 ; keyboard BIOS MOV [LEDS],AL MOV AL,0xff ;禁止PIC主从片的中断 OUT 0x21,AL NOP ;不能有两个连续的OUT指令 OUT 0xa1,AL CLI ;禁止PIC工作要在CLI之前 CALL waitkbdout ;等待键盘电路准备好,要设置A20使1MB以上内存能被访问 MOV AL,0xd1 OUT 0x64,AL CALL waitkbdout MOV AL,0xdf ; enable A20 OUT 0x60,AL CALL waitkbdout [INSTRSET "i486p"] LGDT [GDTR0] ;加载临时的GDT表首地址到GDTR寄存器 MOV EAX,CR0 AND EAX,0x7fffffff OR EAX,0x00000001 MOV CR0,EAX ;设置CR0寄存器PE标志位 JMP pipelineflush ;设置标志位之后马上JMP pipelineflush: ;从此寻址方式变了 MOV AX,1*8 ;段值的设置,用GDT中那个段(GDT+1段) MOV DS,AX MOV ES,AX MOV FS,AX MOV GS,AX MOV SS,AX MOV ESI,bootpack ;将bootpack.c生成的目标代码移动到0x00280000,乾坤大挪移 MOV EDI,BOTPAK MOV ECX,512*1024/4 CALL memcpy MOV ESI,0x7c00 ;将启动扇区复制到1MB以后的内存 MOV EDI,DSKCAC MOV ECX,512/4 CALL memcpy MOV ESI,DSKCAC0+512 ;将0x00008200数据复制到0x00100200 MOV EDI,DSKCAC+512 MOV ECX,0 MOV CL,BYTE [CYLS] IMUL ECX,512*18*2/4 SUB ECX,512/4 CALL memcpy ;至此内存中0x00100000部分与磁盘内容就一样了 ;调用bootpack.c的初始化操作,解析bootpack.hrb的header并传入参数 MOV EBX,BOTPAK MOV ECX,[EBX+16] ADD ECX,3 SHR ECX,2 JZ skip MOV ESI,[EBX+20] ADD ESI,EBX MOV EDI,[EBX+12] CALL memcpy skip: MOV ESP,[EBX+12] JMP DWORD 2*8:0x0000001b ;跳到指定段中跳过可执行文件头p421 waitkbdout: IN AL,0x64 AND AL,0x02 JNZ waitkbdout RET memcpy: MOV EAX,[ESI] ADD ESI,4 MOV [EDI],EAX ADD EDI,4 SUB ECX,1 JNZ memcpy RET ALIGNB 16 GDT0: ;临时设计的GDT表 RESB 8 DW 0xffff,0x0000,0x9200,0x00cf DW 0xffff,0x0000,0x9a28,0x0047 DW 0 GDTR0: ;临时设计的GDT选择子 DW 8*3-1 DD GDT0 ALIGNB 16 bootpack:
6. C语言代码如下bootpack.c
void io_hlt(void); void write_mem8(int addr,int data); void HariMain(void) { int i; for(i=0xa0000;i<=0xaffff;i++) { write_mem8(i,15); /*向内存的0xa0000~0xaffff位置写入信息,这块内存是显存空间,15是白色*/ } for(;;) { io_hlt(); } }
7. C语言中调用的io_hlt和write_mem8函数放到了如下代码中func.asm
[FORMAT "WCOFF"] [INSTRSET "i486p"] [BITS 32] [FILE "naskfunc.nas"] global _io_hlt,_write_mem8 [section .text] ;void io_hlt(void); _io_hlt: HLT RET ;void write_mem8(int addr,int data); _write_mem8: MOV ECX,[ESP+4] MOV AL,[ESP+8] MOV [ECX],AL RET
8. 在toolset文件夹内建立一个新文件夹,将上面所有的文件放在里边,编译链接接上面的文件,写个bat文件如下
nasm -o ipl10.bin ipl10.asm ;生成引导扇区代码 nasm -o img.img img.asm ;生成软盘镜像文件 ..\z_tools\nask.exe asmhead.nas asmhead.bin ..\z_tools\cc1.exe -I..\z_tools\haribote\ -Os -Wall -quiet -o bootpack.gas bootpack.c ..\z_tools\gas2nask.exe -a bootpack.gas bootpack.nas ..\z_tools\nask.exe bootpack.nas bootpack.obj ..\z_tools\nask.exe func.asm func.obj ..\z_tools\obj2bim.exe @..\z_tools\haribote\haribote.rul out:bootpack.bim stack:3136k map:bootpack.map bootpack.obj func.obj ..\z_tools\bim2hrb.exe bootpack.bim bootpack.hrb 0 copy /B asmhead.bin+bootpack.hrb kernel.sys
9.这样除了中间文件外,生成img.img文件和kernel.sys文件。使用winImage打开img.img文件将kernel.sys文件加入到该img文件中。
10. 启动Bochs,呵呵看见屏幕白了,这可是从C代码里控制的啊!
11. asmhead中跳入保护模式的代码慢慢在深入掌握,不然会掉入细节里不能自拔了。
12. (这句很经典)asmhead和C代码是通过copy /B进行链接的其中asmhead代码最后留了个标号bootpack,在这个标号后面C的目标代码被砍去文件头直接将代码链接到了这里,所以能实现从汇编跳转到C语言的目的。
相关文章推荐
- 读书笔记《30天自制操作系统》day03
- 读书笔记《30天自制操作系统》day03
- 多定时器处理2(30天自制操作系统 -- 读书笔记)
- 读书笔记《30天自制操作系统》day11
- 读书笔记《30天自制操作系统》day12~day13
- 多定时器处理3(30天自制操作系统 -- 读书笔记)
- 读书笔记《30天自制操作系统》day12~day13
- 《30天自制操作系统》读书笔记Day6
- 《30天自制操作系统》读书笔记(5) GDT&IDT
- 【1】--《30天自制操作系统》读书笔记--0~3天
- 《30天自制操作系统》读书笔记Day16
- 读书笔记《30天自制操作系统》day01
- 《30天自制操作系统》读书笔记(4) 绘图
- 读书笔记《30天自制操作系统》day02
- 《30天自制操作系统》读书笔记(6) 鼠标键盘
- 《30天自制操作系统》读书笔记Day9
- 读书笔记《30天自制操作系统》day11
- 《30天自制操作系统》读书笔记Day3
- 《30天自制操作系统》读书笔记(3) 引入C语言
- 《30天自制操作系统》读书笔记Day17