2024年5月31日发(作者:)

我详细解析了bootsect.s,同时阅读了setup.s。其中bootsect.s存放于

磁盘的主引导扇区,bios-startup程序加载该程序(bootsect.s)到内存0x700

处,并由此执行bootsect.s来引导Linux kernel。在bootsect.s中加载setup.s

至内存中,并在执行完它自身后,jump跳至刚刚已读入的setup部份,继续执

行。

Linux Kernel Image 生成过程:

一. 引导扇区汇编代码bootsect.s被预处理成bbootsect.s或bootsect.s

(无论有无D_BIG_KERNEL),当然这取决于编译目标是bzImage还是bImage。

bbootsect.s被汇编,然后被转化成合法的二进制文件,通过调用bbootsect.s。

(或者是bootsect.s被汇编,然后被转化成合法的二进制文件,通过调用

bootsect.s。)

二. 启动代码setup.s(include video.s)被预处理成bsetup.s(就bzImage

而言),或者是setup.s(就zImage而言)。和bootsect.s一样,不同的是bzImage

使用-D_BIG_KERNEL来标志。结果同样也将被转化成合法的二进制文件,通过调

用bsetup.s或setup.s。

三. 进入子目录 arch/i386/boot/compressed 把/usr/src/linux/vmlinux

转变成$(临时文件名,合法的二进制格式)。删除.note 和.comment

文件,在这个目录arch/ARM/boot/ compressed下的Makefile文件中TEXTADDR

(0xC0008000)表示内核起始运行的地址,在这个arch/ARM/boot/目录下

arch/i386/boot/下的Makefile中ZRELADDR(0x00008000)是将内核解压到目

标板上的地址,

四. gzip -9 <$tmppiggy> $。(gunzip()在main.c中被实现。

用于解压缩部份Linux内核,负责解压缩Linux内核的函数还有

decompressed())

五. 联接(Link)$ ,使其成为 ELF relocate(ld -r)文件

piggy.0。

六. 编译压缩程序 head.s 和 misc.c(仍然存在于子目录

arch/i386/boot/compressed中。)成ELF的目标文件head.o和misc.o。

七. 联接(Link)所有的目标文件head.o、misc.o、piggy.o成bvmlinux(或

者vmlinux,就zImage而言,注意:不要错误地把它认为是

/usr/src/linux/vmlinux !)。一定要注意到这两者之间的不同:-Ttext

0x1000(调用的是经过压缩的内核镜像vmlinux),-Ttext 0x100000(调用的是未

经过压缩的大内核镜像bvmlinux,还有bzImage compression loader 将被

high-loaded,调到内存高地址处)。

八.最后返回 arch/i386/boot 子目录,bvmlinux转化成合法的二进制文

件 ,删除 .note 和.comment部份。

九. 最后返回 arch/i386/boot 子目录,使用编程工具把

bbootsect+bsetup+compressed/ 编译成bzImage。(也可以使编

译成zImage)。

总结:

1.在/usr/src/linux/这个目录的Makefile文件中先把

『include arch/$(ARCH)/Makefile

vmlinux: include/linux/version.h init/main.o init/version.o

kernel drivers mm fs net ipc lib

$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o

--start-group

$(CORE_FILES)

$(DRIVERS)

$(NETWORKS)

$(LIBS)

--end-group

-o vmlinux