前言
- 这里我们在《“多快好省”——交叉编译构建自己的linux操作系统》的基础上,使用busybox来构建initrd,在基于XFS文件系统的SATA硬盘上构建带有initrd的linux操作系统
设置编译环境
set +h
umask 022
export LJOS=~/lj-os
export LC_ALL=POSIX
export PATH=${LJOS}/cross-tools/bin:/bin:/usr/bin
unset CFLAGS
unset CXXFLAGS
export LJOS_HOST=$(echo ${MACHTYPE} | sed "s/-[^-]*/-cross/")
export LJOS_TARGET=x86_64-unknown-linux-gnu
export LJOS_CPU=k8
export LJOS_ARCH=$(echo ${LJOS_TARGET} | sed -e 's/-.*//' -e 's/i.86/i386/')
export LJOS_ENDIAN=little
export CC="${LJOS_TARGET}-gcc"
export CXX="${LJOS_TARGET}-g++"
export CPP="${LJOS_TARGET}-gcc -E"
export AR="${LJOS_TARGET}-ar"
export AS="${LJOS_TARGET}-as"
export LD="${LJOS_TARGET}-ld"
export RANLIB="${LJOS_TARGET}-ranlib"
export READELF="${LJOS_TARGET}-readelf"
export STRIP="${LJOS_TARGET}-strip"
静态编译busybox
- 这里为了方便我配置busybox为静态编译Busybox(Settings --> Build Options --> Build BusyBox as a static binary (no shared libs)
make CROSS_COMPILE="${LJOS_TARGET}-" menuconfig
make CROSS_COMPILE="${LJOS_TARGET}-"
make CROSS_COMPILE="${LJOS_TARGET}-" install

以ko的形式编译xfs驱动
make ARCH=${LJOS_ARCH} CROSS_COMPILE=${LJOS_TARGET}- menuconfig

make ARCH=${LJOS_ARCH} CROSS_COMPILE=${LJOS_TARGET}-
构建initramfs

mkdir initramfs
cp -R busybox-1.28.3/_install/* initramfs/
cd initramfs
mkdir dev etc lib mnt proc sys
cp -R ../busybox-1.28.3/examples/bootfloppy/etc/* etc/
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
::sysinit:/etc/init.d/rcS
console::respawn:-/bin/sh
proc /proc proc defaults 0 0
mknod dev/console c 5 1
mknod dev/null c 1 3
- 重新创建init脚本
echo "exec initramfs init"
echo "mounting proc and sys"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
insmod /lib/modules/4.16.3/kernel/lib/libcrc32c.ko
insmod /lib/modules/4.16.3/kernel/fs/xfs/xfs.ko
echo "detect and export hardware info"
mdev -s
echo "Mount real rootfs to /mnt/sysroot..."
mkdir /mnt/sysroot
mount -t xfs /dev/sda2 /mnt/sysroot
echo "Switch to read rootfs..."
exec switch_root /mnt/sysroot /linuxrc
mkdir -p lib/modules/4.16.3/kernel/fs/xfs/
cp /root/ljos_tar/linux-4.16.3/fs/xfs/xfs.ko lib/modules/4.16.3/kernel/fs/xfs/
find . |cpio -o -H newc | gzip > ../initrd.img
给SATA硬盘分区
- 分两个区,并格式化成xfs文件系统,挂载到编译机上(/root/sda1和/root/sda2)
|/dev/sdb
|---------/dev/sdb1(用于/boot)
|---------/dev/sdb2(用于/)
grub2-install --root-directory=/root/sda2 /dev/sdb
配置bootloarder
[[email protected] sda2]
set pager=1
if [ -s $prefix/grubenv ]; then
load_env
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="${saved_entry}"
fi
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
fi
}
function load_video {
if [ x$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
}
if [ x$feature_timeout_style = xy ] ; then
set timeout_style=menu
set timeout=5
else
set timeout=5
fi
set tuned_params=""
if [ -f ${prefix}/user.cfg ]; then
source ${prefix}/user.cfg
if [ -n ${GRUB2_PASSWORD} ]; then
set superusers="root"
export superusers
password_pbkdf2 root ${GRUB2_PASSWORD}
fi
fi
menuentry 'OS1.0a' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
linux /vmlinuz-4.16.3 root=/dev/sda2 ro
initrd /initrd.img
}
- 把制作好的initrd.img放入/root/sda2/boot(即boot分区下)
启动目标机硬盘

- 正常启动,且加载了xfs驱动