vmlinux、vmlinuz、uImage、linuxrc的区别

一、vmlinux

Linux内核编译出来的原始的内核文件,ELF格式。

使用16进制工具查看vmlinux的头部就是这样的,就是一个ELF可执行文件:

二、vmlinuz

vmlinuz是由ELF文件vmlinux经过objcopy后,并经过压缩后的文件,它是可引导的文件。

vmlinuz的建立有两种方式

  • 一种是通过编译内核时通过“make zImage”创建,也就是zImage,它适用于小内核的情况,适用于低端内存(640K),它的存在是为了向后的兼容性。
  • 另外一种是通过编译内核时通过“make bzImage”创建,也就是bzImage,它是压缩的内核映像,适用于高端内存(1M以上)

1、zImage可以在嵌入式系统经常看到,如下所示:

使用16进制工具查看zImage的头部就是这样的:

使用binwalk分析文件:

2、在Ubuntu系统中,vmlinuz可以在/boot目录找到,使用file命令查看,它是属于bzImage,如下所示:

使用16进制工具查看bzImage的头部就是这样的,有着PE文件的头部:

使用binwalk查看,其中有一段是gzip压缩的数据,解压后就是vmlinux的ELF文件

三、uImage

而uImage则是使用工具mkimage对普通的压缩内核映像文件(zImage)加工而得。它是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。该映像是老版本uboot专用的引导映像。

关于嵌入式系统的uImage类型的固件可以参考《OpenWrt固件结构分析》,如下图所示是openwrt的uImage类型的固件,它有0x40个字节的固件头,就是uImage格式的。

使用16进制工具查看文件的头部:

使用binwalk分析文件:

四、linuxrc

在内核启动的最后阶段启动了三个进程

进程0:进程0其实就是刚才讲过的idle进程,叫空闲进程,也就是死循环。
进程1:kernel_init函数就是进程1,这个进程被称为init进程。
进程2:kthreadd函数就是进程2,这个进程是linux内核的守护进程。这个进程是用来保证linux内核自己本身能正常工作的。

在嵌入式操作系统中一般会指定/linuxrc为init进程,它是由busybox make install产生的,有的操作系统会使用/sbin/init作为init进程。

/linuxrc是一个可执行的应用程序,/linuxrc是应用层的,和内核源码没有直接关系。

操作系统启动后在一系列的自己运行配置之后,最终会给用户一个操作界面(也许是cmdline,也许是GUI),这个用户操作界面就是由/linuxrc带出来的。

参考链接:

https://view.inews.qq.com/a/20220210A03VGA00

https://blog.csdn.net/anzhuangguai/article/details/51241219

https://blog.csdn.net/wen0605/article/details/8439381

http://t.zoukankan.com/ldxsuanfa-p-9952120.html

https://blog.csdn.net/weixin_34268169/article/details/94104334

https://wenku.baidu.com/view/885ee23e5c0e7cd184254b35eefdc8d376ee1429.html