首页 > 代码库 > linux0.11学习笔记(2)
linux0.11学习笔记(2)
makefile文件:
makefile 文件是make 工具程序的配置文件。make 程序是使用Makefile数据文件和代码文件的最后修改时间(last-modification time)来确定那些文件需要进行更新,对于每一个需要更新的文件它会根据Makefile 中的信息发出相应的命令。在Makefile 文件中,开头为‘#‘的行是注释行。文件开头部分的‘=‘赋值语句定义了一些参数或命令的缩写。在引用定义的标识符时,需在前面加上$符号并用括号括住标识符。前一行最后的‘\‘符号表示下一行是续行。all 表示创建Makefile 所知的最顶层的目标。dep: 该目标或规则用于各文件之间的依赖关系。创建的这些依赖关系是为了给make 用来确定是否需要要 重建一个目标对象的。
简单的makefile 文件含有一些规则,这些规则具有如下的形式:
目标(target)... : 先决条件(prerequisites)...
命令(command)
...
...
其中‘目标‘对象通常是程序生成的一个文件的名称;例如是一个可执行文件或目标文件。目标也可以是所要采取活动的名字,比如‘清除‘(‘clean‘)。‘先决条件‘是一个或多个文件名,是用作产生目标的输入条件。通常一个目标依赖几个文件。而‘命令‘是make 需要执行的操作。一个规则可以有多个命令,每一个命令自成一行。请注意,你需要在每个命令行之前键入一个制表符。自动变量的值是基于目标对象及其先决条件而在命令执行前设置的。例如,’$^’的值表示规则的所有先决条件,包括它们所处目录的名称;’$<’的值表示规则中的第一个先决条件;’$@’表示目标对象
.c.s: # make 老式的隐式后缀规则。该行指示make 利用下面的命令将所有的 .c 文件编译生成.s 汇编程序。‘:‘表示下面是该规则的命令。
$*.s(或$@)# 是自动目标变量,$<代表第一个先决条件,这里即是符合条件 *.c 的文件。
(cd kernel/math; make)计入子目录执行make命令
内核的编译过程:对boot/中的bootsect.s、setup.s 使用8086 汇编器进行编译,分别生成各自的执行模块。再对源代码中的其它所有程序使用GNU 的编译器gcc/gas 进行编译,并连接成模块system。再用build 工具将这三块组合成一个内核映象文件image.
as86 和ld86 是由Bruce Evans 编写的Intel 8086 汇编编译程序和连接程序。它完全是一个8086的汇编编译器,但却可以为386 处理器编制32 位的代码。Linux 使用它仅仅是为了创建16 位的启动扇区(bootsector)代码和setup 二进制执行代码。该编译器的语法与GNU 的汇编编译器的语法是不兼容的,但近似于Intel 的汇编语言语法(如操作数的次序相反等)。
Linux 操作系统启动部分的主要执行流程:
PC 的电源打开后,80x86 结构的CPU 将自动进入实模式,并从地址0xFFFF0 开始自动执行程序代码,这个地址通常是ROM-BIOS 中的地址。PC 机的BIOS 将执行某些系统的检测,并在物理地址0 处开始初始化中断向量。此后,它将可启动设备的第一个扇区(磁盘引导扇区,512 字节)读入内存绝对地址0x7C00 处,并跳转到这个地方。启动设备
通常是软驱或是硬盘
Linux 的最最前面部分是用8086 汇编语言编写的(boot/bootsect.s),它将由BIOS 读入到内存绝对地址0x7C00(31KB)处,当它被执行时就会把自己移到绝对地址90000(576KB)处,并把启动设备中后2kB 字节代码(boot/setup.s)读入到内存0x90200 处,而内核的其它部分(system 模块)则被读入到从地址0x10000 开始处,因为当时system 模块的长度不会超过0x80000 字节大小(即512KB),所以它不会覆盖在0x90000 处开始的bootsect 和setup 模块。随后将system 模块移动到内存起始处,这样system模块中代码的地址也即等于实际的物理地址。便于对内核代码和数据的操作。然后将整个系统从地址0x10000 移至0x0000 处,进入保护模式并跳转至系统的余下部分(在0x0000 处)。
此时所有32 位运行方式的设置启动被完成: IDT、GDT 以及LDT 被加载,处理器和协处理器也已确认,分页工作也设置好了;最终调用init/main.c 中的main()程序。上述操作的源代码是在boot/head.S 中的。
(42)
linux0.11学习笔记(2)