最近想要重新看一遍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 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
最后即可生成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