从源码构建linux 2.6.10系统环境

最近想要重新看一遍ldd3,以前看的时候总是照着新版的内核写代码,结果很多接口都发生了变化,在这个问题上浪费了不少时间,以至于最后看不下去了。所以这次打算使用upstream的linux 2.6.10来做实验,一方面upstream的内核没有受到第三方patch的污染,另一方面可以把关注点放在内核的接口设计以及驱动框架本身。所以就花了一些时间把linux 2.6.10的系统环境搭建了出来,这里记录一下搭建过程。

Build kernel

由于linux 2.6.10是一个相当古老的内核版本,她是2004年release的,想要在2020年的系统中直接编译她是很难的,我们需要找一个与她release时间接近的发行版,这里我选择了ubuntu 5.04的Docker container,关于如何制作这样的Docker image,可以参考这篇文章:将rootfs转换成Dcoker image

安装依赖包

1
sudo apt-get install build-essential libncurses-dev gcc make libc6-dev

配置kernel

由于我需要使用nfs挂载rootfs,所以需要需要保证kernel启动时能够正常配置网络。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
make defconfig
make menuconfig

# 配置网卡驱动,qemu使用的网卡通常为E1000
Intel(R) PRO/1000 Gigabit Ethernet support (E1000)
Location:
-> Device Drivers
-> Networking support
-> Network device support (NETDEVICES)
-> Ethernet (1000 Mbit)
# 配置IP PNP,NFS ROOT依赖此选项
IP: kernel level autoconfiguration (IP_PNP)
IP: DHCP support (IP_PNP_DHCP)
IP: BOOTP support (IP_PNP_BOOTP)
IP: RARP support (IP_PNP_RARP)
Location:
-> Device Drivers
-> Networking support
-> Networking support (NET)
-> Networking options
-> TCP/IP networking (INET)
# 配置NFS ROOT
Root file system on NFS (ROOT_NFS)
Location:
-> File systems
-> Network File Systems

编译kernel

1
make -j8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  SYSMAP  System.map
SYSMAP .tmp_System.map
Building modules, stage 2.
MODPOST
AS arch/x86_64/boot/setup.o
OBJCOPY arch/x86_64/boot/compressed/vmlinux.bin
LD arch/x86_64/boot/setup
GZIP arch/x86_64/boot/compressed/vmlinux.bin.gz
LD arch/x86_64/boot/compressed/piggy.o
LD arch/x86_64/boot/compressed/vmlinux
OBJCOPY arch/x86_64/boot/vmlinux.bin
BUILD arch/x86_64/boot/bzImage
Root device is (0, 60)
Boot sector 512 bytes.
Setup is 2444 bytes.
System is 2141 kB
Kernel: arch/x86_64/boot/bzImage is ready

Build rootfs

构建rootfs的方式有很多种,比如busybox,buildroot,yocto等。由于本次的重点在于kernel,所以我们选择buildroot来快速构建一个rootfs。

版本选择

虽然kernel的系统调用接口是非常稳定的,但由于linux 2.6.10太老了,使用新版本的toolchain编译出的binary在她上执行可能会报“kernel too old”的错误,所以我们并不能直接使用最新的buildroot,经过实验,buildroot-2014.11是一个能够使用的版本。

配置Buildroot

Buildroot自带一些config模板,因为我们使用的是qemu-x86-64的平台,因此只要执行以下命令

1
make qemu_x86_64_defconfig

因为我们并不需要Buildroot来编译内核,也不需要生成文件系统镜像,所以要基于此配置做一些修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
make menuconfig

# 取消kernel编译
Symbol: BR2_LINUX_KERNEL [=n]
Type : boolean
Prompt: Linux Kernel
Location:
-> Kernel
# 只打包tar包
Symbol: BR2_TARGET_ROOTFS_TAR [=y]
Type : boolean
Prompt: tar the root filesystem
Location:
-> Filesystem images
# 配置console
Symbol: BR2_TARGET_GENERIC_GETTY_PORT [=console]
Type : string
Prompt: TTY port
Location:
-> System configuration
-> Run a getty (login prompt) after boot (BR2_TARGET_GENERIC_GETTY [=y])
-> getty options

编译Buildroot

1
make -j8

最后即可生成rootfs的tar包

1
output/images/rootfs.tar

NFS boot

这里并不会直接使用命令行来启动qemu,而是使用virt-manager,ubuntu使用以下命令来安装

1
sudo apt install virt-manager

NFS exports参数

1
/exports/rootfs *(rw,no_root_squash,no_all_squash)

使用的cmdline如下

1
root=/dev/nfs nfsroot=192.168.1.1:/exports/rootfs,nfsvers=3 rw ip=dhcp console=ttyS0