从零写 OS 内核-第二十篇:用户工具链 —— 实现 ls、cat、mkdir 等基础命令
“内核再强大,若没有用户工具,也只是孤岛。 今天,我们编写第一个用户态 shell 工具集,让你的 OS 真正可用!”
在前十九篇中,我们构建了完整的操作系统内核: ✅ 多核 SMP 支持 ✅ 高半内核地址空间 ✅ ext2 文件系统 ✅ 进程管理与调度 ✅ 标准输入输出
但用户仍只能运行硬编码的测试程序。 真正的操作系统,必须提供 基础命令行工具 ,让用户能:
浏览文件(
ls
)
创建目录(
mkdir
)
查看文件(
cat
)
创建空文件(
touch
)
输出文本(
echo
)
今天,我们就来: 1️⃣ 编写这些工具的简化版用户程序 2️⃣ 通过 ext2 文件系统加载并执行它们 3️⃣ 实现一个简易 shell
让你的 OS 拥有 完整的命令行交互能力 !
🛠️ 一、用户工具设计原则
为简化,我们遵循:
静态链接
:无动态库依赖
单文件实现
:每个工具一个
.c
文件
仅依赖系统调用
:
open
/
read
/
write
/
mkdir
等
无错误恢复
:出错直接退出
工具列表:
| 命令 | 功能 | 系统调用 |
|---|---|---|
| ls | 列出目录内容 | open , getdents |
| cat | 显示文件内容 | open , read , write |
| mkdir | 创建目录 | mkdir |
| touch | 创建空文件 | open , close |
| echo | 输出参数 | write |
| shell | 命令行解释器 | fork , exec , wait |
💡 所有工具通过 exec(“/bin/ls”, …) 从 ext2 加载 !
📁 二、实现 ls:目录遍历
系统调用: getdents
用户态 ls:
✅ getdents 返回目录项, ls 过滤并输出 。
📖 三、实现 cat:文件读取
🔑 循环读取直到 EOF(read 返回 0) 。
📂 四、实现 mkdir 与 touch
mkdir:
touch:
💡 O_CREAT 标志让 open 在文件不存在时创建它 。
💬 五、实现 echo 与 shell
echo:
简易 shell:
🌟 shell 通过 fork + exec 运行任意命令 !
🧪 六、构建与部署到 ext2
- 编译用户工具
-
创建 ext2 镜像
-
内核启动 init
▶️ 七、运行效果
启动 QEMU:
交互示例:
✅ 完整的命令行体验!
⚠️ 八、局限与改进方向
- 无管道与重定向
需实现
dup2
系统调用
shell 需解析
|
,
>
,
< -
无环境变量
需在
exec
时传递
envp -
无路径搜索
当前硬编码
/bin/
,应支持
PATH
环境变量 -
无权限检查
ext2 中已存储权限,但未在
open
/
mkdir
中验证
🌱 下一步:实现 shell 重定向与管道,支持 cat file | grep text !
💬 写在最后
这些看似简单的 ls 、 cat , 是 Unix 哲学“小工具组合”的起点。 它们让操作系统从“内核”变为“平台”, 让用户能自由构建自己的工作流。
今天你编译的 echo , 正是无数开发者每天使用的命令的雏形。
🌟 工具的价值,不在于复杂,而在于可用。
📬 动手挑战 : 添加 rm 命令(需实现 unlink 系统调用),并测试删除文件。 欢迎在评论区分享你的工具扩展!
👇 下一篇你想看: shell 重定向与管道 ,还是 动态链接器(ld.so) ?
#操作系统 #内核开发 #用户工具 #shell #ls #cat #文件系统 #从零开始
评论