如何编译并运行Linux系统?
前言
学习Linux内核是一件振奋人心的事情,而在学习伊始对Linux内核的成功编译并运行也更会燃起更足的动力去钻研。本文从下载并编译Linux内核、编译busybox、制作一个最小的根文件系统,最后用qemu启动你编译好的内核和根文件系统 ,初步感受Linux内核的魅力所在。
首先明确两点:
- 配置内核就是你来决定编码哪些代码;
- 编译内核就是生成可执行文件的一个过程。
再明确内核文件的产物名称:
- vmlinux:原始的,未经压缩的内核可执行文件
- zImage:压缩过的可执行文件——压缩vmlinux后,加上一个head part(用来解压)
- uImage:用于给uboot引导的zImage
- bzImage:即bigzImage ,通过gzip压缩的
好了,明确了上述几点,就可以开始实验了。本文的实验环境如下:
- Linux系统:ubuntu 20.04
- linux源码版本:linux-4.9.229
- busybox源码版本:busybox-1.30.0
- qemu-system-x86_64版本:2.0.0
实验目标:
- 编译Linux内核源码
- 编译busybox
- 制作一个简版文件系统
- 制作根文件系统镜像文件
- 利用qemu运行linux内核
1.下载并编译Linux内核
Index of /pub/linux/kernel/v4.x/mirrors.edge.kernel.org/pub/linux/kernel/v4.x/
下载并解压后,进入目录。
1.指定硬件体系架构
为了演示方便,选用了x86架构,如果编译arm则需要再下载对应的toolchain。
1 | $ export ARCH=x86 |
2.配置board config
1 | $ make x86_64_defconfig |
3.配置内核
这一步其实是对第2步的进行微调,这里我们使用基于ncurse库编制的图形界面工具:
1 | $ make menuconfig |
如果执行该命令时出现:
原因:缺少ncurses dev工具
1 | sudo apt-get install libncurses5-dev |
如果需要内核支持ramdisk驱动,需要选中如下配置:
1 | General setup ---> |
4.编译内核
1 | $ make -j8 |
编译成功后的内核位于:arch/x86_64/boot/bzImage
至此,内核编译完成。
2. 编译busybox
什么是busybox?
busybox号称“嵌入式Linux的瑞士军刀”。BusyBox工具小巧高效,可以替代一大批常用的标准Linux命令行工具,功能有所简化,非常适合资源有限的嵌入式平台。BusyBox是模块化且高度可配置的,可以对其进行裁剪以满足特定需求。
在如下链接下载busybox:
https://busybox.net/downloads/busybox.net/downloads/
我们以busybox-1.30.0作为实验对象。
下载之后解压并进入该busybox目录开始配置并编译。这里把busybox配置为静态编译,这样不依赖其他动态库比较容易操作和演示。编译则似曾相识,与编译内核的指令是一样的!
1 | $ make menuconfig |
配置完之后进行编译和安装
1 | $ make && make install |
make是编译busybox,make install是为了在对应目录中编译安装一系列的工具。
编译完成后的busybox就安装在源码根目录下的_install目录了。
至此,我们对Linux内核和busybox进行了配置和编译。光编译肯定不过瘾,接下来演示基于busybox制作一个简单的文件系统,并通过qemu模拟器运行Linux,真正的让内核工作起来!
3. 制作一个简版文件系统
编译完成后的busybox就安装在源码根目录下的_install目录了,我们进入_install目录,补充一些必要的文件或目录,相关的shell命令如下:
1 | mkdir -p etc dev mnt proc sys tmp mnt |
4. 制作根文件系统镜像文件
思路:
- 先制作一个空的镜像文件;
- 然后把此镜像文件格式化为ext3格式
- 接着把此镜像文件挂载,并把根文件系统复制到挂载目录
- 卸载该镜像文件。
- 打成gzip包。
1 | !/bin/bash |
最终生成的文件系统镜像名字为:rootfs.img.gz
准备好了内核和文件系统镜像,接下来就是见证奇迹的时刻!
5. qemu运行linux内核
1 | qemu-system-x86_64 \ |
这样一个完整的Linux系统就起来啦!