读书笔记《30天自制操作系统》day03
来源:互联网 发布:林徽因 知乎 编辑:程序博客网 时间:2024/05/08 21:13
0. 自己试着在win7下用NASM和minGW改写汇编和C混合编程,结果受挫了。还是先使用作者提供的工具构建吧。
1. 通过前2天的工作已经能使用NASM制作一个映像了,并且编写的汇编代码可以成为引导扇区代码。
2. 引导扇区代码中可以调用BIOS中断,读取软盘上其它扇区到内存中,根据FAT12文件系统格式得知,保存到软盘内的第一个文件的文件名一定从19逻辑扇区开始,且该文件的内容从逻辑扇区33开始(见day01,图一)。
3. 引导扇区可以将第一个保存的文件(asmhead.nas,功能是跳入保护模式并调用C语言编写的函数代码)读入内存并使之执行,找这个文件用到了一个技巧(如2描述),不然通过文件系统结构分析出文件位置,并加载码就太复杂了。
4. 引导扇区代码如下ipl10.asm
CYLSEQU10ORG0x7c00JMPentryDB0x90DB"HARIBOTE"DW512DB1DW1DB2DW224DW2880DB0xf0DW9DW18DW2DD0DD2880DB0,0,0x29DD0xffffffffDB"HARIBOTEOS "DB"FAT12 "RESB18entry:MOVAX,0MOVSS,AXMOVSP,0x7c00MOVDS,AXMOVAX,0x0820 ;目的地址MOVES,AXMOVCH,0 ;柱面号MOVDH,0 ;磁头号MOVCL,2 ;扇区号readloop:MOVSI,0retry:MOVAH,0x02 ;读磁盘MOVAL,1 ;读1个扇区MOVBX,0 ;目的地址MOVDL,0x00 ;驱动器号INT0x13 ;来BIOS中断JNCnextADDSI,1CMPSI,5JAEerror ;读五次还失败就放弃MOVAH,0x00 ;重置驱动器功能号MOVDL,0x00 ;驱动器号INT0x13JMPretrynext:MOVAX,ESADDAX,0x0020 ;保存位置向后移动512字节,0x0020是段地址加偏移量后成为0x0200了MOVES,AXADDCL,1CMPCL,18 ;读18个扇区JBEreadloopMOVCL,1ADDDH,1CMPDH,2JBreadloopMOVDH,0ADDCH,1CMPCH,CYLSJBreadloopMOV[0x0ff0],CHJMP0xc200 ;跳到软盘kernel.sys(asmhead.nas+bootpack.c)文件内部执行 ;该文件在加载软盘文件基址0x8000+Fat12文件系统中文件出现位置0x004200处=0xc200Herror: MOV SI,msgputloop: MOVAL,[SI] ADDSI,1 CMPAL,0 JEfin MOVAH,0x0e MOVBX,15 INT0x10 JMPputloopfin: HLT JMPfinmsg: DB0x0a, 0x0a DB"load error" DB0x0a DB0; RESB 0x7dfe-$ times 510-($-$$) db 0 DB0x55, 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)跳转进入保护模式
BOTPAKEQU0x00280000DSKCACEQU0x00100000DSKCAC0EQU0x00008000CYLSEQU0x0ff0LEDSEQU0x0ff1VMODEEQU0x0ff2SCRNXEQU0x0ff4SCRNYEQU0x0ff6VRAMEQU0x0ff8ORG0xc200 ;让引导扇区加载后从这里开始运行,认为它们在一个段中所以能直接跳转过来MOVAL,0x13;保存信息MOVAH,0x00INT0x10MOVBYTE [VMODE],8MOVWORD [SCRNX],320MOVWORD [SCRNY],200MOVDWORD [VRAM],0x000a0000MOVAH,0x02INT0x16 ; keyboard BIOSMOV[LEDS],ALMOVAL,0xff ;禁止PIC主从片的中断 OUT0x21,ALNOP;不能有两个连续的OUT指令OUT0xa1,ALCLI ;禁止PIC工作要在CLI之前CALLwaitkbdout ;等待键盘电路准备好,要设置A20使1MB以上内存能被访问MOVAL,0xd1OUT0x64,ALCALLwaitkbdoutMOVAL,0xdf; enable A20OUT0x60,ALCALLwaitkbdout[INSTRSET "i486p"]LGDT[GDTR0] ;加载临时的GDT表首地址到GDTR寄存器MOVEAX,CR0ANDEAX,0x7fffffffOREAX,0x00000001MOVCR0,EAX ;设置CR0寄存器PE标志位JMPpipelineflush ;设置标志位之后马上JMPpipelineflush: ;从此寻址方式变了MOVAX,1*8 ;段值的设置,用GDT中那个段(GDT+1段)MOVDS,AXMOVES,AXMOVFS,AXMOVGS,AXMOVSS,AXMOVESI,bootpack ;将bootpack.c生成的目标代码移动到0x00280000,乾坤大挪移MOVEDI,BOTPAKMOVECX,512*1024/4CALLmemcpyMOVESI,0x7c00 ;将启动扇区复制到1MB以后的内存MOVEDI,DSKCACMOVECX,512/4CALLmemcpyMOVESI,DSKCAC0+512 ;将0x00008200数据复制到0x00100200MOVEDI,DSKCAC+512MOVECX,0MOVCL,BYTE [CYLS]IMUL ECX,512*18*2/4SUBECX,512/4CALLmemcpy ;至此内存中0x00100000部分与磁盘内容就一样了 ;调用bootpack.c的初始化操作,解析bootpack.hrb的header并传入参数MOVEBX,BOTPAKMOVECX,[EBX+16]ADDECX,3SHRECX,2JZskipMOVESI,[EBX+20]ADDESI,EBXMOVEDI,[EBX+12]CALLmemcpyskip:MOVESP,[EBX+12]JMPDWORD 2*8:0x0000001b ;跳到指定段中跳过可执行文件头p421waitkbdout:IN AL,0x64AND AL,0x02JNZwaitkbdoutRETmemcpy:MOVEAX,[ESI]ADDESI,4MOV[EDI],EAXADDEDI,4SUBECX,1JNZmemcpyRETALIGNB16GDT0: ;临时设计的GDT表RESB8DW0xffff,0x0000,0x9200,0x00cfDW0xffff,0x0000,0x9a28,0x0047DW0GDTR0: ;临时设计的GDT选择子DW8*3-1DDGDT0ALIGNB16bootpack:
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:HLTRET;void write_mem8(int addr,int data);_write_mem8:MOV ECX,[ESP+4]MOV AL,[ESP+8]MOV [ECX],ALRET
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 0copy /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
- 读书笔记《30天自制操作系统》day03
- 读书笔记《30天自制操作系统》day01
- 读书笔记《30天自制操作系统》day02
- 读书笔记《30天自制操作系统》day04
- 读书笔记《30天自制操作系统》day05
- 读书笔记《30天自制操作系统》day06
- 读书笔记《30天自制操作系统》day07
- 读书笔记《30天自制操作系统》day08
- 读书笔记《30天自制操作系统》day09
- 读书笔记《30天自制操作系统》day10
- 读书笔记《30天自制操作系统》day11
- 读书笔记《30天自制操作系统》day01
- 读书笔记《30天自制操作系统》day02
- 读书笔记《30天自制操作系统》day12~day13
- 读书笔记《30天自制操作系统》day01
- 读书笔记《30天自制操作系统》day02
- Flash Player 11.2正式发布 多线程视频解码
- 【排序】静态表格实现排序功能
- 如何删除幽灵设备(Phantom Devices)
- 编译TortoiseSVN源代码
- GetTempFileNameW详解
- 读书笔记《30天自制操作系统》day03
- 《WEB应用开发》复习题(二)
- map/reduce unit test
- LBS基站定位和GPS卫星定位对比
- 水晶报表(CrystalReports)的简单应用(ASP.NET)
- java 面向对象编程整理一
- 用libvlc进行网络串流streaming
- Windows本地编译TortoiseSVN项目源代码
- UNIX文件权限详解(尤其是SUID和SGID)