linux1.0内核代码学习(三) 之linu1.0内核运行
通过Makefile中的命令make zdisk可以制作从磁盘启动的linux1.0映像文件,由于linux1.0开发的时候当时的gun工具版本比较低,当时生成的可执行文件时a.out格式的,但现在的gun工具编译出来的可执行文件都是elf格式的,比如我的gcc版本是4.3.2的,而linux1.0的tools工具在生成可执行文件的过程中都是按照a.out格式来制作的,我曾经尝试用gcc编译a.out格式的文件,但没有成功,虽然文件名变成了a.out,但里面的格式仍然是elf格式;因此要正确启动linux1.0内核程序需要在制作zdisk的过程中对tools工具做修改;一个方法就是将生成的tools/zSystem和zBoot/zSystem文件用objcopy命令生成可执行二进制代码,然后再生成zImage映像,再通过make zdisk制作成从软盘启动的映像。Makefile文件修改如下:
#sync强制写入所有需要更新的 buffer 上的数据到硬盘上
#-R .note -R .comment 表示移掉 .note 与 .comment 段
#-O binary (或--out-target=binary) 输出为原始的二进制文件
zImage: $(CONFIGURE) boot/bootsect boot/setup zBoot/zSystem tools/build #
objcopy -O binary -R .note -R .comment zBoot/zSystem tools/kernel
tools/build boot/bootsect boot/setup tools/kernel $(ROOT_DEV) > zImage
rm tools/kernel -f
sync
zdisk: zImage
dd bs=8192 if=zImage of=/dev/fd0
zlilo: $(CONFIGURE) zImage
if [ -f /vmlinuz ]; then mv /vmlinuz /vmlinuz.old; fi
if [ -f /zSystem.map ]; then mv /zSystem.map /zSystem.old; fi
cat zImage > /vmlinuz
cp zSystem.map /
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
#表示tools/zSystem文件要由冒号右边所列的元素生成。紧接的是生成zSystem的命令。
#最后的> zSystem.map表示需要将zSystem经过处理后重定向到zSystem.map文件中。
tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs
$(LD) $(LDFLAGS) -e startup_32 -Ttext 100000 boot/head.o init/main.o tools/version.o \
$(ARCHIVES) \
$(FILESYSTEMS) \
$(DRIVERS) \
$(LIBS) \
-o tools/zSystem
nm tools/zSystem | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | \
sort > zSystem.map
mv tools/zSystem tools/tmpzSystem
objcopy -O binary -R .note -R .comment tools/tmpzSystem tools/zSystem
rm tools/tmpzSystem -f
可以看到linux1.0内核已经启动起来,打印出内核的版本号和编译日期等信息,但在切换到用户模式和fork调用的时候出现错误,不知道是不是没有加载文件系统还是其他内核问题,还需要进一步研究。