因为实习,没法一次性把课设做完,就干脆些把笔记写成博文方便自己查阅吧,持续更新,直至完成。
这课设的设计基本上是依赖于一本书的,大概是怕我们遇到太多的坑吧。。而OS上的坑又不是那么容易解决的,总之以下操作不带有普遍性。
课设平台:
- fedora 7
- linux-2.6.21 source code
- i386
实验1 编译内核
纯粹照着书搞。。
实验过程
以下操作假设用户为root,目录自行决定。
% tar -zxvf linux-2.6.21.tar.gz
% cd linux-2.6.21
% make mrproper # 清楚掉之前编译产生的垃圾
% make oldconfig # 如果自己有配置文件的话,直接 copy 进来命名为 .config 即可
% vim Makefile
修改EXTARVERSION ...
《操作系统概念》(第七版)第九章虚拟内存那章有如下这样一句话:
动态载入能够帮助减轻这一限制(将整个进程放入内存才能执行的限制),但是它需要程序员特别小心并且需要一些额外的工作。
那么,额外工作指的是? 在网上基本上已经搜不到书上所说的动态载入了,基本上都是.dll或者.so之类的。 以下为个人理解,理解基于动态载入不需要操作系统提供特别支持这一事实。
动态载入是以子程序为单元的,也就将一个程序写成了许多的子程序。在使用到了某个子程序时,程序员需要在程序中编码以检查该子程序是否已在内存中,不在内存中时,需要编码将其动态载入,这里的程序员的编码就是所谓的额外开销。比如下面这段代码(我不确定是否正确):
// so_obj是一个变量标识是否导入了某个.so
if (so_obj == NULL) {
// load it here
}
而虚拟内存是以页为单元的,一个程序被分放到了一些页上。而按需调页做到的是,当你在访问某一行代码,该代码在某一个不在内存中的页上时,操作系统会trap然后调页,从而将该代码所在页调入内存,从而看起来像是在“动态载入”了代码,但程序员没做任何事~
Update at 2014-05-26
因为动态加载和动态链接在操作系统的实现上已经模糊了 ...
大致的理解如下,不一定正确,确认后会更新:
按照一般的步骤,用户程序在执行前会经历以下几个步骤:
- 编译汇编
- 链接(将编译出来的模块和其他引用了的模块合并)
- 加载(从硬盘加载到内存中)
- 执行(在内存中执行)
动态加载和动态链接是打破以上所描述的常规行为的。
动态加载
硬盘上存储了一个已经生成好的目标模块,但是这个目标模块是由许多子程序组成的。每时每刻,不一定所有的子程序都需要在内存中,所以,在使用到相应子程序时再把其加载到内存中来使用,这要求用户在编写程序时合理地编写子程序,不需要操作系统提供特别的支持。
动态链接
它与动态加载的概念相似,但是,它不是将加载延迟到了执行时,而是将链接延迟到执行时。主要的问题就在于理解这句话。对于动态链接,磁盘上存储着的目标模块中包含着一部分它并未链接的模块(但是它迟早要用,所以动态链接嘛~)。而使用动态加载技术时,你动态加载的模块是经过链接之后的,也就是该模块已经结合了所有它会用到的模块,只是在你程序的不同地方使用了,所以在不同的地方动态加载需要的代码。
动态链接的实现是依赖于存根(stub)的,目标模块中在使用需要动态链接的模块的地方使用存根来代替,存根能够指出如何装入以及装入后的程序在内存的哪。
动态链接的好处在于多个程序使用到了一个相同的模块时,不需要将该模块都像常规步骤或者动态加载那样合并到目标模块中,而是在执行时再动态链接,这样在内存中就只用存在一份该模块的代码了,即实现了共享库。
Update at 2014-05-26 ...