嵌入式技术
整个Linux内核编译的过程非常简单,但是内核编译需要花费很长的时间。因为Linux内核的代码非常多。当然,如果你的计算机性能强劲,时间会短很多。当你准备好性能强劲的计算机后,让小编带你一步一步的编译Linux内核。
进入Linux 内核的官网,下载最新版本,或者其它版本的内核代码。这里是源代码的压缩包。
在kernel.org上你能看到几种类型的内核存在:
- mainline
最新版本的linux内核,发布新版本后会打开一个合并窗口,接受下一版本要做出的合并,窗口关闭后,就会发布新的rc(即release candidate,发布候选)版内核
- stable
这是一个主要针对过去发布的内核进行bug修复的树,它更加的稳定
- linux-next
为发布将来的版本而累积新代码并进行测试的源码树
- longterm
Long Term Support,长期维护的意思
在官网上查看内核tarball链接地址,在一个Linux操作系统中,使用wget命令行下载内核tarball代码。
在下载的过程中可以看到下载进度,下载完成后信息大致如下所示。
Linux内核压缩包如下:
[root@localhost~]# ls -l | grep linux-6.3.tar.xz
-rw-r--r-- 1 root root 136891752 Apr 24 12:59 linux-6.3.tar.xz
压缩包下载完成后,可以通过tar命令解压。
tar -xvf linux-6.3.tar.xz
在解压的时候可以看到文件列表,内容较多,需要解压一会儿。
安装全套必备工具。下面步骤 全部在管理员状态下进行 。
yum install ncurses-devel gcc make rpmdevtools openssl-devel bison flex rpm-build rpm-devel rpmlint python3 coreutils diffutils patch
在编译内核之前,我们可以对内核源代码进行配置。配置的目的主要是确定哪些模块会编译到内核当中。
step 1) 进入源代码目录
cd linux-6.3/
step 2) 拷贝当前主机系统内核使用的config文件
从当前机器的启动目录拷贝config文件到内核源代码目录。目标是使编译内核的config采用与当前环境一致的配置。这个文件保存了在安装系统时内核所安装的模块配置信息,否则需要重新手动指定每一个模块的编译配置。
cp -v /boot/config-$(uname -r) .config
或者
make oldconfig
make oldconfig
命令的作用是检查已有的.config文件和Kconfig文件的规则是否一致,如果一致,就什么都不做,否则提示用户哪些源代码中有的选项在.config文件没有。一般情况下一直执行回车即可。
执行后,内核源码目录下会生成.config文件
[root@localhost linux-6.3]# ls -al | grep -w "config"
-rw-r--r-- 1 root root 232033 May 6 13:39 .config
.config
中保存的就是内核编译的相关设置。它的内容大致是这样的:
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
# CONFIG_COMPILE_TEST is not set
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION="_20230506"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_HAVE_KERNEL_ZSTD=y
CONFIG_KERNEL_GZIP=y
注 :以
#
开头的行就是注释行,这些CONFIG_*
就是设置项,这些设置项与Linux内核的各功能相对应,它的值有三种分别表示编译时的三种操作:
- CONFIG_*=y
表示该项目所对应的功能会被静态地添加到内核中
- CONFIG_*=m
表示该项目对应的功能会被编译成模块,在内核需要时再加载入内核
- CONFIG_* is not set
表示不编译该项目对应的功能
注意:由于内核间功能的相互依赖十分复杂,因此不要尝试手工编辑
.config
文件,否则可能出现编译失败,或者编译后内核无法执行的情况!
step 3) 启动配置界面(可选)
make menuconfig
该命令会运行一些脚本,然后打开一个配置界面
step 4) 打开配置界面(依赖上一步操作)。
可以看出里面包含所有的内核组件,包括文件系统,网络,IO栈,虚拟化和设备驱动等等。
可以通过该图形界面对内核加载的模块编译选项进行调整,如修改编译后的内核名称、新添加之前系统缺少的模块等。
如果你不熟悉,可以不做任何修改。
step 5) 确认config文件中Local version功能是否配置成功
vi .config
打开.config文件,搜索CONFIG_LOCALVERSION,发现已含有刚刚修改的版本附加信息。
使用如下命令编译内核
make -j $(nproc --all)
nproc命令来自英文词组“number of processing units available”的缩写,其功能是用于显示当前进程可用的CPU数量。--all 表示显示所有拥有的CPU数量
参考示例:
显示当前进程可用的CPU数量:
[root@localhost linux-6.3]# nproc
72
显示所有CPU数量:
[root@localhost linux-6.3]# nproc --all
80
输出结果很多,截取部分如下:
编译前内核源码内容如下:
编译后内核源码内容如下:
将模块安装到指定的路径。使用如下命令安装内核模块
make modules_install
默认安装的路径(/lib/modules/kernel-version/)
make modules_install #kernel-version是所编译的内核的版本
指定安装路径
make modules_install INSTALL_MOD_PATH=~/rootfs #指定到开发板的文件系统中或者打包放到文件系统中。
执行过程如下:
[root@localhost linux-6.3]# make modules_install
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/events/amd/power.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/events/amd/power.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/events/intel/intel-uncore.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/events/intel/intel-uncore.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/events/intel/intel-cstate.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/events/intel/intel-cstate.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/events/rapl.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/events/rapl.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/kernel/cpu/mce/mce-inject.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/kernel/cpu/mce/mce-inject.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/twofish-x86_64.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/twofish-x86_64.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/twofish-x86_64-3way.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/twofish-x86_64-3way.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/twofish-avx-x86_64.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/twofish-avx-x86_64.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/serpent-sse2-x86_64.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/serpent-sse2-x86_64.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/serpent-avx-x86_64.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/serpent-avx-x86_64.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/serpent-avx2.ko
SIGN /lib/modules/6.3.0_20230506/kernel/arch/x86/crypto/serpent-avx2.ko
...
INSTALL /lib/modules/6.3.0_20230506/kernel/net/vmw_vsock/vmw_vsock_virtio_transport.ko
SIGN /lib/modules/6.3.0_20230506/kernel/net/vmw_vsock/vmw_vsock_virtio_transport.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/net/vmw_vsock/vmw_vsock_virtio_transport_common.ko
SIGN /lib/modules/6.3.0_20230506/kernel/net/vmw_vsock/vmw_vsock_virtio_transport_common.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/net/vmw_vsock/hv_sock.ko
SIGN /lib/modules/6.3.0_20230506/kernel/net/vmw_vsock/hv_sock.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/net/vmw_vsock/vsock_loopback.ko
SIGN /lib/modules/6.3.0_20230506/kernel/net/vmw_vsock/vsock_loopback.ko
INSTALL /lib/modules/6.3.0_20230506/kernel/net/qrtr/qrtr.ko
SIGN