Linux Nine Detailed Explanation of Kernel Construction Process, Image Introduction, Image Instructions

  In the previous blog post Linux 8: Complete Embedded Linux Environment, (Cross) Compiler Toolchain, CPU Architecture, Embedded System Construction Tools, it was said that the entire embedded Linux operating environment should be built step by step, and the Linux Kernel will be compiled today.

source code

  The source code involved in this article is put on my personal Github: https://github.com/ZCShou/BOARD-STM32F769I-EVAL. This warehouse contains all the source codes of the complete embedded Linux environment to be built. Subsequent blog posts will be based on the source codes in this warehouse to learn!
insert image description here

development environment

  The basic development environment I use here is still Ubuntu 22.04.1 LTS + Arm GNU Toolchain 11.3.Rel1 explained many times in previous blog posts, and the corresponding J-link is still J-Link_Linux_V764e_x86_64.deb. The issues that need attention in this environment are as follows:
insert image description here

  1. Since Ubuntu 22.04 LTS comes standard with OpenSSL 3.x by default, and the old version of U-Boot uses OpenSSL 1.x, so when compiling the old version of U-Boot in this environment (relevant processing has been added since commit e927e21c), there will be a bunch of warnings , therefore, the follow-up use of u-boot-v2022.10 is the main version:
    insert image description here
  2. Arm GNU Toolchain 10.2-2022.02 has a BUG, ​​which causes an error when compiling U-Boot. Do not use this version!
    insert image description here
  3. Newer versions (after Arm GNU Toolchain 10.3) of the Arm GNU Toolchain require Python 3.8 support for GDB on Linux. However, Ubuntu 22.04 defaults to Python 3.10. Run it directly and arm-none-eabi-gdbreport the error as follows:
    insert image description here
    The solution is to install Python3.8 manually directly. Legacy Arm GNU Toolchain 10.3 -2021.10 does not require Python support
    sudo add-apt-repository ppa:deadsnakes/ppa -y
    sudo apt install python3.8
    

  Another point, since I have already installed most of the tools needed in the build process when compiling U-Boot, there may not be too many tools to reinstall here. If there is an error, please refer to the detailed explanation of the U-Boot process of compiling U-Boot based on one of the blog posts , the introduction and usage instructions of the Image mirror, and the usage instructions of the DTB file . There should be a solution.

operating environment

  The embedded environment I use is the STM32F769I-EVAL board. The STM32F769NI MCU used by the STM32F769I-EVAL board uses the ARM Cortex-M7 core, and the instruction set architecture is ARMv7m. In addition, it should be noted that the RX of the serial port on this board is disconnected by default and needs to be connected with a short-circuit cap.
insert image description here
  Kernel itself does not provide support for the STM32F769I-EVAL board, but it supports the STM32F769-Disco board. Both the MCU of the STM32F769-Disco development board and the STM32F769I-EVAL evaluation board use the STM32F769NI, so we can run it after compiling and downloading directly.

  However, the onboard resources of the two are different (for example, DRAM size), so some peripheral information recognized by the Kernel is incorrect. Here we only focus on how to perform zero-based compilation. In the blog post Ten Linux Porting Process Details, STM32F769I-EVAL Development Board Adaptation, I introduced in detail how to port the Kernel to the STM32F769I-EVAL board.

build process

  The process of building Linux Kernel is exactly the same as that of U-Boot. Because the construction of U-Boot adopts the Kconfig/Kbuild construction system of Linux Kernel. For details, please refer to the detailed explanation of the U-Boot process of compiling U-Boot based on zero basis, the introduction and usage instructions of Image mirroring, the usage instructions of DTB files, and the detailed explanation of the U-Boot 4th construction process (Kconfig configuration + Kbuild compilation) .

  Before starting to compile, we first introduce two commands: make cleanused to clear the compilation intermediate files and make distcleanused to clear all compiled files. If we want to recompile, we can use the above two commands to clean up the environment. These two commands are defined in the Makefile in the root directory of the Kernel source code.

  1. The first step must be to obtain the source code of the Kernel. I am using the latest LTS version: 5.15.52: wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.52.tar.xz. Unzip directly after downloading: tar xvJf linux-5.15.52.tar.xz.
    insert image description here

    1. Relevant tools may be required to download directly from the Kernel official website
    2. It is best not to choose the version of the Mainline branch
    3. The decompression process takes a long time, please wait patiently

      After successfully downloading and decompressing the source code, we need to enter the decompressed Kernel source code directory and use the command: cd linux-5.15.52. After that, perform various operations in the Kernel source code directory.

  2. The second step is to generate the configuration, use the command directly: ARCH=arm CROSS_COMPILE=arm-none-eabi- make O=build_stm32 stm32_defconfig. Among them, the parameter O=xxis used to specify the output path of compilation, so that all compilation outputs are placed in the specified directory for easy viewing.
    insert image description here

  3. The third step is to modify the configuration (cropping). Use the command directly: ARCH=arm CROSS_COMPILE=arm-none-eabi- make O=build_stm32 menuconfig. Among them, the parameter O=xxis used to specify the output path of compilation, so that all compilation outputs are placed in the specified directory for easy viewing.
    insert image description here
      Special attention should be paid to the fact that each step of the command must have ARCH=arm CROSS_COMPILE=arm-none-eabi-these two parameters, otherwise the configuration cannot be displayed normally according to the architecture we specified. Normally, you will enter the configuration interface on the left below.
    insert image description here
      Here we need to change some parameters: “System Type” > “DRAM Base” = 0xc0000000 and “DRAM Size” = 0x02000000, and remove the model in front of “Boot options” -> “Kernel Execute-In_Place From ROM”. Finally save and exit.
    insert image description here

  4. The fourth step is to actually compile, directly use the command: ARCH=arm CROSS_COMPILE=arm-none-eabi- make O=build_stm32 -j$(nproc), and then wait for a long time... Among them, the parameter O=xxis used to specify the output path of the compilation, so that all compilation outputs are placed in the specified directory for easy viewing.
    insert image description here

  5. After the normal compilation is completed, the two files we really need arch/arm/boot/zImageand .arch/arm/boot/dts/stm32f769-disco.dtb
    insert image description here

Image Description

  When building a Kernel image, we can choose a variety of formats for the kernel image. It depends on the configuration in make menuconfigthis step. Some formats of images may be specific to the architecture. Let's introduce common image formats.
insert image description here

  • vmlinux : vmIt is the abbreviation of Virtual Memory. It is the most original kernel file compiled by the user from the kernel source code. It is a file in ELF (Executable and Linkable Format) format. After we compile the Kernel, the file will be generated in the root directory of the source code. vmlinux is the most original image file, and other image files are generated by it. All other uncompressed images are generated directly or indirectly from it.
    insert image description here
      The name vmlinux comes from Unix. In the 1960s, Unix developers simply called their kernel "unix", so after Linux was born in the 1990s, Linus started calling their kernel "Linux". When virtual memory was developed for easier multitasking capabilities, "vm" was placed at the front of the file to indicate that the kernel supports virtual memory. For a while, the Linux kernel was called vmlinux.
      In Ubuntu, the kernel image file is in the format of vmlinux, stored in /bootthe folder , and the format of the name is vmlinuz-ABCD. ABC is the version number of Stable Kernel, and D represents the version number of PATCH.
    insert image description here
    Note that ./arch/arm/boot/compressedunder , there is also a compressed vmlinux. All other compression-related images are generated directly or indirectly from it.
    insert image description here

  • System.map: Record the location of each symbol in the Kernel, but this file is manually generated using nm and grep tools (not the map file output by the linker), and the specific processing is in scripts\mksysmapthe file
    insert image description here

  • vmlinuz : As the kernel got bigger and couldn't fit in the available boot memory, the kernel image was compressed, and the last x was changed to z in the name to indicate that it was compressed with zlibcompression This compression is not always used, but is often replaced by LZMA or BZIP2.

  • Image : It is generated based on the uncompressed vmlinux in the root directory. After compiling the Kernel, the file will be generated under the corresponding architecture boot(for example, ).   The kernel code containing only binary data processed by objcopy is the remaining content after removing the ELF header and tail symbol tables in vmlinux.arch\arm\boot
    insert image description here

    insert image description here

  • zImage : It is generated based on the compressed vmlinux. After compiling the Kernel, the file will be generated under the corresponding architecture boot(for example, ). The generation method is exactly the same as the image above (pruning the head and removing the tail). There are not many pictures here.arch\arm\boot
    insert image description here

    1. zImage is a compressed image file commonly used by ARM linux
    2. Most of the Linux image files in this format are stored on NAND
  • bzImage : bz means big zImage, its format is similar to zImage, but it uses a different compression algorithm, and bzImage has a higher compression rate.

  • uImage : This is a dedicated image file for uboot. It adds a header (tag) with a length of 0x40 before zImage. The header information describes the type, loading location, generation time, size and other information of the image file. In other words, if the execution starts directly from the 0x40 position of uImage, there is no difference between zImage and uImage.

    1. After compiling the Kernel, the file will be generated under the corresponding architecture boot(for example, )arch\arm\boot
    2. Most of the Linux image files in this format are stored on NAND
  • xipImage : It is generated based on the uncompressed vmlinux in the root directory. After compiling the Kernel, the file will be generated under the corresponding architecture boot(for example, ). The generation method is exactly the same as the image above (pruning the head and removing the tail). There are not many pictures here.arch\arm\boot
    insert image description here

    xipIt is the abbreviation of Execute In Place. Most of the Linux image files in this format are stored on the NorFlash. They do not need to be copied to the memory SDRAM during operation, and can be run directly on the NorFlash.

Image use

  The use of Kernel image is related to our configuration make menuconfigin . Of course it is also related to U-Boot. In the above compilation, the files we actually need are linux-5.15.52/build_stm32/arch/arm/boot/zImageand linux-5.15.52/build_stm32/arch/arm/dts/stm32f769-disco.dtbthese two files.

  • zImage : This usually requires the use of U-Boot related commands to download it to the corresponding memory of the development board. For example, here I need to use the command fatload mmc 0 0xc0000000 zImageto download zImage to MMC
  • stm32f769-disco.dtb : This needs to be directly burned into the internal FLASH of the MCU, the address is 0x81c0000. This actually has a corresponding configuration item in U-Boot.

reference

  1. https://www.howtogeek.com/howto/31632/what-is-the-linux-kernel-and-what-does-it-do/
  2. https://www.cnblogs.com/Oude/articles/12039025.html
  3. https://james-hui.com/2021/07/02/building-a-small-uboot-linux-and-rootfs-for-arm-cortex-m7/
  4. https://blog.csdn.net/m0_47799526/article/details/106203517
  5. https://blog.csdn.net/lpwsw/article/details/122098847

Guess you like

Origin blog.csdn.net/ZCShouCSDN/article/details/122102706