关于Linux-0.00 的编译和运行可以参考我的博文:http://blog.csdn.net/longintchar/article/details/78757065
为了能在64位的Ubuntu环境下编译,修改后的Makefile是
# Makefile for the simple example kernel.
AS86 =as86 -0 -a
LD86 =ld86 -0
AS =as --32
LD =ld
LDFLAGS =-m elf_i386 -Ttext 0 -e startup_32 -s -x -M
all: Image
Image: boot system
dd bs=32 if=boot of=Image skip=1
objcopy -O binary system head
cat head >> Image
disk: Image
dd bs=8192 if=Image of=/dev/fd0
sync;sync;sync
head.o: head.s
system: head.o
$(LD) $(LDFLAGS) head.o -o system > System.map
boot: boot.s
$(AS86) -o boot.o boot.s
$(LD86) -s -o boot boot.o
clean:
rm -f Image System.map core boot head *.o system
对于boot.s文件,我们用的是as86
汇编器和ld86
链接器。
as86:
-0 :生成8086目标程序;
-a :生成与gas和gld部分兼容的代码;
ld86:
-0:产生具有16bit魔数的头结构;
boot.s–>boot.o–>boot
用命令file boot
可以查看boot的文件类型是
Linux-8086 impure executable
需要注意的是:boot的大小是544B,包含一个32B的文件头,所以需要把这个头去掉。
dd bs=32 if=boot of=Image skip=1
这个命令表示跳过boot的前32字节,把其余部分写入文件Image;
这时候Image的大小是512字节,用file
命令查看的结果是 x86 boot sector
;
对于head.s文件,我们用的是GNU的as
汇编器和ld
链接器。
as –32表示生成32位的代码;
ld:
-m elf_i386:指定仿真模式是elf_i386
;
-Ttext 0:指定.text
的段地址为0;
-e startup_32:指定入口函数是startup_32
;
-s:删除符号信息;
-x:丢弃局部符号;
-M:在标准输出上打印链接图文件;
head.o: head.s
用的是隐含规则,即
as -o head.o head.s
用file
查看head.o,得到
ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
链接后得到system,用file
查看得到
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
objcopy -O binary system head
以上命令表示把elf格式的system转换成二进制文件head,用file查看head,得到
COM executable for DOS
cat head >> Image
表示把head追加到Image的后面。Image就是最终的镜像文件。