一个小的OS内核,一些感受,一些总结。
2006-12-18 17:51
295 查看
前几天刚读了《Bran的内核开发指南》,感觉有些收获。这里简单总结一下。
可以从http://rammaker.cosoft.org.cn/store/bkerndev_zh_CN_beta/index.htm得到完整的文档。
首先介绍下我的环境:
DJGPP,NASM [Windows]
VMWare WorkStation.(上跑RedHat Linux)
在将一个编译好的简单kernel运行的时候,用的是VMWare上虚拟的软盘。至于怎样在软盘上装grub等,不提。
下面说下几点体会:
1.对于一个整个系统,或者叫一个整个的工程,一般都是有若干个小的部分组成的。以这个kernel为例,为了生成最终的一个kernel.bin,需要编写若干个.c文件和一个.asm文件。在分别将这些文件编译成.o后,最终需要一个ld的过程。从最终文件来看,这些各组成文件中的符号应该是全局惟一的,因为他们最终都会在kernel.bin中存在。以前在学习c的时候,讲到关键字extern,说它的作用是声明一个变量或者函数在另外一个模块中定义,现在终于体会到了是怎么一回事。也从全局的角度来看,对于.bin的贡献(^_^),.asm和.c是相同的。只是.asm只需一个nasm,而.c需要预处理,编译,汇编的过程而已。
2.在过程中,曾遇到这样一个问题:我在DJGPP中gcc了那些.c文件,但是我却在RH Linux中用ld,结果总是出现某些符号为定义的错误。找过去,找过来,最终发现一个问题。在DJGPP中GCC生成的文件是COFF格式,而RH LINUX下的LD需要的是ELF格式。我猜测,因为格式的不同,ELF格式中对于.C的函数和变量符号在汇编后,在.S中是用本身的符号表示的,而不做变换。如.C中有函数ABC(),在编译后的.S中也以符号ABC表示;而COFF格式中对于.C的函数和变量符号在汇编后,在.S中会对他们的符号作些变换,具体是在前面加一个下画线。例如:.C中的函数ABC()在编译后的.S中会以符号_ABC表示。所以,当我换在WINDOWS CMD下,用LD链接后,没有出现问题。这时用的LD应该就是以COFF格式输入的。
3.在生成了KERNEL.BIN后,COPY到软盘下时,要注意:在BOOT/GRUB下面的STAGE1,2的访问权限要有X。(试试知道的)
4.在汇编和C间传递参数用栈就可以了。并且,可以定义结构来表示栈中的内容,但要主要栈中内容的顺序和结构的顺序。
对于OS内核,有些感受:
5.正如MULTIBOOT规范中所讲,一个OS的内核的格式应该可以是操作系统中可以运行的文件的格式,入A.OUT、ELF等。为了能够引导不同格式的内核,也及可以利用MULTIBOOT,那么就必须在内核文件的开头或者某些特殊位置定义某些固定的变量。如MAGIC等。
6.接上,既然内核可以是一般格式的可执行文件。那么它就可以象应用程序那样使用系统的内存,该文件也可以定义若干的数据结构。只是,为了满足硬件对于操作系统的支持,需要把这些数据结构的地址,大小等加载到某些特定功能的寄存器。如GDT的地址和大小限制需要一个数据结构来表示,该结构的地址需要被LOAD到GDTR中,类似的还有IDT和IDTR.
7.在IDT中保存了若干的中断号以及中断服务程序的地址后,也可以对它们的映射关系做改变。当然,对于开始的32个中断(异常)是保留的,后面的可以自己映射。对于这里,以前一直不是很理解,现在简单总结一下中断。当一个中断源(如键盘,系统时钟)到来时,在8259对它们进行优先级判断等操作后通知CPU,CPU在得到它们的中断号后,通过IDTR得到IDT的基地址,然后用中断号取出距离IDT若干距离的ISR的地址,并转到该ISR运行。注意,这个IDTR是我们用指令LIDT写入的。其实,从这个KERNEL来看,我们就只需加载GDTR和IDTR,以及提供一些映射就可以了。其他的,CPU会在遇到某种情况时自己找到该运行的程序。
上面的东西,部分是我自己猜测的,希望各位看官能够指出其中的错误。感谢万分。
可以从http://rammaker.cosoft.org.cn/store/bkerndev_zh_CN_beta/index.htm得到完整的文档。
首先介绍下我的环境:
DJGPP,NASM [Windows]
VMWare WorkStation.(上跑RedHat Linux)
在将一个编译好的简单kernel运行的时候,用的是VMWare上虚拟的软盘。至于怎样在软盘上装grub等,不提。
下面说下几点体会:
1.对于一个整个系统,或者叫一个整个的工程,一般都是有若干个小的部分组成的。以这个kernel为例,为了生成最终的一个kernel.bin,需要编写若干个.c文件和一个.asm文件。在分别将这些文件编译成.o后,最终需要一个ld的过程。从最终文件来看,这些各组成文件中的符号应该是全局惟一的,因为他们最终都会在kernel.bin中存在。以前在学习c的时候,讲到关键字extern,说它的作用是声明一个变量或者函数在另外一个模块中定义,现在终于体会到了是怎么一回事。也从全局的角度来看,对于.bin的贡献(^_^),.asm和.c是相同的。只是.asm只需一个nasm,而.c需要预处理,编译,汇编的过程而已。
2.在过程中,曾遇到这样一个问题:我在DJGPP中gcc了那些.c文件,但是我却在RH Linux中用ld,结果总是出现某些符号为定义的错误。找过去,找过来,最终发现一个问题。在DJGPP中GCC生成的文件是COFF格式,而RH LINUX下的LD需要的是ELF格式。我猜测,因为格式的不同,ELF格式中对于.C的函数和变量符号在汇编后,在.S中是用本身的符号表示的,而不做变换。如.C中有函数ABC(),在编译后的.S中也以符号ABC表示;而COFF格式中对于.C的函数和变量符号在汇编后,在.S中会对他们的符号作些变换,具体是在前面加一个下画线。例如:.C中的函数ABC()在编译后的.S中会以符号_ABC表示。所以,当我换在WINDOWS CMD下,用LD链接后,没有出现问题。这时用的LD应该就是以COFF格式输入的。
3.在生成了KERNEL.BIN后,COPY到软盘下时,要注意:在BOOT/GRUB下面的STAGE1,2的访问权限要有X。(试试知道的)
4.在汇编和C间传递参数用栈就可以了。并且,可以定义结构来表示栈中的内容,但要主要栈中内容的顺序和结构的顺序。
对于OS内核,有些感受:
5.正如MULTIBOOT规范中所讲,一个OS的内核的格式应该可以是操作系统中可以运行的文件的格式,入A.OUT、ELF等。为了能够引导不同格式的内核,也及可以利用MULTIBOOT,那么就必须在内核文件的开头或者某些特殊位置定义某些固定的变量。如MAGIC等。
6.接上,既然内核可以是一般格式的可执行文件。那么它就可以象应用程序那样使用系统的内存,该文件也可以定义若干的数据结构。只是,为了满足硬件对于操作系统的支持,需要把这些数据结构的地址,大小等加载到某些特定功能的寄存器。如GDT的地址和大小限制需要一个数据结构来表示,该结构的地址需要被LOAD到GDTR中,类似的还有IDT和IDTR.
7.在IDT中保存了若干的中断号以及中断服务程序的地址后,也可以对它们的映射关系做改变。当然,对于开始的32个中断(异常)是保留的,后面的可以自己映射。对于这里,以前一直不是很理解,现在简单总结一下中断。当一个中断源(如键盘,系统时钟)到来时,在8259对它们进行优先级判断等操作后通知CPU,CPU在得到它们的中断号后,通过IDTR得到IDT的基地址,然后用中断号取出距离IDT若干距离的ISR的地址,并转到该ISR运行。注意,这个IDTR是我们用指令LIDT写入的。其实,从这个KERNEL来看,我们就只需加载GDTR和IDTR,以及提供一些映射就可以了。其他的,CPU会在遇到某种情况时自己找到该运行的程序。
上面的东西,部分是我自己猜测的,希望各位看官能够指出其中的错误。感谢万分。
相关文章推荐
- 一个简单的CUDA程序以及一些总结
- 内核启动后停止的一些错误总结
- 个人总结的一个中高级Java开发工程师或架构师需要掌握的一些技能
- 内核启动的一些总结
- 面试总结-OS篇(windows与linux内核对比)
- 做一个商务网站的一些总结与收获
- 事件代理总结: 已经有一些使用主流类库的事件代理示例出现了,比如说jQuery、Prototype以及Yahoo! UI。你也可以找到那些不用任何类库的例子,比如说Usable Type blog上的这一个。一旦需要的话,事件代理将是你工具箱里的一件得心应手的工具,而且它很容易实现。
- μC/OS-II是一个基于抢占式的实时多任务内核
- eclipse调试一个struts2例子时遇到的一些问题总结
- 一个小项目后的一些技术小总结
- 刚进软件公司的一些感受总结
- 对近期使用Nhibernate开发的一个项目的一些总结(一)
- 内核移植出错的一些总结
- 个人总结的一个中高级Java开发工程师或架构师需要掌握的一些技能
- 个人总结的一个中高级Java开发工程师或架构师需要掌握的一些技能
- 从cpu加电到加载OS内核的详细过程(清华大学ucore-lab1总结一)
- 开发中碰到过的一些问题总结,给自己也给大家一个参考!
- 接触Matlab10年后的一个总结,随时使用Matlab要掌握的一些要点
- 程序员面试金典——解题总结: 9.18高难度题 18.9随机生成一些数字并传入某个方法。编写一个程序,每当收到新数字时,找出并记录中位数。
- 刚用MVC完成一个小项目,总结一些MVC技巧