The first hurdle in learning embedded linux is uboot. Many friends feel helpless about this slightly complex MCU program. This is mainly because there will be many folders after extracting a uboot compressed package, which contains a lot of code. In addition, there are makefile, Kconfig, device tree and so on. I don't know where to start. If we can delete the unused code at this time, it will be very helpful for us to analyze, configure and transplant uboot.
Taking the 2018.3 version of uboot released by xilinx as an example, the processing method of uboot released by other chip manufacturers is similar. First, decompress the uboot compressed package, as shown in the following figure,
First, click README. Here is an explanation of the arch folder,
/arch Architecture specific files
This folder is related to architecture, and our soc is based on arm architecture, so other architectures are useless to us and can be deleted as follows,
At the same time, the Kconfig in this directory also needs to be modified as follows,
Those marked in red above need to be deleted. Since we only retain the arm architecture and delete the rest, Kconfig in other directories will not run naturally. Save and close.
When we click the arm folder, we can see that there are many folders starting with mach and followed by the soc name,
The soc we use here is zynq, so we just keep Mach zynq, and delete the rest as follows,
In addition, the following are reserved for the source in Kconfig, and the rest are deleted,
Let's go back to the arm folder. Here is a dts folder. Click in,
You can see many device tree files for different SOCS. Here we keep the following files related to zynq, and delete the rest,
At the same time, make the following changes to the makefile under this directory, and the rest will remain unchanged,
Then we go to the root directory and enter the board folder. There are many folders for different development boards under this folder. Here we only keep xilinx,
Next, we go to the configs folder under the root directory. There are many configuration files of different development boards. We only keep zynq_zc702_defconfig, delete the rest.
Then we go to the configs folder under the include folder in the root directory. We keep the following two header files,
After all, enter the following two commands to compile,
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zynq_zc702_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
Should be able to compile through.
At this time, uboot looks much refreshing. Next, let's analyze the configuration system of uboot. Today's uboot has introduced kconfig. In the above description, you can also see that we need to modify kconfig. In readme under the root directory of uboot, there are the following contents:,
Selection of Processor Architecture and Board Type: --------------------------------------------------- For all supported boards there are ready-to-use default configurations available; just type "make <board_name>_defconfig". Example: For a TQM823L module type: cd u-boot make TQM823L_defconfig
That is, each board has its own default configuration file. We take zynq's 7020 as an example, so our configuration file is zynq under the configs folder_ zc702_ Defconfig, when we enter the following command,
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zynq_zc702_defconfig
You will see the following printed information,
That is, there is one in the root directory of uboot The config file will be created, which holds the configuration information, since Config and zynq_zc702_defconfig is a configuration file. Are the two files the same? We can find that A lot of configuration information in config is zynq_ zc702_ None in defconfig! Where did the extra configuration information come from? For example, the following configuration items,
CONFIG_SYS_CPU="armv7" CONFIG_SYS_SOC="zynq" CONFIG_SYS_VENDOR="xilinx" CONFIG_SYS_BOARD="zynq"
namely. config yes and zynq_ zc702_ There are no in defconfig. Next, I'll take these configuration items as examples to reveal the answer!, We use vscode to open the uboot folder. In zynq_zc702_defconfig contains the following configuration items:,
CONFIG_ARCH_ZYNQ=y
In other words, the chip we define is zynq, and we use ARCH_ZYNQ searches in the uboot folder (vscode search function is very easy to use),
The following configuration is available in kconfig under arch / arm / Mach zynq folder,
if ARCH_ZYNQ config SPL_LDSCRIPT default "arch/arm/mach-zynq/u-boot-spl.lds" config SPL_FAT_SUPPORT default y config SPL_LIBCOMMON_SUPPORT default y config SPL_LIBDISK_SUPPORT default y config SPL_LIBGENERIC_SUPPORT default y config SPL_MMC_SUPPORT default y if MMC_SDHCI_ZYNQ config SPL_SERIAL_SUPPORT default y config SPL_SPI_FLASH_SUPPORT default y if ZYNQ_QSPI config SPL_SPI_SUPPORT default y if ZYNQ_QSPI config ZYNQ_DDRC_INIT bool "Zynq DDRC initialization" default y help This option used to perform DDR specific initialization if required. There might be cases like ddr less where we want to skip ddr init and this option is useful for it. config SYS_BOARD default "zynq" config SYS_VENDOR string "Vendor name" default "xilinx" config SYS_SOC default "zynq"
That is, if config_ ARCH_ If the zynq configuration item is valid, SYS_BOARD,SYS_VENDOR and sys_ The value of SOC is determined. In addition, there are the following contents in kconfig under arch/arm folder,
config ARCH_ZYNQ bool "Xilinx Zynq based platform" select BOARD_LATE_INIT select CPU_V7 select SUPPORT_SPL select OF_CONTROL select SPL_BOARD_INIT if SPL select BOARD_EARLY_INIT_F if WDT select SPL_OF_CONTROL if SPL select DM select DM_ETH if NET select SPL_DM if SPL select DM_MMC if MMC select DM_SPI select DM_SERIAL select DM_SPI_FLASH select SPL_SEPARATE_BSS if SPL select DM_USB if USB select CLK select SPL_CLK if SPL select CLK_ZYNQ imply CMD_CLK imply FAT_WRITE imply CMD_SPL
Arch selected_ Zynq chose CPU_V7, and CPU is selected_ V7,SYS_ The CPU is configured as armv7,
config SYS_CPU default "arm720t" if CPU_ARM720T default "arm920t" if CPU_ARM920T default "arm926ejs" if CPU_ARM926EJS default "arm946es" if CPU_ARM946ES default "arm1136" if CPU_ARM1136 default "arm1176" if CPU_ARM1176 default "armv7" if CPU_V7 default "armv7m" if CPU_V7M default "pxa" if CPU_PXA default "sa1100" if CPU_SA1100 default "armv8" if ARM64
So far, we can conclude that when we execute make defconfig, it will be based on zynq_zc702_defconfig and kconfig files to generate a config.
In addition, the configuration items are from zynq_zc702_defconfig and kconfig files are another important source. In the root directory of uboot, there are the following contents,
Configuration Options: ---------------------- Configuration depends on the combination of board and CPU type; all such information is kept in a configuration file "include/configs/<board_name>.h". Example: For a TQM823L module, all configuration settings are in "include/configs/TQM823L.h".
For our zynq, that is, the following header file,
From the above analysis, we can see that the configuration items of uboot mainly come from two places, one is the kconfig system, and the other is the header file of c language. So why can't they all come from the kconfig system? In the doc folder, read me The answer given in the kconfig file is as follows:,
If we could completely switch to Kconfig in a long run (i.e. remove all the include/configs/*.h), those additional processings above would be removed.
In other words, today's uboot is a transitional period. If it is completely over successful, all configuration items come from kconfig!