
实验二十六 构建 etc 与 dev 目录——给骨架装上灵魂对应课件《第6章 构建Linux根文件系统-V2》6.2 节中Slide 34-48系列说明本系列基于华清远见 FS-MP1ASTM32MP157A开发板对应课件《第6章 构建Linux根文件系统》。实验二十五的rfs-busybox有了命令bin/sbin和库lib但它还不知道启动后先干什么init 看谁的脸色、不知道挂哪些文件系统、/dev还是空的。本篇补齐写 etc 四件套inittab / rcS / fstab / profile、按 busybox 官方文档把 mdev 的设备管理流程跑起来、创建其余空目录——根文件系统从躯壳变成系统。全程仍在 Ubuntu 里板子不开上板点火是实验二十七的事。前置实验二十五rfs-busybox 就绪。一、init 进程的工作方式一张 inittab 说清楚内核挂上根文件系统后运行sbin/init实验二十五装出来的init 是 1 号进程之后的一切程序都是它的子孙。init 睁眼第一件事读/etc/inittab没有就用默认行为按里面的条目创建子进程。每条格式id:runlevels:action:processid该子进程用的控制台省略 与 init 同一个我们只有 ttySTM0 一个串口全部省略runlevelsbusybox 的 init 不用这字段留空actioninit 怎么对待这个子进程下表process要执行的程序或脚本前面带-表示交互的起一个可敲命令的会话。action的八个取值课件表 17.6重点三个加粗图课件 Slide 36~37——表 17.6《/etc/inittab 文件中action字段的意义》截图sysinit、wait、once、respawn、askfirst、shutdown、restart、ctrlaltdel 八行的执行条件与说明两页课件用的是同一张表截图。action什么时候执行init 等它吗sysinit系统启动后最先执行仅一次等它结束才继续waitsysinit 之后仅一次等oncewait 之后仅一次不等respawn启动后子进程退出就重启它监视askfirst与 respawn 类似但先打印 “Please press Enter to activate this console.” 等你回车才启动监视shutdown关机/重启时——restartinit 收到 SIGHUP 时需配置 CONFIG_FEATURE_USE_INITTAB——ctrlaltdel按 CtrlAltDel 时——“Please press Enter to activate this console.” 这句话你见过——实验十六点火出厂内核时串口最后几行就有它那是出厂根的 inittab 里某条askfirst条目干的。本篇我们自己的 inittab 里也写一条到时候一模一样地出现。init 的工作节奏总结启动前期跑 sysinit/wait/once 三类正常运行期间维持 respawn/askfirst 两类退了就拉起来退出时跑 shutdown/restart/ctrlaltdel 三类。二、实验环境实际项目实际值操作位置Ubuntu 虚拟机实验二十五的rfs-busybox/目录板子不开上篇产物rfs-busybox/bin、sbin、usr、linuxrc、lib 已齐内核基线实验十九~二十二编的 5.4.31CONFIG_UEVENT_HELPER未开——本篇步骤 5 会用到这个事实开工自检10 秒ls rfs-busybox四样齐全ls rfs-busybox/lib | wc -l有几十个库。缺了回实验二十五。三、课件 ↔ 步骤对应表课件 Slide内容对应步骤34~37构建 etcinittab 内容与 action 表步骤 138etc/init.d/rcS 脚本步骤 239~41fstab 六字段步骤 342profile 与 PS1步骤 443~44dev 方案mdev 内核 Pseudo 配置 mdev.txt 文档步骤 546rcS 最终内容mdev 七步并入步骤 547uevent helper 报错与内核配置步骤 648其他空目录步骤 7本篇动作 → 后面谁用 → 现在含糊的后果本篇动作后面哪一篇要用现在含糊的后果inittab 的::sysinit:/etc/init.d/rcS实验二十七点火后 init 的第一个动作就是它rcS 没跑 什么都没挂载 系统半死rcS 里的 mdev 七步实验二十七起 /dev 自动建设备文件/dev 空 → 串口外的设备全失联fstab 的 tmpfs /tmp 行实验二十七启动日志mount -a的执行对象fstab 格式错一行rcS 第一句就报错profile 的 PS1实验二十七起命令行提示符的样子[rootfsmp1a: /]#提示符不对不知道是哪个文件在管uevent helper 报错预告实验二十七点火时若看到cant create /proc/sys/kernel/hotplug照方抓药以为根文件系统做坏了四、实验步骤以下命令都假设当前在rfs-busybox/里cd rfs-busyboxnano是顺手工具CtrlO回车保存这台 Ubuntu 的 nano 是 4.8底栏就是^O 写入新版 nano 的CtrlS未默认绑定按了可能没反应——以^O 写入为准、CtrlX退出——完整键位卡见实验二十步骤 1本系列通用。本篇四处文件都是新建不存在定位问题nano 直接敲内容即可。步骤 1写 etc/inittabSlide 34mkdir-petc/init.dnanoetc/inittab内容照课件 Slide 34 逐行照抄六条生效行 穿插的六行注释注释行也照抄复制出来与课件截图一模一样# /etc/inittab #this is run first except when booting in single-user mode. ::sysinit:/etc/init.d/rcS # /bin/sh invocations on selected ttys # start an askfirst shell on the console (whatever that may be) ::askfirst:-/bin/sh # stuff to do when restarting the init process ::restart:/sbin/init # stuff to do before rebooting ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ::shutdown:/sbin/swapoff -a图课件 Slide 34——创建的/etc/inittab内容共 12 行6 条生效行::sysinit:/etc/init.d/rcS、::askfirst:-/bin/sh、::restart:/sbin/init、::ctrlaltdel:/sbin/reboot、::shutdown:/bin/umount -a -r、::shutdown:/sbin/swapoff -a穿插 6 行#注释——与上面代码块逐行一致。逐条读生效行#开头的都是注释给读者看的init 不执行第一条是灵魂——系统起来后 init 等着执行/etc/init.d/rcS我们的启动脚本步骤 2第二条起一个交互 shell-表示交互每次都要回车确认即那句 “Please press Enter”后面四条是重启/关机时的收尾动作。对照第一节的 action 表六条各就各位。步骤 2写 etc/init.d/rcSSlide 38nanoetc/init.d/rcS#!/bin/sh# This is the first script called by init process/bin/mount-a# use mdevmount-ttmpfs-osize64k,mode0755 tmpfs /devmkdir/dev/ptsmount-tdevpts devpts /dev/ptsmount-tproc proc /procmount-tsysfs sysfs /sysecho/sbin/mdev/proc/sys/kernel/hotplug mdev-s图课件 Slide 38——inittab 内容截图第 3 行::sysinit:/etc/init.d/rcS中/etc/init.d/rcS被下划线标出——rcS 由 inittab 指定两个文件是上下游。图课件 Slide 38——rcS 脚本内容第 3 行/bin/mount -a标注挂载 etc/fstab 中指定的文件系统第 10~11 行标注 mdev 相关。逐行读行干什么#!/bin/sh脚本解释器声明/bin/mount -a把 fstab步骤 3里登记的文件系统全部挂上mount -t tmpfs ... tmpfs /dev在 /dev 上挂内存文件系统——设备文件生在内存里减少对 Flash/eMMC 的读写实验二十四第一节 tmpfs 的应用mkdir /dev/ptsmount -t devpts devpts /dev/pts远程虚拟终端telnet用的挂载点mount -t proc proc /proc挂 proc——cat /proc/cpuinfo的前提mount -t sysfs sysfs /sys挂 sysfs——mdev 的信息源下一行echo /sbin/mdev /proc/sys/kernel/hotplug告诉内核“设备插拔时请调用 /sbin/mdev”——内核的热插拔代理mdev -s扫描 /sys把启动时已存在的设备全部生成对应文件s scan保存后必须加可执行权限课件红字提醒脚本没有 x 位 init 调不动chmodx etc/init.d/rcSls-letc/init.d/rcS# -rwxr-xr-xx 位在步骤 3写 etc/fstabSlide 39~41nanoetc/fstab# device mount point type options dump fsck order tmpfs /tmp tmpfs defaults 0 0图课件 Slide 39——创建的/etc/fstab内容一行tmpfs /tmp tmpfs defaults 0 0。rcS 的mount -a挂的就是这张表里登记的proc/sysfs/devpts 在 rcS 里手工挂了没进表。六个字段的含义本篇只用了一行的量但字段规则值得记全字段含义备注device挂什么设备文件如 /dev/mtdblock1、NFS 时写host:dirproc/tmpfs 等虚拟文件系统此字段无意义任意值mount point挂到哪目录需先存在type文件系统类型ext4、nfs、sysfs……或auto让内核自辨options挂载参数逗号分隔defaults rw,suid,dev,exec,auto,nouser,async 组合dump是否备份0 不备份通用fsck order开机检查顺序0 不查通常根 1、其他 2图课件 Slide 40——options 字段常用取值表auto/noautomount -a 是否自动挂、user/nouser普通用户可否挂、exec/noexec可否运行挂载区程序、ro/rw只读/读写、sync/async是否同步写盘、defaults组合值。步骤 4写 etc/profileSlide 42nanoetc/profile#!/bin/shexportHOSTNAMEfsmp1aexportUSERrootexportHOMErootexportPS1[$USER$HOSTNAME: \w]# PATH/bin:/sbin:/usr/bin:/usr/sbin:$PATHLD_LIBRARY_PATH/lib:/usr/lib:$LD_LIBRARY_PATHexportPATHLD_LIBRARY_PATH图课件 Slide 42——创建的/etc/profile内容第 5 行export PS1[$USER$HOSTNAME: \w]# 标注PS1 设置命令行提示符。课件截图里 HOSTNAME 写的是fsmpl1a应为fsmp1a的笔误——照录说明名字本身随便定实验二十九还会用 profile.d 的方式再改提示符格式。profile 是用户登录时执行的脚本设提示符PS1、补 PATH、告诉动态连接器去哪找库LD_LIBRARY_PATH。\w 当前路径、\u 用户名、\h 主机名——实验二十九的 PS1 参数表会展开讲。步骤 5dev 目录与 mdev 七步Slide 43~46/dev的方案实验二十四定了mdev 自动管理。先确认内核侧两个前提我们的内核 5.4.31——实验十九的 multi_v7fragment 基线——里这两项都是开的这里只是查一眼grep-ECONFIG_SYSFSy|CONFIG_TMPFSy内核源码/.config# 两行都应有——sysfs 是 mdev 的信息源tmpfs 给 /dev 落脚图课件 Slide 43——内核 .config 的 Pseudo filesystems 段CONFIG_PROC_FSy、CONFIG_SYSFSy、CONFIG_TMPFSy红框等。busybox 源码里的官方说明书busybox源码/docs/mdev.txt给了完整流程图课件 Slide 44——mdev.txt 节选mdev 有 initial population初始生成与 dynamic updates动态增删两种用途都需要 sysfs 挂在 /sys文档给出的典型 init 脚本片段 mount proc、mount sysfs、echo /sbin/mdev /proc/sys/kernel/hotplug、mdev -s更完整的 setup 还要先挂 tmpfs /dev、建 /dev/pts、挂 devpts。把文档七步对到 rcS 上——步骤 2 写的 rcS 恰好就是这七步的落地版mdev.txt 步骤rcS 对应行(1) 挂 tmpfs 到 /devmount -t tmpfs -o size64k,mode0755 tmpfs /dev(2) 建 /dev/ptsmkdir /dev/pts(3) 挂 devptsmount -t devpts devpts /dev/pts(4) 挂 procmount -t proc proc /proc(5) 挂 sysfsmount -t sysfs sysfs /sys(6) 设热插拔代理echo /sbin/mdev /proc/sys/kernel/hotplug(7) 扫描生成设备文件mdev -s图课件 Slide 46——并入 mdev 相关命令后的 rcS 完整内容第 4~11 行红框与步骤 2 我们写的一致。另按课件提醒要手工建一个空的dev目录——tmpfs 挂上去之前挂载点得先存在mkdirdev步骤 6认知预告——uevent helper 报错与内核配置Slide 47本步不动手——内核的 menuconfig 与重编都归实验二十七步骤 1那边有显式的cd与完整操作。现在人在rfs-busybox里敲make menuconfig会报make: *** 没有规则可制作目标“menuconfig”。 停止。不是坏了是站错了地方——rfs-busybox是根文件系统目录没有 Makefilemenuconfig是内核源码树的命令得先回内核顶层实验二十七步骤 1 第一条就是那个cd。课件在此预告了一个上板才会露头的报错先把它的来龙去脉记下实验二十七点火时对号图课件 Slide 47——开发板串口输出Run /sbin/init as init process、/etc/init.d/rcS: line 11: cant create /proc/sys/kernel/hotplug: nonexistent directory以及 “Please press Enter to activate this console.”。报错的成因echo ... /proc/sys/kernel/hotplug需要内核开启CONFIG_UEVENT_HELPER/proc/sys/kernel/hotplug 这个出口由它提供。我们的内核基线是 multi_v7fragment这个选项是关的2026-09-26 对着 multi_v7_defconfig 查证只有 fragment-03 里一句CONFIG_UEVENT_HELPER_PATH开关本身默认 n——所以这条报错在我们板上必然出现不是根文件系统做错了。修法课件给的内核配置实验二十七点火前顺手做图课件 Slide 47——需修改的内核配置路径Location: - Device Drivers - Generic Driver Options - Support for uevent helper选中。图课件 Slide 47——内核 menuconfig 的 Generic Driver Options 菜单[*] Support for uevent helper已选中红框其下还有() path to uevent helper、[*] Maintain a devtmpfs filesystem to mount at /dev、[*] Automount devtmpfs at /dev...等选项。操作记忆卡实验二十七步骤 1 展开内核顶层make menuconfig→ Device Drivers → Generic Driver Options → 勾[*] Support for uevent helper→ 退出保存 →make -j4 uImage dtbs LOADADDR0xC2000040重编 → 按实验二十三的流程把新 uImage 送进 TFTP。顺带一个会让人疑惑的观察提前说明白我们的内核同时开着CONFIG_DEVTMPFS与CONFIG_DEVTMPFS_MOUNTmulti_v7 默认 y——内核挂上根后会自动把 devtmpfs 挂到 /dev 并生成设备文件。所以点火时你可能看到 /dev 里已经有 ttySTM0 等文件那是内核 devtmpfs 干的、不是 mdev 没干活rcS 的 tmpfs mdev 是课件方案的完整教学版两者叠加不冲突。看到什么、谁干的实验二十七的日志里见分晓。步骤 7其他空目录Slide 48mkdirproc mnt tmp sys root var usr/libls# bin dev etc lib linuxrc mnt proc root sbin sys tmp usr varproc、sys、tmp、mnt 是挂载点rcS/fstab 要往里挂东西root 是 root 用户的家var 放可变数据usr/lib是 profile 里 LD_LIBRARY_PATH 报过的路径虽然暂时没有库放那里建上不亏。就地验证分两层看各看各的ls# bin dev etc lib linuxrc mnt proc root sbin sys tmp usr var 十三样findetc-typef|sort# etc/fstab etc/init.d/rcS etc/inittab etc/profile 恰四个别用find . -maxdepth 2 | sort | head -30看整棵树最初稿就写的它实测翻车bin里有近百个符号连接排序后全挤在./bin/...段head -30里只有binetc排在后面根本露不了面——顶层结构交给lsetc里有什么交给find etc各看各的才看得全。五、注意事项rcS 必须有可执行权限chmod x——课件红字init 调一个没有 x 位的脚本会直接失败症状是启动卡住无输出。fstab 的字段分隔用 Tab 或空格都行但列数必须是 6——少一列mount -a就报错。inittab 的::askfirst:-/bin/sh前导减号不能丢——丢了它就不是交互会话回车进不了命令行。hotplug 报错不是根做错了——是内核没开 UEVENT_HELPER本篇步骤 6去内核 menuconfig 勾上重编别在根文件系统里打转。etc 下文件的换行必须是 LF——Windows 记事本编辑会带 CRLF板上sh会报诡异的\r: not found在 Ubuntu 里编辑天然无此问题从 Windows 拷文件时留意。改错想重来这些文件都是纯文本nano 重开覆盖即可rfs-busybox整个目录删了重做也不过几分钟busybox 不用重编。六、验证点一览验证点命令通过的样子在哪一步敲inittab 六条在位cat etc/inittabsysinit/askfirst/restart/ctrlaltdel/shutdown×2 各一条步骤 1rcS 可执行ls -l etc/init.d/rcS-rwxr-xr-x步骤 2fstab 一行四项cat etc/fstabtmpfs /tmp tmpfs defaults 0 0步骤 3profile 在位head -5 etc/profileHOSTNAME/USER/PS1 各行步骤 4内核前提grep -E CONFIG_SYSFSy|CONFIG_TMPFSy 内核/.config两行都在步骤 5dev 空目录ls -d dev目录存在步骤 5全树齐find . -maxdepth 1bin dev etc lib linuxrc mnt proc root sbin sys tmp usr var步骤 7不达标时的排查现象先查什么板上实验二十七init 后直接 kernel panicno initsbin/init在不在ls -l 看它是不是指向 busybox 的连接bin/busybox 在不在板上 rcS 逐行报not found脚本换行符是否 CRLFWindows 中转过文件解释器#!/bin/sh第一行有没有被 nano 加了多余字符板上 /dev 空的rcS 的 mdev 段跑没跑报错行号mdev 勾没勾实验二十五步骤 2UEVENT_HELPER 勾没勾本篇步骤 6板上提示符不是 profile 设的样子profile 文件名拼写-bashvssh的差异busybox ash 登录会读它七、实验完成标志etc/inittab六条写好::sysinit:/etc/init.d/rcS在第一有效行步骤 1 实测etc/init.d/rcS十一行写好、chmod x落实、权限位可见步骤 2 实测ls -l见-rwxrwxr-x属主执行位在etc/fstab一行 tmpfs /tmp、六字段齐步骤 3 实测etc/profile写好PS1 与 LD_LIBRARY_PATH 设上步骤 4 实测dev空目录与 mdev 七步对上 mdev.txt 文档内核 SYSFS/TMPFS 均 y 已 grep 确认步骤 5 实测uevent helper 报错的成因与修法记下内核勾Support for uevent helper 重编实验二十七落实步骤 6proc mnt tmp sys root var usr/lib全建顶层ls十三样、find etc四文件步骤 7 实测八、下一步NFS 挂载根文件系统根文件系统做完了但它在 Ubuntu 里躺着——怎么让板子用上它下一篇实验二十七搭 NFSUbuntu 出一个共享目录板子的 bootargs 改成root/dev/nfs从网络挂根——从此改根文件系统不用重烧卡Ubuntu 里改完板上重启就生效顺手把 uevent helper 那个内核配置处理掉、点火进我们自己的根文件系统。