制作自己的Linux系统与启动光盘
制作自己的Linux系统与启动光盘
在初次接触Linux时,我有个想法,想把自己编译好的Linux内核放在虚拟机中启动。起初,我束手无策,但后来在IBM的Linux文档库中发现了一种制作Linux ISO的方法(《BIOS和EFI介绍及其启动光盘制作》)。这种方法主要是通过ISOLINUX制作BIOS的启动程序。具体详情可以参考以下文章:What is ISOLINUX?
废话不多说,接下来我将介绍如何生成一个可被Legacy BIOS引导的Linux最小系统的ISO镜像文件。
一、Legacy BIOS boot介绍
首先,让我们了解一下Legacy BIOS是如何启动或引导的。当系统首次引导或被重置时,处理器会执行一个位于已知位置的代码,该位置保存在主板上的闪存中,即基本输入/输出系统(BIOS)。处理器会调用这个重置向量来启动闪存/ROM中已知地址处的程序。通常,它会执行启动自检(POST)来检查机器,并从引导驱动器上的主引导记录(MBR)加载第一个扇区。
这时,第一阶段的引导加载程序开始工作。引导程序(boot loader)位于MBR的第一个扇区中。它被加载到RAM并执行。该引导加载程序的大小通常小于512字节(一个扇区),其作用是加载第二阶段的引导加载程序。
当第二阶段的引导加载程序被加载到RAM并执行时,通常会显示一个动画屏幕,并将Linux和一个可选的初始RAM磁盘(临时根文件系统)加载到内存中。在加载映像时,第二阶段的引导加载程序将控制权交给内核映像,然后内核可以进行解压和初始化操作。在这个阶段,第二阶段的引导加载程序会检测系统硬件、枚举系统链接的硬件设备、挂载根设备,并加载必要的内核模块。完成这些操作后,它启动第一个用户空间程序(init),并执行高级系统初始化工作。
在这里,我简单介绍一下用户空间程序init,它位于/sbin目录下,是初始化的简称。init程序的工作是读取/etc/inittab文件中描述的指令,对系统的各种软硬件环境进行最初化设定。最后,它运行mingetty等待用户输入用户名登录系统。虽然Linux启动时有很多内容,看上去十分高深,但实际上都不过是对这个过程的扩展。明白了这个道理后,你可以编写一些脚本程序,在系统启动的特定时间运行完成任务。
事实上,内核并不关心/sbin下的init是否真的是init,只要是放在/sbin下并命名为init的可执行程序,它都可以执行。你可以进行以下实验:
编写一个非常简单的C程序:
main()
{
printf("hello, world!\n");
}
保存为init.c,并使用gcc编译:
gcc --static -o init init.c
这里的--static参数告诉gcc将程序进行静态链接,这样程序就不依赖任何库就能运行。将编译好的init程序拷贝到/sbin目录下,并备份原来的init程序。重新启动系统,最后系统的输出结果是:hello, world! 然后停在那里。【帮客之家】
在进行这个实验之前,请确保您知道如何将系统恢复到原来的状态。有一个简单的方法,在内核启动前给它加上init=参数。例如,如果您将原来的init程序更改为init.bak,只需在启动时给内核加上init=/sbin/init.bak,就可以使用原来的init程序启动系统。
下图展示了开机过程的示意图:
请注意,上述示意图仅供参考,实际情况可能会有所不同。
希望这些内容能帮助您更好地了解制作自己的Linux系统与启动光盘的过程。如果您有任何问题,请随时提问。