码迷,mamicode.com
首页 > 其他好文 > 详细

Tinix写HelloWorld起步

时间:2015-02-11 23:16:51      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:

系统启动理论基础

机器启动之后处于实模式,这时候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而已,真正的操作系统之路还很远。事实上,后面的东西真的很难,起码对我来说是这样的,无论怎样都要加油!

技术分享

 

Tinix写HelloWorld起步

标签:

原文地址:http://www.cnblogs.com/liqiongxiong/p/4287041.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!