news 2026/5/1 20:07:08

制作最简根文件系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
制作最简根文件系统

author: hjjdebug
date: 2026年 04月 29日 星期三 17:39:34 CST
descrip: 制作最简根文件系统


根文件系统是linux内核启动完成后,要挂载的第一个文件系统,
内核必需要从该文件系统中找到一个启动文件, 例如tty-shell,
然后把执行权就交给该shell

文章目录

  • 1. 什么是根文件系统?
  • 2. 创建一个最小可用 Linux 根文件系统(rootfs)
    • 2.1 创建符合linux规范的目录及文件集合.
    • 2.2 把linux 根目录打包成.cpio.gz文件, 这就是initramfs 文件
  • 3. 步骤2的所有操作可以用一个脚本来完成.
  • 4. 用途
    • 4.1 qemu 启动脚本
    • 4.2 qemu 调试

1. 什么是根文件系统?

根,就是最顶层的意思.最基础的意思.
文件系统,就是多个文件构成系统.
所谓mount文件系统,安装文件系统,就是找到根目录位置,有时候我们把根叫"/"
目录的分割也是用"/"来分割.

根文件系统构成 = 目录结构 + 基础工具 + 启动脚本 + 必要库文件
根文件系统制作过程.

  1. 建标准目录树
  2. 放基础命令(busybox 最常用)
  3. 放动态库 (busybox 编译成静态就可以不用动态库了)
  4. init 启动脚本
  5. 打包成镜像(cpio 或 ext4)
    制作cpio 文件是为了制作内存镜像文件.
    所谓内存镜像文件,就是文件系统存在于内存中, 而不是存放在磁盘上.

典型目录结构都在根下:如下示例
/bin、/sbin:基础命令
/etc:系统配置
/lib:动态库
/dev:设备文件
/usr、/var 等
这些都是根目录下的子目录.也是linux-base目录结构
各个目录下有相关的文件.

2. 创建一个最小可用 Linux 根文件系统(rootfs)

我们用busybox 创建一个根文件系统.
busybox 是一个命令的集合.
假定你已经有了一个静态的busybox, 位置/bin/busybox
动态busybox可能由于动态库的问题(找不到,或者版本)而跑不起来.所以别用.

2.1 创建符合linux规范的目录及文件集合.

创建 bin dev etc proc sys host目录, host 目录是一个文件系统挂载点
创建 init 脚本, 内核启动完就会首先执行这个init 脚本, 其mount -a 会读取fstab 文件
创建 etc/fstab 文件, 这是init脚本执行时的配置文件,会自动挂载文件系统,省得你手工挂载
创建 profile 文件, 这是login shell 的登录执行初始化文件,你可以把一些初始化操作放到这里
把busybox copy 到bin 目录, 并在bin 目录下建立若干软链接

2.2 把linux 根目录打包成.cpio.gz文件, 这就是initramfs 文件

用内存盘根文件系统很方便

3. 步骤2的所有操作可以用一个脚本来完成.

脚本中还有一些细节注释.

$ cat build_initramfs.sh #!/bin/bash # 配置项 BUSYBOX="/bin/busybox"# 改成你自己的静态 busybox 路径,要静态的,否则不能运行 OUTPUT="initramfs.cpio.gz"WORKDIR="./initramfs.tmp"# 清理 rm-rf"$WORKDIR""$OUTPUT"mkdir-p"$WORKDIR"cd"$WORKDIR"||exit1#1.创建目录结构 mkdir-p bin dev etc proc sys host #2.创建 etc/fstab(mount-a 调用,9P 自动挂载) cat>etc/fstab<<EOFdevtmpfs/dev devtmpfs defaults00proc/proc proc defaults00sysfs/sys sysfs defaults00host_share/host9p trans=virtio,version=9p2000.L00EOF#3.创建 profile,login shell 调用 cat>etc/profile<<EOFalias ls='ls --color'EOF#4.生成 init 脚本,内核默认调用该用户态文件 cat>init<<'EOF'#!/bin/sh # 按 fstab 自动挂载 mount-a#setsid,cttyhack 是为了消除一个Can't access tty;job control turned off的警告#-l 会启用login shell,从而执行profile文件 exec/bin/setsid/bin/cttyhack/bin/sh-lEOFchmod+x init #5.放入 busybox cp"$BUSYBOX"bin/chmod+x bin/busybox # 建立软链接 cd bin||exit1forcmd in sh setsid cttyhack mount modprobe ls cat mkdir dmesg insmod rmmod;doln-s busybox"$cmd"done cd..#6.打包 cpio+gzip find.|cpio-o-H newc|gzip-9>../"$OUTPUT"# 完成 cd..rm-rf"$WORKDIR"echo"✅ 生成成功:$OUTPUT"

4. 用途

用qemu 启动内核并运行到根文件系统的shell.

4.1 qemu 启动脚本

$ cat qemu-run.sh
qemu-system-x86_64
-m 2G -smp 2
-enable-kvm -cpu host
-kernel arch/x86/boot/bzImage
-initrd ~/test/rootfs/initramfs.cpio.gz
-append “root=/dev/ram0 console=ttyS0 nokaslr”
-virtfs local,path=/mnt/share,mount_tag=host_share,security_model=passthrough,id=hostshare
-nographic

参数解释:
-m 内存大小
-smp 核心数 (symmetric_multi_processing)
-enable-kvm 就会直接用你电脑 CPU 的硬件虚拟化能力,速度直接提升 10~100 倍
-cpu host 把宿主机的 CPU 型号、特性 1:1 暴露给虚拟机,i7、i9、AMD 等, 所有指令集全部开放,
否则就模拟一个假的、老旧的 CPU(兼容性好但性能差)
-kernel 内核 QEMU 可以直接加载Linux 内核镜像, 可以不用从硬盘启动,用bootloader加载等
-initrd 根文件 初始ram文件系统,临时根文件系统,就是我们上面制作的文件,内核挂靠的系统
-append 启动内核时传递给内核的参数,
root=/dev/ram0, 告诉内核根文件系统在内存
console=ttyS0, 控制台输出重定向到ttyS0, 向串行口打印. 配合-nographic 参数,将打印到宿主机的终端
nokaslr, no kernel address space layout randomization, 内核地址不要随机化,要固定, 调试内核程序保持地址固定需要它.
-virtfs 虚拟文件系统,宿主机和虚拟机通过虚拟文件系统实现文件共享,具体实现:
local, 共享本地目录
path=/mnt/share, 共享的本地路径名称
mount_tag=hostshare, 宿主机和虚拟机的共享标签,沟通的桥梁.
security_model=passthrough, 宿主机的文件属性全部pass给虚拟机
id=hostshare, 这是给qemu看的一个设备名称, 可以把这种共享功能标记为一个虚拟共享卡,卡的名字叫hostshare
其实,宿主机不使用这个id,但qemu会用它, 你还可以创建第二个共享卡(如果愿意),起不同名称就行
所以这个id必需要写,因为qemu要管理这个设备,要在log中记录这个设备,要区分设备,所以要为每个设备配置ID,且没个设备ID都不同

-nographic 无窗口, 不出现窗口,需配合内核参数console=ttyS0, 才能由宿主机接受打印信息

把简易的linux 系统先启动起来, 这很不容易,为后续的继续前进铺平了道路. 先到这里吧.

4.2 qemu 调试

qemu 能跑了, 则可用gdb 来调试它.
搞得这么复杂,还不是为了最后能够用gdb远程调试内核或驱动
如果仅仅是跑一个linux, 那就不用费这么大劲了,我们的宿主机就是ubuntu linux.而且工具及多,功能很强大.

完整qemu调试启动命令:
$ cat qemu-run.sh
qemu-system-x86_64
-m 2G -smp 1
-no-hpet
-enable-kvm -cpu host
-kernel arch/x86/boot/bzImage
-initrd ~/test/rootfs/initramfs.cpio.gz
-append “root=/dev/ram0 console=ttyS0 nokaslr”
-virtfs local,path=/mnt/share,mount_tag=host_share,security_model=passthrough,id=hostshare
-nographic
-s
-S

在qemu启动脚本中再加上 -s -S 选项, 就可以用gdb调试驱动了.
-s: -gdb tcp:1234, 在tcp:1234 端口接受gdb 命令
-S: Stop, 停止运行, 等待gdb连接
具体的调试实例, 后面再补充.

  1. 命令行上的两个小坑.
    调试的时候, -smp 1 必需要cpu 核心数为1, 否则,中断后,单步执行时, 走不了几步会被切换到其它cpu. 不能实现单步调试.
    -no-hpet, 关闭高精度事件定时器(no high performance event timer), 否则中断后,单步时,直接跳转到定时器,没法单步调试
    解决了这两个问题,就解决了单步调试问题.

  2. 设置中断时,要用hbreak 命令, 即要用硬中断命令, 用b命令是断不下来的.
    第一次insmod 时, add-symbol-file 之后, 用b 命令也能断下来,例如b demo_read.
    但时,rmmod 后, 再insmod, 就断不下来了,虽然info b 看起来都正常, 删除断点重新设置也不行.
    这是一个大坑. 我不可能为了一次中断而启动一次机器.
    原因的b 命令就不能在内核代码上设置软中断断点,它改不动内核程序区. 第一次insmod后能改动是因为当时内核还没有关闭修改属性.
    为什么gdb能对用户态的程序修改代码区指令为int cc 指令,这是因为内核对gdb ptrace 命令开后门, 但修改内核态代码区却没有后门.
    坑人的地方就在与gdb设置断点没有成功可是它却没有任何提示, 用户以为它成功了. 但时却断不下来.
    所以,内核中设置断点只能用hbreak 硬件断点. 记住就行了.
    这样就解决了设置断点问题, 断点断不下来的问题.

gdb 调试启动命令
$ gdb -x 1.gdb

1.gdb 的内容如下,做一个参考
其中add-symbol-file 中各个段的地址由 /sys/module/demo_drv/section/
隐藏文件.text, .data, .bss, .init.text 等文件内容提供
这样就把中断设置在正确位置,打印变量也能得到正确的地址和值

$ cat1.gdb file vmlinux target remote localhost:1234#hbreakstart_kerneladd-symbol-file/home/hjj/test/module3/demo_drv.ko0xffffffffa0000000\-s.data0xffffffffa0002000\-s.bss0xffffffffa0002480\-s.init.text0xffffffffa0005000hbreak demo_read hbreak demo_init c

贴一张调试图吧! demo_drv.ko 是我调试的一个虚拟字符设备驱动. 中间是若干个单步n 命令,执行成功了.

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 20:05:24

深度学习激活函数选择指南与实战对比

1. 深度学习激活函数的选择逻辑 在构建神经网络时&#xff0c;激活函数的选择往往被初学者视为"黑箱操作"。实际上&#xff0c;这个看似简单的选择直接影响着模型的收敛速度、梯度传播效率以及最终性能表现。我在处理图像分类和时序预测项目时&#xff0c;曾因不当的…

作者头像 李华
网站建设 2026/5/1 20:03:06

企业如何通过 Taotoken 实现内部 AI 调用审计与安全管控

企业如何通过 Taotoken 实现内部 AI 调用审计与安全管控 1. 企业级 API Key 管理与访问控制 企业 IT 管理员在 Taotoken 控制台可以创建多个 API Key&#xff0c;并为每个 Key 设置不同的权限和访问范围。通过为不同部门或项目分配独立的 Key&#xff0c;实现调用权限的隔离。…

作者头像 李华
网站建设 2026/5/1 19:55:58

OpenClaw AI智能体实战:49个中文场景用例与飞书/钉钉深度集成指南

1. 项目概述&#xff1a;一份面向中文开发者的AI智能体实战指南 如果你对AI智能体&#xff08;AI Agent&#xff09;感兴趣&#xff0c;特别是听说过OpenClaw这个开源项目&#xff0c;但面对海量的技能、工具和概念感到无从下手&#xff0c;那么你找对地方了。我花了几个月时间…

作者头像 李华
网站建设 2026/5/1 19:55:30

4DLangVGGT框架:时空连续体的语言-视觉联合建模

1. 项目背景与核心价值在计算机视觉与自然语言处理的交叉领域&#xff0c;动态4D场景理解一直是个极具挑战性的课题。传统方法往往将3D空间与时间维度割裂处理&#xff0c;导致对动态场景的语义理解存在断层。我们团队开发的4DLangVGGT框架&#xff0c;首次实现了时空连续体下的…

作者头像 李华