此篇文章属于文章 Floppinux - An Embedded 🐧Linux on a Single 💾Floppy 的中文版。
本文全程在Ubuntu20.04 64bit
上操作
在这篇文章中,你将:
- 将Linux 的系统裁减到用一张软盘便可以启动
作用:
- 获得一个<1.44MB的Linux软盘
装B的资本
现在开始。
准备工作
你需要以下软件包
git(Ubuntu自带) flex bison libncurses-dev qemu-system-x86 syslinux
安装
sudo apt install git flex bison libncurses-dev qemu-system-x86 syslinux
创建项目文件夹
mkdir linux
cd linux
建造Linux内核
下载Linux Kernel
源码:
git clone --depth=1 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
创建Linux Kernel
的最小配置:
make ARCH=x86 tinyconfig
添加额外配置:
make ARCH=x86 menuconfig
在菜单中选择以下项目:
Processor type and features > Processor family > 486
Device Drivers > Character devices > Enable TTY
General Setup > Configure standard kernel features (expert users) > Enable support for printk
General Setup > Initial RAM filesystem and RAM disk (initramfs/initrd)
- 将此项中除了
Support initial ramdisk/ramfs compressed using xz
外的项目取消勾选
- 将此项中除了
Executable file formats > Kernel support for ELF binaries
Executable file formats > Kernel support for scripts starting with #!
建造内核
make ARCH=x86 bzImage -j $(CPUCORE)
$(CPUCORE)
处为你CPU的核心数
OK,你获得了一个文件bzImage
,将它放到工作目录下
cp arch/x86/boot/bzImage ./
检查你的内核是否为32bit
$ file bzImage
bzImage: Linux kernel x86 boot executable bzImage, version 5.13.0-rc3+ (me@meOnUbuntu) #1 Sun Aug 22 16:12:54 CST 2021, RO-rootFS, Normal VGA
建造工具
如果没有工具,Linux内核只会启动,然后什么也做不了……
下载并解压Musl
wget https://musl.cc/i486-linux-musl-cross.tgz
tar xvf i486-linux-musl-cross.tgz
BusyBox
wget https://busybox.net/downloads/busybox-1.33.1.tar.bz2
tar xjvf busybox-1.33.1.tar.bz2
mv busybox-1.33.1 busybox
cd busybox
安装:
make ARCH=x86 allnoconfig
make ARCH=x86 menuconfig
菜单中选择你要的工具,后面会有文件大小,请合理选择:
以下是官方选择:
- Settings > Build static binary (no shared libs)
- Settings > Support files > 2GB
- Coreutils > cat, du, echo, ls, sleep, uname
- Console Utilities > clear
- Editors > vi
- Init Utilities > poweroff, reboot, init, Support reading an inittab file
- Linux System Utilities > mount, umount
- Miscellaneous Utilities > less
- Shells > ash, Optimize for size instead of speed, Alias support, Help support
保存,然后执行命令:
sed -i "s|.*CONFIG_CROSS_COMPILER_PREFIX.*|CONFIG_CROSS_COMPILER_PREFIX="\"~/linux/linux/"i486-linux-musl-cross/bin/i486-linux-musl-\"|" .config
sed -i "s|.*CONFIG_SYSROOT.*|CONFIG_SYSROOT=\""~/linux/linux/"i486-linux-musl-cross\"|" .config
sed -i "s|.*CONFIG_EXTRA_CFLAGS.*|CONFIG_EXTRA_CFLAGS=-I~linux/linux/i486-linux-musl-cross/include|" .config
sed -i "s|.*CONFIG_EXTRA_LDFLAGS.*|CONFIG_EXTRA_LDFLAGS=-L~/linux/linux/i486-linux-musl-cross/lib|" .config
构建BusyBox:
make ARCH=x86 -j ${CPUCORE}
make ARCH=x86 install
检查BusyBox是否为32bit:
$ file filesystem/bin/busybox
filesystem/bin/busybox: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
移动到filesystem
:
mv _install ../filesystem
构建文件系统
有了内核与工具,我们还需要一些额外的结构.
cd ../filesystem
mkdir -pv {dev,proc,etc/init.d,sys,tmp}
sudo mknod dev/console c 5 1
sudo mknod dev/null c 1 3
现在创造一些文件:
欢迎文件
vim welcome
编辑welcome
文件,文件内容将在开机时出现
官方用的是
cat >> welcome << EOF
但我觉得太麻烦了[笑]
处理启动、退出和重启的文件
vim ./etc/inittab
写入:
::sysinit:/etc/init.d/rc
::askfirst:/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
初始化脚本
vim ./etc/init.d/rc
写入:
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
clear
cat welcome
/bin/sh
使 init
文件可执行及使文件所有者为root
chmod +x etc/init.d/rc
sudo chown -R root:root .
注意: 第二条命令末尾有一个英文句号 “.“
将目录压缩至单个文件
find . | cpio -H newc -o | xz --check=crc32 > ../rootfs.cpio.xz
你可以在工作目录使用QEMU
测试你的工作:
cd ..
qemu-system-i386 -kernel bzImage -initrd rootfs.cpio.xz
制作启动映像
创建引导文件
vim syslinux.cfg
写入:
DEFAULT linux
LABEL linux
SAY [ BOOTING FLOPPINUX VERSION 0.1.0 ]
KERNEL bzImage
APPEND initrd=rootfs.cpio.xz
chmod +x syslinux.cfg
创建空镜像文件:
dd if=/dev/zero of=floppinux.img bs=1k count=1440
mkdosfs floppinux.img
syslinux --install floppinux.img
挂载它并将引导文件、内核与文件系统复制进去:
sudo mount -o loop floppinux.img /mnt
sudo cp bzImage /mnt
sudo cp rootfs.cpio.gz /mnt
sudo cp syslinux.cfg /mnt
sudo umount /mnt
结束!
你得到了一个Linux镜像文件!
你可以用 QEMU
运行它:
qemu-system-i386 -fda floppinux.img
运行截图
这是我最后得到的(文件大小: 1.41MB):