linux内核有数千个编译配置选项,以致于管理这些配置项都需要写个程序来管理了.
管理配置项的程序有好几个, make menuconfig
就是其中一个.
他们最终的目的就是生成一个.config文件.
在我的电脑上,执行 make menuconfig
后,什么选项都不更改,直接退出,就得到了这样一个.config文件.
Download .config
把这个.config文件copy到linux源码目录,执行 make
命令,然后等上好一段时间,编译就完成了.
cp .config /path/to/linux-2.6.39/
cd /path/to/linux-2.6.39
make
文件名 | 大小 | 怎么来的 |
---|---|---|
vmlinux | 141438505 |
gcc编译,只不过用了自己的链接脚本 arch/x86/kernel/vmlinux.lds.S 这是一个标准的ELF文件, readelf -h -S vmlinux 可以查看ELF Header及Section Headers
|
System.map | 这个文件的大小我们不关心 |
这个文件非常有用,它记录着函数,变量的内存地址readelf -s vmlinux 也可以拿到vmlinux的symbol table不过这个System.map是由 scripts/mksysmap 这个脚本生成的.
|
arch/x86/boot/compressed/vmlinux.bin | 18545760 |
objcopy -R .comment -S vmlinux arch/x86/boot/compressed/vmlinux.bin @see arch/x86/boot/compressed/.vmlinux.bin.cmd |
arch/x86/boot/compressed/vmlinux.bin.gz | 4559912 |
cat vmlinux.bin | gzip -f -9 > vmlinux.bin.gz @see arch/x86/boot/compressed/.vmlinux.bin.gz.cmd |
arch/x86/boot/compressed/piggy.S | 这个文件的大小我们不关心 |
mkpiggy vmlinux.bin.gz 前边生成的vmlinux.bin.gz被include到了这个文件里
|
arch/x86/boot/compressed/vmlinux | 6681360 |
ld -m elf_x86_64 -T vmlinux.lds head_64.o misc.o string.o cmdline.o early_serial_console.o piggy.o -o vmlinux @see arch/x86/boot/compressed/.vmlinux.cmd |
arch/x86/boot/vmlinux.bin | 4579584 |
objcopy -O binary -R .note -R .comment -S compressed/vmlinux vmlinux.bin @see arch/x86/boot/.vmlinux.bin.cmd |
arch/x86/boot/setup.bin | 16620 |
objcopy setup.elf 而来, 这个文件我们不太关心 @see arch/x86/boot/.setup.elf.cmd @see arch/x86/boot/.setup.bin.cmd |
arch/x86/boot/bzImage | 4596496 |
tools/build setup.bin vmlinux.bin CURRENT > bzImage @see arch/x86/boot/.bzImage.cmd |
build.c 的作用是把 setup.bin 和 vmlinux.bin 合成一个 bzImage.
合成前,需要计算出几个值,覆盖掉 setup.bin 里的默认值.
setup.bin的前两个sector(共1K)的内容是由 header.S 生成的, 链接脚本是 setup.ld
自己写过bootloader的话能很容易看明白 header.S 这段程序.
stat /
取得. 由于我们的.config 里配置了CONFIG_BLK_DEV_INITRD=y
也就是说系统启动需要一个initrd image, 而GRUB加载initrd的话,会把ROOT Device Number重设为一个固定值,所以这个值在这里就无所谓了SECTIONS
{
. = 0;
.bstext : { *(.bstext) }
.bsdata : { *(.bsdata) }
. = 497;
.header : { *(.header) }
对应 header.S
.section ".header", "a"
.globl hdr
hdr:
setup_sects: .byte 0 /* Filled in by build.c */ # offset 497 (0x1f1)
root_flags: .word ROOT_RDONLY # offset 498,499 (0x1f2, 0x1f3)
syssize: .long 0 /* Filled in by build.c */ # offset 500,501,502,503 (0x1f4, 0x1f5, 0x1f6, 0x1f7)
ram_size: .word 0 /* Obsolete */ # offset 504, 505
vid_mode: .word SVGA_MODE # offset 506, 507
root_dev: .word 0 /* Filled in by build.c */ # offset 508, 509
boot_flag: .word 0xAA55
对应build.c
/* Set the default root device */
buf[508] = minor_root;
buf[509] = major_root;
/* Patch the setup code with the appropriate size parameters */
buf[0x1f1] = setup_sectors-1;
buf[0x1f4] = sys_size;
buf[0x1f5] = sys_size >> 8;
buf[0x1f6] = sys_size >> 16;
buf[0x1f7] = sys_size >> 24;
首先写入setup.bin,前边我们已经计算好了它要占几个sector,setup.bin不会恰好占满这多么sector,余下的字节以0填充.
写入vmlinux.bin,前边我们已经计算好了它要占多少个16字节,vmlinux.bin也不会恰好占满这多么个16字节,保留最后4个字节,其它字节以0填充.
计算setup.bin + padded zero + vmlinux.bin + padded zero 的CRC32检验值,结果写到最后,占4个字节.
OK, bzImage就这样生成了.
stat -c %D /
803
php build.php ../../linux-2.6.39/arch/x86/boot/setup.bin ../../linux-2.6.39/arch/x86/boot/vmlinux.bin 3 8
setup.bin padded zeros: 276
vmlinux.bin padded zeros: 12
./crc32 /tmp/bzImage.pad
bzImage.pad size = 4596492
crc32 bzImage.pad = 5fcb720e
# root_dev
hexdump -C -n 2 -s 508 /tmp/bzImage.pad
000001fc 03 08 |..|
# setup_sects
hexdump -C -n 1 -s 497 /tmp/bzImage.pad
000001f1 20 | |
# sys_size
hexdump -C -n 4 -s 500 /tmp/bzImage.pad
000001f4 11 5e 04 00 |.^..|
# setup.bin padded zeros
hexdump -C -n $((16+276+16)) -s $((16620-16)) /tmp/bzImage.pad
000040dc 2b 00 00 00 00 0f 50 00 19 00 00 00 55 aa 5a 5a |+.....P.....U.ZZ|
000040ec 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000041fc 00 00 00 00 fc f6 86 11 02 00 00 40 75 0c fa b8 |...........@u...|
0000420c 18 00 00 00 |....|
# vmlinux.bin padded zeros
hexdump -C -n 512 -s $(((16620+511)/512*512+4579584-16)) /tmp/bzImage.pad
004622f0 00 00 00 00 00 89 80 00 00 00 00 00 00 00 00 00 |................|
00462300 00 00 00 00 00 00 00 00 00 00 00 00 |............|
# root_dev
hexdump -C -n 2 -s 508 bzImage
000001fc 03 08 |..|
# setup_sects
hexdump -C -n 1 -s 497 bzImage
000001f1 20 | |
# sys_size
hexdump -C -n 4 -s 500 bzImage
000001f4 11 5e 04 00 |.^..|
# setup.bin padded zeros
hexdump -C -n $((16+276+16)) -s $((16620-16)) bzImage
000040dc 2b 00 00 00 00 0f 50 00 19 00 00 00 55 aa 5a 5a |+.....P.....U.ZZ|
000040ec 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000041fc 00 00 00 00 fc f6 86 11 02 00 00 40 75 0c fa b8 |...........@u...|
0000420c 18 00 00 00 |....|
# vmlinux.bin padded zeros
hexdump -C -n 512 -s $(((16620+511)/512*512+4579584-16)) bzImage
004622f0 00 00 00 00 00 89 80 00 00 00 00 00 00 00 00 00 |................|
00462300 00 00 00 00 00 00 00 00 00 00 00 00 0e 72 cb 5f |.............r._|