System analysis of deleting irrelevant codes and their configuration in uboot

Posted by rebelo on Sun, 30 Jan 2022 12:38:43 +0100

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!

Topics: Linux Embedded system ARM