跟大师学习系统编程---操作系统加载(1)
来源:互联网 发布:vue引入第三方js 编辑:程序博客网 时间:2024/06/07 07:01
简介
本文选取linux 0.11版本,描述操作系统是如何加载起来的。读者可以参考《linux内核完全注释》这本书,作者赵炯。本文主要选取这一主题最重要的方面进行说明。
当开发linux 0.11版本时,linus torwards自己的pc是80386的cpu。
当PC的电源打开后,80x86结构的CPU将自动进入实模式,并从地址0xFFFF0开始自动执行程序代码,这个地址通常是ROM-BIOS中的地址。
PC机的BIOS将执行某些系统的检测,并在物理地址0处开始初始化中断向量。此后,它将可启动设备的第一个扇区(磁盘引导扇区,512
字节)读入内存绝对地址0x7C00处,并跳转到这个地方。启动设备通常是软驱或是硬盘。
注意:这里有一个可启动设备的概念。相信大多数同学安装过windows操作系统,在BIOS设置菜单中可以设置可启动设备的优先顺序,假定系统中只有2种可启动设备,一块硬盘和一块光盘。并且设置成了硬盘优先,那么会出现一种状况:无法安装新的操作系统,因为始终启动硬盘中已经存在的操作系统。 此时,就需要进入BIOS设置菜单中,调整可启动设备优先顺序,优先启动光盘,保存配置重启后。BIOS检测到光盘中有可启动系统,则执行光盘中的程序,然后我们就可以安装操作系统了。
启动
.globl begtext, begdata, begbss, endtext, enddata, endbss.textbegtext:.databegdata:.bssbegbss:.textSETUPLEN = 4 ! nr of setup-sectorsBOOTSEG = 0x07c0 ! original address of boot-sectorINITSEG = 0x9000 ! we move boot here - out of the waySETUPSEG = 0x9020 ! setup starts hereSYSSEG = 0x1000 ! system loaded at 0x10000 (65536).ENDSEG = SYSSEG + SYSSIZE ! where to stop loading! ROOT_DEV: 0x000 - same type of floppy as boot.! 0x301 - first partition on first drive etcROOT_DEV = 0x306
上述代码使用了8086的汇编语言,当前CPU工作在实模式。本段代码声明了数据段,代码段,BSS段(未初始化数据段)当前是共享的。上述那些常量并不占用内存,只在实际使用的时候替换对应的汇编指令?
需要说明的是:BOOTSEG = 0x07c0这个地址即OS与BIOS之间的约定,BIOS将操作系统的第一行代码加载到这个位置。不同的CPU架构,这个代码位置是不同的。
entry startstart: mov ax,#BOOTSEG mov ds,ax mov ax,#INITSEG mov es,ax mov cx,#256 sub si,si sub di,di rep movw jmpi go,INITSEGgo: mov ax,cs
start开始即为操作系统的第1条可执行语句(mov ax,#BOOTSEG),其存放位置就是0x07c00。
这段代码的含义是将自身(512字节)拷贝到另外一个内存区(INITSEG)区域。即从内存(0x07c00–0x07e00)拷贝到(0x90000–0x90200)。然后跳转到0x90000对应的内存区去执行go标签对应的语句——即已经在另外一个内存区执行了指令mov ax, cs了。原来的内存区中只会执行前十行代码。
为什么需要将这512字节的代码和数据移动到另外一个地方,不移动行不行? 在后面的代码会看到,启动代码分成了3部分
- bootsect.s
- setup.s
- system(剩余的的内核代码打包而成)
bootsect.s主要负责将setup.s和system加载进内存。考虑到中断向量表在0地址附近,在setup.s中还需要使用,所以system先加载到0x10000以后。并且linus 为system预留了0x80000字节空间(在当时看,这个空间足够了)。
当setup.s使用完中断向量(利用中断获取一些硬件配置参数)以后,则把system从0x10000~0x8ffff移动到0x00000~0x7fffff。因此,setup.s必须处于0x90000以后,否则setup.s执行system移动过程中会修改代码自身(假定setup.s放在0x00000~0x10000内存区)。
而且setup.s获取到的参数也必须保存在0x90000以后。否则其会修订system代码或者被system代码修改。
结论:bootsect.s移动到0x90000不是必须的,但setup.s移动到0x90000之后是必须的,linus torwards先移动了bootsect.s,然后让setup.s(0x90200)位于bootsect.s之后,最后setup.s获取的参数覆盖bootsect.s(0x90000~0x90200)的内存区。到达了上述要求。
加载setup.s到0x90000之外是必须的,且setup.s的数据存储在0x90000之外也是必须的。
- 跟大师学习系统编程---操作系统加载(1)
- 跟大师学习系统编程---操作系统加载(2)
- 跟大师学习系统编程---操作系统加载(3)
- 跟大师学习系统编程---操作系统加载(4)
- 跟大师学习系统编程---操作系统加载(5)
- 跟大师学习系统编程---操作系统加载(6)
- 跟大师学习系统编程---操作系统加载(7)
- 跟大师学习系统编程---操作系统加载(8)
- 跟大师学习系统编程---操作系统加载(9)
- 跟大师学习系统编程---linux时间换算
- windows游戏编程大师技巧2学习感悟(1)
- 《WINDOWS游戏编程大师技巧》学习笔记1
- 操作系统学习(1)
- 操作系统学习(1)
- 跟我学编程(1)
- 跟择善老师系统学习JAVA(一)
- windows游戏编程大师技巧--读书笔记1
- windows游戏编程大师技巧1
- 区分编译型语言,解释型语言是否还有意义?
- C++和Lua交互教程(基于LuaBridge)
- 39、C#项目开发注意
- 在同一台服务器上配置多个Tomcat的方法
- spring boot 1.5.7 搭建基础项目框架一
- 跟大师学习系统编程---操作系统加载(1)
- [容斥] Topcoder SRM div1-3 12004. SetAndSet
- 实现右键屏蔽菜单的代码
- 二进制、八进制、十进制、十六进制
- 基于kurento的RtpEndpoint元素实现的loopback
- 1002. 写出这个数 (20)PAT乙级真题
- ng-change 在input type=file时失效的解决办法
- bzoj 2143 飞飞侠【最短路】
- 转DjVu格式为什么要选人工转?