以time/gettimeofday系统调用为例分析ARM64 Linux 5.4.34
准备工作
安装编译工具链
由于Ubuntu是X86架构,为了编译arm64的文件,需要安装交叉编译工具链
sudo apt install gcc-aarch64-linux-gnu
sudo apt install libncurses5-dev build-essential git bison flex libssl-dev
制作根文件系统
linux的启动需要配合根文件系统,这里我们利用busybox来制作一个简单的根文件系统
编译busybox
类似 lab3
cd ~/linux_lab/lab4
wget https://busybox.net/downloads/busybox-1.33.1.tar.bz2
extract busybox-1.33.1.tar.bz2
cd busybox-1.33.1
打开静态库编译选项
make menuconfig
Settings --->
[*] Build static binary (no shared libs)
指定编译工具
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
编译
make
make install
编译完成,在busybox目录下生成_install目录
定制文件系统
为了init进程能正常启动, 需要再额外进行一些配置
根目录添加etc、dev和lib目录
cd _install
mkdir etc dev lib
结果如下
$ ls
bin dev etc lib linuxrc sbin usr
etc
在etc分别创建文件:profile、inittab、fstab、init.d/rcS
busybox
作为linuxrc
启动后, 会读取/etc/profile
, 这里面设置了一些环境变量和 shell 的属性- 根据
/etc/fstab
提供的挂载信息, 进行文件系统的挂载 busybox
会从/etc/inittab
中读取sysinit
并执行, 这里sysinit
指向了/etc/init.d/rcS
/etc/init.d/rcS
中 ,mdev -s
这条命令扫描/sys
目录,查找字符设备和块设备,并在/dev
下mknod
cd etc
code profile
#!/bin/sh
export HOSTNAME=imingz
export USER=root
export HOME=/home
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
code inittab
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
code fstab
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
kmod_mount /mnt 9p trans=virtio 0 0
mkdir -p init.d
code init.d/rcS
mkdir -p /sys
mkdir -p /tmp
mkdir -p /proc
mkdir -p /mnt
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
dev
console
: 将用户态的输出打印到串口上
sudo mknod console c 5 1
lib
拷贝lib库,支持动态编译的应用程序运行:
cp /usr/aarch64-linux-gnu/lib/*.so* -a .
编译内核
配置内核
linux内核源码可以用之前的。
根据 arch/arm64/configs/defconfig
文件生成 .config
cd ~/linux_lab/lab4/linux-5.4.34
make defconfig ARCH=arm64
将下面的配置加入.config文件下面
code .config
CONFIG_DEBUG_INFO=y
CONFIG_INITRAMFS_SOURCE="./root"
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_ROOT_GID=0
- CONFIG_DEBUG_INFO 是为了方便调试
- CONFIG_INITRAMFS_SOURCE 是指定 kernel ramdisk 的位置,这样指定之后 ramdisk 会直接被编译到 kernel 镜像中。
将之前制作好的根文件系统cp到root目录下
cp -r ../busybox-1.33.1/_install root
sudo mknod root/dev/console c 5 1
执行编译
指定 target
为 Image
增加编译速度, 这样会只编译 kernel, 不会编译 modules。
make ARCH