标签:
系统启动理论基础
机器启动之后处于实模式,这时候CS=DS=ES=SS=0xFFFF,IP=0x0000,从CS:IP也就是0xFFFF0开始自动执行程序代码,这个地址通常是BIOS中的地址,但由于这个地址开始到结束也只有16个字节的空间,所以这里一般存放的是BIOS的跳转指令,跳转到BIOS真正的代码地址中。
执行PC机中的BIOS代码时将执行系统硬件的检测,并在物理地址0处初始化中断向量。此后它将设备的第一个扇区(512字节的引导扇区,这里假定只有软盘)读入到内存绝对地址0x7c00处,并跳转到这个地址。
通常这个引导扇区存的是boot模块的代码,boot模块的主要工作是负责将load模块的代码从软盘读取至内存,并跳转到load代码中执行,因为load模块代码大小可能不止一个扇区,所以不能将load代码作为引导扇区启动,load模块主要为加载kernel模块。
那怎么样叫一个引导扇区呢?
软盘的第0个扇区,也就是0面0道1扇区,对于这个扇区的512个字节,如果最后的两个字节为0xAA55,那么BIOS则认为该软盘为一个引导扇区。当然除了这个之外,这个扇区应该有一段小于512字节的执行码。
令人迷惑的ox7c00
0x7c00干了啥?书中的代码1-1,第一句是org 0x7c00,上面BIOS将引导扇区读入到的内存地址也是0x7c00,这两个是否同一个意思呢?如果去掉这句又有什么不同呢?
在这里我编译了两个版本的boot,分别是boot_7c00.bin,boot_0100.bin,第一个使用org 07c00h编译,第二个使用org 0100h编译。
直接使用beyond compare比较两个bin文件,发现除了一个位置之外两个文件包完全相同,而这个不同就是这里指定的7c以及01。
对于dos下面跑的com文件,将来加载到的起始地址在0x0100h,用作boot的文件将来加载到的起始地址在0x7c00h,使用nasm提供的ndisasm.exe指定起始地址反编译刚才生成的bin文件,分别生成disboot_7c00.asm以及disboot_0100.asm文件。
再行比较生成的两个反编译disboot_7c00.asm以及disboot_0100.asm文件,发现除了第一列起始地址外,相对于原来的boot.asm代码有几个不同的地方。
1、 org 这一行在反汇编里面不存在,因为这句不是intel指令,是编译器指令。
2、 call DispStr,jmp $这两句的机器指令是一致的,但是反编译出来的汇编代码不一致,也就是说反编译出来的汇编指令加上了代码段地址。
3、 mov ax, BootMessage这句汇编语句被编译成真正的地址,而真正的地址都被加上了数据段地址,BootMessage的地址在0x7c1f以及0x011f处,下来到0x7c1f的下面,两侧的机器码都是一致的,分别是48 65 6C 6C 6F…转换回ASCII就是Hello…
综上所述,org这句实际上是在编译的时候为数据生成了真实的数据地址。
小提示:查看ASCII的时候可以使用linux中的man ascii命令来进行查看
Helloword代码解析
对于1-1这个代码片段,书中基本上都已经解析了,但是有一个int 10h中断书中没怎么解析,这里再贴一下int 10h中断的用法如下,AH=13是表示显示字符串的功能号。
1 DispStr: 2 mov ax, BootMessage 3 mov bp, ax ; ES:BP = 串地址 4 mov cx, 16 ; CX = 串长度 5 mov ax, 01301h ; AH = 13, AL = 01h 6 mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮) 7 mov dl, 0 8 int 10h ; 10h 号中断 9 ret
功能号:13H
功能:在Teletype模式下显示字符串
入口参数:AH=13H
BH=页码
BL=属性(若AL=00H或01H)
CX=显示字符串长度
(DH、DL)=坐标(行、列)
ES:BP=显示字符串的地址 AL=显示输出方式
0—字符串中只含显示字符,其显示属性在BL中。显示后,光标位置不变
1—字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变
2—字符串中含显示字符和显示属性。显示后,光标位置不变
3—字符串中含显示字符和显示属性。显示后,光标位置改变
操作系统的hello world
使用命令nasm boot.asm –o boot.bin编译boot.asm生成boot.bin文件;生成一个新的镜像文件Tinix.img,生成镜像的方式有多种,如linux下的dd命令,或windows下也可使用fsutil命令生成,或使用VDM生成;生成镜像后直接使用于渊提供的工具FloppyWriter.exe来将boot.bin写入软盘镜像的引导扇区。
注意,软盘镜像不要在dos下格式化然后将Tinix.img虚拟成软盘,再拷贝boot.bin进去,这样拷贝的boot.bin其位置不在引导扇区。
设置debug虚拟机的软盘镜像
确定之后,启动debug虚拟机,可以看到红色的Hello, OS world! 怎么样,不是很难把?当然这只是一个boot而已,真正的操作系统之路还很远。事实上,后面的东西真的很难,起码对我来说是这样的,无论怎样都要加油!
标签:
原文地址:http://www.cnblogs.com/liqiongxiong/p/4287041.html