找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4426

积分

0

好友

582

主题
发表于 1 小时前 | 查看: 4| 回复: 0

做嵌入式的,都知道 Linux 内核 有多大:几千万行。

但你可能不知道,Linux 0.01 版本——就是最初那个内核——只有 8413 行代码

今天说的这个项目更狠:1000 行

作者是日本开发者 Seiya Nuta。他写这本书的本意,是让你用一个无聊的周末从零写一个操作系统。他在 Hacker News 上说的原话:

I wrote this book so you can spend a boring weekend writing an operating system from scratch.

他管设计操作系统叫"创造你自己的世界"——你想怎么弄就怎么弄。

先说说这人是干什么的。Seiya Nuta 不止写了这一个项目:他还写过 1000 行的 hypervisor(虚拟机监控器),用 Rust 写过 Linux 兼容内核。2021 年那会儿,他的个人网站就是跑在自己写的操作系统上的。属于把操作系统当玩具玩的那类人。

这本书叫《OS in 1,000 Lines》,中文版在 1000os.seiya.me,代码在 GitHub 开源。它原本只是 Nuta 一本日文微内核专著《マイクロカーネルの設計と実装》的附录——结果一个附录,不知道把多少人带进了写操作系统的坑。

书里实现了什么

多任务、异常处理、分页、系统调用、设备驱动、文件系统、Shell,一共 7 个功能。

源代码结构:从零构建操作系统的11个文件与功能说明

多任务不是单片机里 while(1) 轮流点灯那种假多任务,而是真正的进程级上下文切换:寄存器保存、恢复、完整的切换流程。

分页用的是 RISC-V 的 Sv32 两级页表,每个进程有独立的地址空间。PAGE_U 标志位负责管着用户代码能不能碰内核的地盘。

设备驱动是 virtio-blk 磁盘驱动,512 字节一个扇区。文件系统更取巧,直接解析 tar 格式。Shell 就是给人敲命令用的。

7 大功能:多任务 / 异常处理 / 分页 / 系统调用 / 设备驱动 / 文件系统 / Shell。

这 1000 行怎么分的?大致如下:启动和串口输出 60 行,内存管理 130 行,进程调度 120 行,系统调用 60 行,磁盘驱动 100 行,文件系统 120 行,Shell 110 行。每一块代码一屏就能看完。

作者刻意没把项目做成一个迷你 UNIX,只留最核心的部分。他的原话是:想想你的 OS 跟 Linux、Windows 差在哪,本身就是件有意思的事。

它没实现什么,才是最有意思的部分

不处理中断,改成轮询——定期检查设备有没有新数据。做裸机的朋友应该很熟悉这个词:忙等待。

不做抢占式多任务。进程自己觉得该让就让,主动让出 CPU,这叫协作式多任务。

不做进程间通信,管道、socket、共享内存统统没有。

不支持多核,就单核。

把这四块最难啃的骨头砍掉,剩下的就是操作系统最核心的骨架。轮询是基本功,中断是进阶门槛。这个项目故意用轮询,就是让你先把内核到底在干什么看清楚。协作式多任务搞明白了,抢占式无非是外面加个定时器中断的事。

砍掉的 4 块:中断 / 抢占 / IPC / 多核,每一块都对应了一个简单的替代方案。

一个特别有共鸣的点

书里有句话我看了很有感触:

"在实现 printf 之前,你是没有办法用 printf 来调试的。"

搞嵌入式的都懂。开发板上调程序,第一步是先点亮 LED、先跑通串口。串口一通,printf 有了,后面才好干活。没有 printf 的日子,只能靠点灯、靠逻辑分析仪、靠盯着波形硬猜。

Nuta 写操作系统也一样:printf 排在很后面才实现。在那之前,调试靠 QEMU 的指令跟踪、GDB 断点,还有 wfi 指令把 CPU 停住看状态。最原始的工具,调试最底层的东西。等 printf 终于跑起来,那个函数才 40 行,后面的开发就像开了挂。

整个项目就 11 个文件

kernel.c 一个文件,把进程管理、系统调用、设备驱动、文件系统全包了。

kernel.c内核入口代码:memset初始化BSS段并调用PANIC

还有两个链接脚本:kernel.lduser.ld。看到 .ld 这个后缀,写过单片机工程的应该会心一笑——这不就是 STM32 工程里那个链接脚本吗?指定内存布局、段放哪、堆栈在哪。写了这么多年单片机,没想过一个操作系统的内存布局,也是用同一个东西定义的。

书里还专门提醒了一句:这里的 user 是"应用程序"的意思,别跟"用户账户"搞混。我第一眼看到 user.ld 也在想,用户是谁?哈哈。

两个世界:kernel.ld 管内核布局(M/S 模式),user.ld 管用户程序布局(U 模式),中间靠系统调用(ecall)连接。

跑起来是什么样

QEMU运行截图:OpenSBI启动日志、文件系统加载与Shell交互

QEMU 启动,OpenSBI 固件的日志刷出来,加载文件系统,然后 Shell 在那里等着你下命令。你敲 hello,它回你 Hello world from shell!。整个链路——启动、解析文件系统、创建进程、特权级切换、系统调用、输出——全是你自己写的那 1000 行在干活。

有人已经把它移植到真硬件上跑了:一颗 25 美元的 Allwinner D1,RISC-V 芯片,改一下 MMU 代码就跑起来了。你写的那 1000 行,真的能在一颗真实的芯片上跑起来。

最后说两句

Linux 最开始,也只是 Linus 拿业余时间一点点写出来的东西。0.01 版本 8413 行,跟你自己的项目一样大。Nuta 把操作系统拆到 1000 行给你看,意思很明白:这东西没那么神秘,你天天调的内核,最核心的零件就这些。

有兴趣的直接去翻。GitHub 搜 operating-system-in-1000-lines,书在 1000os.seiya.me,有中文版,跟着走一个周末差不多能写完。

操作系统没那么神秘。它最开始,也就是一个人拿业余时间写出来的东西。

动手吧。如果你也在折腾这些看似硬核的底层项目,或者想找同路人聊聊,云栈社区 上有一群和你一样的人。




上一篇:天坑专业转嵌入式Linux自学路线:双非本到985硕,秋招斩获15+ offer复盘
下一篇:嵌入式根文件系统详解:initrd / initramfs / ramdisk / cpio 到底啥关系?
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-8-14 04:56 , Processed in 1.126817 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表