① linux内核映像vmlinux、Image、zImage、uImage区别
vmlinux:Linux内核编译的原始文件,elf格式,未压缩,便于定位内核问题,但不能直接引导系统启动。
Image:在vmlinux基础上,使用obj处理后的二进制内核映像,未压缩,直接引导系统启动。
zImage:Image经过gzip压缩,再使用obj生成的映像,常见作为uboot的引导文件。
uImage:zImage前面附加64字节头信息,描述映像类型、加载位置、大小等,专用于老版本uboot。
zImage与uImage主要区别在于前者是标准的32位内核映像,后者为附加额外信息的映像。
Linux映像的生成过程包括从原始vmlinux文件到最终引导映像的转换,过程中涉及文件格式转换和压缩等步骤。
学习资源:参考Linux内核源码地址:ke.qq.com/course/403254...
群交流:加入Linux内核源码分析交流群(群号:1095678385),获取学习资料和书籍,共享在群文件中。
② 嵌入式linux启动流程
嵌入式Linux启动流程分为四个主要阶段:引导加载程序(Bootloader)、内核加载、根文件系统挂载和系统初始化。
1. 引导加载程序(Bootloader):
这是嵌入式Linux系统启动的第一个阶段。Bootloader的主要任务是初始化硬件设备、设置内存等,为接下来加载Linux内核做好准备。常见的Bootloader有U-Boot、GRUB等。以U-Boot为例,它首先会执行一些硬件的初始化操作,如设置时钟、初始化SDRAM等。接着,U-Boot会从存储介质(如Flash、SD卡)中读取内核映像和设备树(Device Tree),为下一步的内核加载做准备。
2. 内核加载:
在Bootloader完成硬件初始化和准备好内核映像后,接下来就是将Linux内核加载到内存中。通常,内核映像会被加载到RAM中的一个特定位置,这个位置是由Bootloader在之前的步骤中设置好的。内核映像包括压缩的内核代码和一些必要的参数,如设备树(Device Tree)或ATAGS。设备树用于描述硬件配置,使得内核可以在没有硬编码的情况下了解硬件的详细配置。
3. 根文件系统挂载:
当内核成功加载并初始化后,它会尝试挂载根文件系统。根文件系统包含了系统运行所需的所有文件和目录,如/bin、/etc、/lib等。在嵌入式Linux系统中,根文件系统通常存储在Flash、SD卡或其他存储介质上。内核通过之前从Bootloader获取的设备树信息来找到存储介质和根文件系统的位置,然后将其挂载到根目录“/”下。
4. 系统初始化:
当根文件系统成功挂载后,系统就可以开始执行用户空间的程序了。在这个阶段,系统会执行一系列初始化脚本和服务,如启动SSH服务、设置网络配置、启动GUI等。这些初始化脚本通常存放在/etc/init.d或/etc/systemd/system目录下。这些脚本和服务按照预定的顺序执行,确保系统在启动时能够正确地配置和启动所有必要的组件和服务。
总结来说,嵌入式Linux的启动流程是一个复杂的过程,涉及硬件初始化、内核加载、根文件系统挂载和系统初始化等多个阶段。每个阶段都有其特定的任务和要求,需要仔细设计和实现以确保系统的稳定性和可靠性。同时,由于嵌入式系统的硬件和软件环境差异较大,因此在实际开发中需要根据具体的硬件和软件需求来调整和优化启动流程。
③ 【boot】Linux Kernel 镜像的生成以及加载
Linux Kernel 镜像格式包括:vmlinux、Image、zImage、bzImage、uImage、xipImage。vmlinux是原始可引导且未压缩的内核文件,由用户编译得到,实质是 ELF 格式。Image是经过obj处理的原始二进制数据内核代码,未压缩。zImage是经过gzip压缩的vmlinux加上解压代码,适用于NAND Flash。bzImage是使用不同压缩算法的压缩内核映像,压缩率更高,同样适用于NAND Flash。uImage是用于u-boot的镜像文件,比zImage多一个头部信息。xipImage则存放在NOR Flash中,直接运行无需复制到SDRAM。
内核镜像的产生过程包括:首先生成可执行的vmlinux文件;然后通过obj处理成Image,变小但未压缩;接着使用gzip压缩Image生成compress/vmlinux;最后再使用obj处理compress/vmlinux生成zImage,压缩比约为2:1。
Linux内核镜像的加载过程包括加载文件头、内存布局、分阶段加载内核镜像、实模式和保护模式下内核加载。实模式下加载boot/setup.bin,进行硬件初始化并跳转到main()函数开始执行。保护模式下加载boot/vmlinux.bin,解压缩并初始化页表,调用init/main.c:start_kernel()函数。
Linux内核镜像格式多样,根据硬件类型和存储设备选择合适的镜像格式进行加载。加载过程包括硬件初始化、内存布局设定、分阶段加载内核镜像,最后实模式和保护模式下执行内核。
使用make命令如“make zImage”可以生成zImage镜像,相关代码在arch/arm/Makefile中。
内核加载流程包含加载文件头和末尾的CRC校验码,以及在实模式和保护模式下分别执行boot/setup.bin和boot/vmlinux.bin。实模式下执行setup.bin进行硬件初始化,然后跳转到main()函数执行。保护模式下加载vmlinux.bin,解压缩后初始化页表,调用start_kernel()函数启动内核。