arm32平台
编译一个压缩后的内核镜像:
make zImage
最后链接过程的log如下所示:
LD vmlinux
SYSMAP System.map
SYSMAP .tmp_System.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
AS arch/arm/boot/compressed/head.o
GZIP arch/arm/boot/compressed/piggy.gz
AS arch/arm/boot/compressed/piggy.o
CC arch/arm/boot/compressed/misc.o
AS arch/arm/boot/compressed/head-xscale.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
可以看到这个命令会先生成vmlinux,然后经过OBJCOPY操作生成对应的镜像。内核编译都会先生成未经过压缩的镜像,然后在生成压缩的镜像。以上过程可以分为两个部分:
- 第一步生成未经过压缩的vmlinux、Image
- 第二步生成压缩的vmlinux、zImage
对应关系是这样的:
未压缩的内核镜像生成过程:
vmlinux ---OBJCOPY---> arch/arm/boot/Image
压缩的内核镜像生成过程:
arch/arm/boot/compressed/vmlinux ---OBJCOPY ---> arch/arm/boot/zImage
一般编译器链接生成的文件都是一个ELF格式的可执行文件,对于内核来说也就是经过LD后生成vmlinux,然后利用OBJCOPY工具处理这个EFL文件,去除其中的符号和重定位信息等等,生成一个完全的二进制文件Image。因此当我们需要debug内核时,一定是需要有内核版本对应的vmlinux文件,因为它其中包含了符号信息。可以利用 readelf -s vmlinux
来查看其中的内核符号。
arm64平台
和 arm32 平台不同的是,在 arm64 平台上,一般我们直接生成未压缩的内核镜像来运行,它相对于上面介绍的编译过程省略了压缩的过程。
LD vmlinux
SYSMAP System.map
SYSMAP .tmp_System.map
OBJCOPY arch/arm64/boot/Image
Kernel: arch/arm64/boot/Image is ready
通过上面的log可以看到并没有生成对应的compressed目录来处理内核压缩。仅仅生成了一个版本的内核镜像。
vmlinux ---OBJCOPY---> arch/arm64/boot/Image
欢迎扫码关注我的公众号!