Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

本文是一系列我嘗試製作一個迷你發行版的筆記,皆旨以最简单的语言(可能还是很啰嗦的语言)来描述如何造一個自己的迷你 Linux 發行版。

我還在唸書的時候有很多很大的想法,其中一個便是自己造一個系統。但操作系統編寫是一個龐大的工程,且世界上已經有很多人為此付出很多勞動和心血,業界也是碩果累累。如果論現在重新造一個操作系統有何意義,那大概就只剩下研究操作系統這個領域了。

我從一開始便明白操作系統內核是沒那麼容易編寫的,所以改一個 Linux 系統便是我的首選。

何謂一個「Linux 發行版」

Linux 嚴格來說是指 Linux 內核,而 Ubuntu、CentOS、Fedora 等等則稱為「發行版」。構建出內核後,需要再配合一套配置以及一系列程式,才能算是有一個操作系統。

可以這麼簡單地理解:內核是一個可執行檔,而這些配置和程式是數據,給內核喂進去這些配置和程式,就是給程式喂數據,於是這個程式就起來了,用戶就可以開始用系統了。

一套 Linux 操作系統包含的內容可以這麼簡單地概括:

1
2
3
4
5
┌──────────────────────┐
│ Config & Program │
└─┬──────────────────┬─┘
│ Linux Kernel │
└──────────────────┘

一份內核,搭配一套常人概念中的“系統文件”(一般是安裝媒介寫到根目錄下的文件,或者一些嵌入式系統用的記憶體硬碟,也就是 init ram-disk,簡稱initrd ),便是一個簡單的發行版組成了。

構件一套自己的 Linux 操作系統需要些技術,也有現成的教案可以參考,例如 Linux From Scratch,可以直接在線閱讀,也可以下載 PDF(此版本為 11.0)。

從源碼構建需要關心很多東西,在 menuconfig 裡有很多的內核構建選項可以調整,內容十分地多,但為了簡單,我就直接使用別人的内核以及系统文件了。

Linux 內核是如何啟動的

通常來說,Linux 內核的啟動是這樣的:

  1. 硬件上電後,主板尋找第一個可引導媒體。
  2. 主板加載 GRUB。
  3. GRUB 加載 Linux 內核,給定 initrd,以及內核啟動參數。
  4. Linux 內核啟動,initrd 作為根被掛載。
  5. 內核尋找 /init 或者 /sbin/init 文件並執行

到這裡就是系統配置幹活的地方了。從開始執行 init 或 /sbin/init 開始,Linux 內核就已經啟動成功了。後面的一切事情,例如初始化系統組件、程式預啟動甚至進入桌面等等,就是系統,或者說“發行版”的行為了。本文開始自定義發行版的起始邊界就是到 init (或者 /sbin/init)。

內核其實就是一個普通的應用程序,只是要從 bootloader(一般是 GRUB)處輸入文件名和命令行參數以及指定其需要讀寫的文件(initrd)。內核會根據命令行參數(cmdline)來調整運作方式。cmdline 也可以在內核啟動後通過 /proc/cmdline 訪問得到,所以系統初始化程式可以讀取這個內容來判斷要作何操作。

TinyCore Linux 介紹

TinyCore(Linux)是一个很小的 Linux 发行版,完整的 iso 大小就只有 16MB 左右,但也包含了一个 Linux 操作系统该有的东西。它一般直接完整载入内存运行,也可以根据手册来配置本地持久化。

官方网站就是仓库本身,但访问通常都比较慢,所以我这里所有关于 TinyCore 的资源链接都使用镜像 distro.ibiblio.org(之后以 $TC_REPO 代指)。截止目前为止 TinyCore 的版本号($TC_VERSION 代之)是 13。本文将主要基于 x86_64 架构($TC_ARCH 代之)的 TinyCore 讨论。

TinyCore 使用自己写的 tce-load 来下载依赖包,它从 $TC_REPO/$TC_VERSION.x/$TC_ARCH/tcz 中搜索依赖并下载安装包。它的安装包以 .tcz 结尾,是一个纯粹的 squashfs。可以在 TinyCore 中执行 tce-load -iw 软件名.tcz 来下载对应的包和依赖。其依赖检索方式很简单,路径是 $TC_REPO/$TC_VERSION.x/$TC_ARCH/tcz/$PACKAGE.tcz.dep,内容是所依赖的包的名称。如果对应的 .dep 文件不存在,也就是说这个安装包不依赖其他东西。对应包的额外后缀名含义如下:

  • .dep:依赖列表
  • .info:包的说明
  • .list:包的内容列表
  • .md5.txt:包的 MD5 校验值

可以直接访问 tcz 路径来查找需要的包。

在對應版本的 release/distribution_files/ 包含了該版本的內核文件(vmlinuz)以及初始化記憶體(initrd)。我選用這個發行版作為修改基礎是因為這兩個東西的獲取簡單,而且系統的確沒有東西,十分乾淨。其使用 squashfs 分發軟件的方式也方便把軟件內嵌到 initrd 中。

TinyCore 的文件

TinyCore x86_64 只有兩個文件:一個是內核,一個是 initrd。內核按照傳統,文件名叫 vmlinuz;initrd 在 amd64 版本上是 corepure64.gz。內核沒啥好說的,主要說 initrd。

TinyCore 的 initrd 是一個用 gzip 壓縮過的 cpio 檔,裏面就是整個根文件系統。這個檔案啟動的時候會被直接載入記憶體。本文要修改的目的文件其實就是它。

BusyBox

TinyCore 內嵌 BusyBox

BusyBox 可以說是一個 Linux 上的瑞士軍刀。它是一堆常用 Linux 程序的集合,內建了很多基礎命令甚至額外命令,例如 mv、ls、cat、mkdir、curl 等等命令,甚至連 http 服務器都有(取決於是否有把它編譯進去)。這些常用命令都被包進一個叫 busybox 的可執行檔內,通過 busybox 命令 或者軟鏈易名的形式(這個最常用)的方式來調用想要的命令。

其本身當然也帶一個 shell,ash,是大家都熟悉的終端了。在 TinyCore 裡大部分命令都只是到 busybox 的軟鏈接而已。

下回分解

下一篇文章將開始講述如何方便地修改 initrd 以達成自定義發行版的目的,以及如何通過 qemu 快速啟動虛擬機來測試。

工具提要

調試需要使用 qemu,也就僅僅需要 qemu 而已。

關於啟動和調試

為了方便,這裡暫時不使用傳統的 GRUB 啟動,而是用 qemu 直接加載內核和 initrd。GRUB 的內容以後再說。

下一篇:「Linux 玩耍記事」製作一個發行版·貳:著手開搞

评论