定制一个最小的linux 系统
定制一个最小的linux 系统
一个操作系统宏观上分为两个部分,kernel和shell(核和壳),kernel就是操作系统内核,shell在kernel之上,提供与用户交互的界面,包括CLI(命令行界面)和GUI(图形用户界面)。除此之外还有基础运行库(如c库、posix)等基础软件。只有kernel,不能算作一个操作系统,因为什么也做不了。本文通过linux内核和busybox工具集,制作一个最简单的linux系统。
环境准备
安装必要的软件包
sudo apt update
sudo apt upgrade
sudo apt install build-essential git kconfig-frontends flex bison libelf-dev bc libssl-dev qemu qemu-system-x86
开始
编译 linux-kernel
建议直接从https://www.kernel.org/ 下载 tar -xvJf linux-5.15.175.tar.xz
官方这个这个拉下来大概5g多
git clone https://github.com/torvalds/linux.git
#或者国内的镜像
git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux.git
git checkout
make ARCH=x86_64 defconfig
make menuconfig
make bzImage -j
如果卡死,可能是内存过小,可单线程编译
编译busybox
获取并编译busybox
git clone https://github.com/mirror/busybox.git
git checkout 1_36_stable
make menuconfig
启用静态链接:Busybox Settings -> Build Options -> Build BusyBox as a static binary (no shared libs)
。
make -j$(nproc)
make install
制作 initramfs
bin sbin usr dev etc init proc sys
cd busybox/_install
rm linuxrc
mkdir -p etc/init.d
# 下面这个如不复制,可以在init之前切换到用户态sysint时候创建
sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/
echo "::sysinit:/bin/sh" > etc/inittab
编辑 etc/init.d/init文件
#!/bin/busybox sh
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
# 检查是否为 PID 1
if [ "$$" -ne 1 ]; then
echo "Error: This script can only be run as the init process (PID 1)." >&2
exit 1
fi
[ -d /proc ] || mkdir -p /proc
[ -d /dev ] || mkdir -p /dev
[ -d /sys ] || mkdir -p /sys
[ -d /tmp ] || mkdir -p /tmp
[ -d /var/run ] || mkdir -p /var/run
[ -d /root ] || mkdir -p /root
# 限制文件执行、SUID 和设备文件的创建权限。
mount -t proc proc /proc
mount -t sysfs -o noexec,nosuid,nodev sysfs /sys
# 用 /sbin/init代替当前进程,将 /sbin/init 的输入、输出和错误流全部重定向到 /dev/console
exec /sbin/init < /dev/console > /dev/console 2>&1
编辑etc/inittab文件
::sysinit:/etc/init.d/sysinit
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/poweroff
::restart:/sbin/init
tty1::respawn:/bin/sh
tty2::respawn:/bin/sh
ttyS0::respawn:/bin/sh
# 可选,可配置用户权限
tty1::respawn:/sbin/getty 115200 tty1
tty2::respawn:/sbin/getty 115200 tty2
ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100
编辑 etc/init.d/sysinit
#!/bin/sh
echo "Tiny linux Starting sysinit..."
# 创建必要的设备节点
create_device_nodes() {
echo "Creating essential device nodes..."
mknod -m 666 /dev/null c 1 3
mknod -m 600 /dev/console c 5 1
mknod -m 666 /dev/tty c 5 0
for i in 0 1 2; do
mknod -m 620 /dev/tty$i c 4 $i
done
mknod -m 620 /dev/ttyS0 c 4 64
}
# 挂载必要的文件系统
mount_filesystems() {
echo "Mounting virtual filesystems..."
mount -t devtmpfs devtmpfs /dev
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devpts devpts /dev/pts
mount -t tmpfs tmpfs /dev/shm
}
# 配置 mdev
setup_mdev() {
echo "Setting up mdev..."
mdev -s
}
# 创建标准流链接
create_standard_links() {
echo "Creating standard stream links..."
ln -snf /proc/self/fd /dev/fd
ln -snf fd/0 /dev/stdin
ln -snf fd/1 /dev/stdout
ln -snf fd/2 /dev/stderr
[ -e /proc/kcore ] && ln -snf /proc/kcore /dev/core
}
# 加载内核参数
load_sysctl() {
if [ -e /etc/sysctl.conf ]; then
echo "Loading sysctl settings..."
sysctl -p /etc/sysctl.conf
fi
}
# 启动 acpid 服务, 管理电源按钮、睡眠等 ACPI 相关事件。
start_acpid() {
if [ -e /proc/acpi ]; then
echo "Starting acpid..."
acpid &>/dev/null
fi
}
# 执行所有初始化步骤
main() {
create_device_nodes
mount_filesystems
setup_mdev
create_standard_links
load_sysctl
start_acpid
echo "Sysinit completed."
}
main
可选,配置用户权限,设置用户账号密码
#!/bin/sh
# 创建 /etc/passwd 文件
echo "root:x:0:0:root:/root:/bin/sh" > etc/passwd
# 替换yourpassword为自己的密码, 使用 openssl 生成加密密码
echo "root:$(openssl passwd -6 root):0:0:99999:7:::" > etc/shadow
# sudo bash -c 'echo "root:$(openssl passwd -6 root):0:0:99999:7:::" > etc/shadow'
# 设置权限
chmod 644 etc/passwd && chmod 600 etc/shadow
最后的一些权限准备
sudo chmod +x etc/init.d/init
sudo chmod +x etc/init.d/sysinit
cd ..
sudo chown -R root:root _install/
生成最终需要的 initramfs.cpio.gz
find . | cpio -o --format=newc | gzip > ../initramfs.cpio.gz
准备磁盘和grub
# 创建虚拟磁盘
dd if=/dev/zero of=tiny-linux.img bs=1M count=32
# 创建分区表和分区
sudo losetup -Pf --show tiny-linux.img
fdisk /dev/loopX
n p w
sync
# 格式化分区
sudo mkfs.ext4 /dev/loopXp1
# 挂载
mkdir -p tmpimg
sudo mount /dev/loopXp1 tmpimg/
# 拷贝内核文件和 initramfs
sudo cp linux-5.15.175/arch/x86_64/boot/bzImage tmpimg/
sudo cp busybox/initramfs.cpio.gz tmpimg/
# 安装grub
sudo grub-install --boot-directory=tmpimg/boot/ --target=i386-pc --modules=part_msdos tiny-linux.img
编辑grub2 配置 tmpimg/boot/grub/grub.cfg
set default=0
set timeout=5
menuentry 'CA Tiny Linux' {
linux /bzImage console=tty0 console=ttyS0,115200
initrd /initramfs.cpio.gz
}
运行
qemu-system-x86_64 -hda tiny-linux.img -nographic
-nographic 没有图形界面时候使用,可以在终端显示
# 如果希望在vmware中运行,可以转换磁盘格式,添加到虚拟磁盘
qemu-img convert -f raw -O vmdk tiny-linux.img tiny-linux.img.vmdk
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix