U-Boot porting in depth

1. Drive LCD and network in U-Boot

In the article of U-Boot transplantation, it is introduced how to modify the official uboot, so that uboot can match our own development board, but after the matching is completed, the LCD driver and network driver are still abnormal, so the following will introduce how to modify the LCD driver and network driver wait

1.1 LCD driver modification

The modification of the driver in uboot is carried out in the .c file and .h file of the corresponding board, namely the following two files: mx6ull_andyxi_emmc.c and mx6ull_andyxi_emmc.h

When modifying the LCD driver, pay attention to the following points:

  • Is the LCD IO configuration correct?
  • LCD backlight pin GPIO configuration
  • Are the LCD configuration parameters correct?

The LCD schematic diagram of the I.MX6ULL development board we use is consistent with the official NXP development board, that is, the LCD IO and backlight IO are the same, so the IO part does not need to be modified, just modify the LCD configuration parameters.

⏩ Modify the following content in the mx6ull_andyxi_emmc.c file:

/*######### 原始内容 ###############################*/
/*该代码定义了一个变量displays,类型为display_info_t,这个结构体
是LCD信息结构体,其中包括了LCD的分辨率,像素格式,LCD的各个参数等*/
struct display_info_t const displays[] = {
    
    
	{
    
    
    	.bus = MX6UL_LCDIF1_BASE_ADDR,
    	.addr = 0,
    	.pixfmt = 24,
    	.detect = NULL,
   	 	.enable = do_enable_parallel_lcd,
    	.mode = {
    
    
			.name	      = "TFT43AB",
			.xres         = 480,
			.yres         = 272,
			.pixclock     = 108695,
			.left_margin  = 8,
			.right_margin = 4,
			.upper_margin = 2,
			.lower_margin = 4,
			.hsync_len    = 41,
			.vsync_len    = 10,
			.sync         = 0,
			.vmode        = FB_VMODE_NONINTERLACED
		}
	}
};
/*######### 修改后的内容 ###########################*/
struct display_info_t const displays[] = {
    
    
	{
    
    
    	.bus = MX6UL_LCDIF1_BASE_ADDR,
   	 	.addr = 0,
    	.pixfmt = 24,
    	.detect = NULL,
    	.enable = do_enable_parallel_lcd,
    	.mode = {
    
    
			.name	      = "TFT7016",
			.xres         = 1024,
			.yres         = 600,
			.pixclock     = 19531,
			.left_margin  = 140,  //HBPD
			.right_margin = 160,  //HFPD
			.upper_margin = 20,  //VBPD
			.lower_margin = 12,  //VFPD
			.hsync_len    = 20,   //HSPW
			.vsync_len    = 3,   //VSPW
			.sync         = 0,
			.vmode        = FB_VMODE_NONINTERLACED
		} 
	} 
};

⏩ Modify the panel value in the mx6ull_andyxi_emmc.h file

panel=TFT7016    #根据具体使用型号修改

⏩ After recompiling uboot and burning it into SD, if the LCD still cannot display, you need to check the value of the environment variable panel in the uboot command mode to ensure that it is consistent with the name in the LCD parameter

panel=TFT7016    #与mx6ull_andyxi_emmc.c中修改的名称保持一致

1.2 Network driver modification

I.MX6UL/ULL has an Ethernet MAC peripheral inside, and a PHY chip needs to be connected externally to realize the network communication function. The I.MX6U development board we use provides these two network interfaces, and both use LAN8720A as the PHY chip. The official I.MX6ULL EVK development board of NXP uses the PHY chip of KSZ8081. The following will introduce how to adjust the network driver after replacing the PHY chip to make the network work normally.

The schematic diagram of the development board ENET1/ENET2 is as follows:

insert image description here

The network PHY chip LAN8720A is connected to the I.MX6ULL through the RMII interface. The pins are basically the same as the NXP official I.MX6ULL EVK development board, except that the reset pins are different. As can be seen from the above figure, the reset pin ENET1_RST is connected to the SNVS_TAMPER7 pin of I.M6ULL, and the reset pin ENET2_RST is connected to the SNVS_TAMPER8 pin

When modifying the network driver, pay attention to the following points:

  • LAN8720A reset pin initialization
  • Device ID of LAN8720A
  • LAN8720A driver

⏩ Add reset pin driver in mx6ull_andyxi_emmc.c

/* 结构体数组fec1_pads和fec2_pads是ENET1和ENET2这两个网口的IO 
 * 配置参数,在这两个数组中添加两个网口的复位 IO 配置参数 */
/*######### 原始内容 ###############################*/
static iomux_v3_cfg_t const fec1_pads[] = {
    
    
  MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
  MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  ......
  MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
  MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
};

static iomux_v3_cfg_t const fec2_pads[] = {
    
    
  MX6_PAD_GPIO1_IO06__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
  MX6_PAD_GPIO1_IO07__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  ......
  MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
  MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
};
/*######### 修改后的内容 ###########################*/
static iomux_v3_cfg_t const fec1_pads[] = {
    
    
  MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
  MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  ......
  MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
  MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
  MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL), //添加此行
};

static iomux_v3_cfg_t const fec2_pads[] = {
    
    
  MX6_PAD_GPIO1_IO06__ENET2_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL),
  MX6_PAD_GPIO1_IO07__ENET2_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
  ......
  MX6_PAD_ENET2_RX_EN__ENET2_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL),
  MX6_PAD_ENET2_RX_ER__ENET2_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL),
  MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL), //添加此行
};

/* 函数 setup_iomux_fec 就是根据 fec1_pads 和 fec2_pads 这两个网络IO配置
   数组来初始化I.MX6ULL的网络IO,此处需要在其中添加网络复位IO的初始化代码,
   并且复位一下 PHY 芯片
 */
/*######### 原始内容 ###############################*/
static void setup_iomux_fec(int fec_id)
{
    
    
  if (fec_id == 0)
    imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads));
  else
    imx_iomux_v3_setup_multiple_pads(fec2_pads,	ARRAY_SIZE(fec2_pads));
}
/*######### 修改后的内容 ###########################*/
static void setup_iomux_fec(int fec_id)
{
    
    
  if (fec_id == 0)
  {
    
    
    imx_iomux_v3_setup_multiple_pads(fec1_pads,ARRAY_SIZE(fec1_pads));
    gpio_direction_output(ENET1_RESET, 1);
    gpio_set_value(ENET1_RESET, 0);
    mdelay(20);
    gpio_set_value(ENET1_RESET, 1);
  }
  else {
    
    
    imx_iomux_v3_setup_multiple_pads(fec2_pads,ARRAY_SIZE(fec2_pads));
    gpio_direction_output(ENET2_RESET, 1);
    gpio_set_value(ENET2_RESET, 0);
    mdelay(20);
    gpio_set_value(ENET2_RESET, 1);
  }
}

⏩ Modify the PHY device address and driver in mx6ull_andyxi_emmc.h

/*######### 原始内容 ###############################*/
#ifdef CONFIG_CMD_NET
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define CONFIG_FEC_ENET_DEV 1  //用于选择使用哪个网卡,默认为1(ENET2)
#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x2  //ENET1的PHY地址,默认为0x2
#define CONFIG_FEC_XCV_TYPE RMII
#elif (CONFIG_FEC_ENET_DEV == 1)
#define IMX_FEC_BASE ENET2_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x1  //ENET2的PHY地址,默认为0x1
#define CONFIG_FEC_XCV_TYPE RMII
#endif
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_PHYLIB
#define CONFIG_PHY_MICREL  //用于使能Micrel公司的PHY驱动(KSZ8081芯片)
#endif
/*######### 修改后的内容 ###########################*/
#ifdef CONFIG_CMD_NET
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define CONFIG_FEC_ENET_DEV 1
#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x0  //修改ENET1的PHY地址为0x0
#define CONFIG_FEC_XCV_TYPE RMII
#elif (CONFIG_FEC_ENET_DEV == 1)
#define IMX_FEC_BASE ENET2_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x1  //修改ENET2的PHY地址为为0x1
#define CONFIG_FEC_XCV_TYPE RMII
#endif
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_PHYLIB
#define CONFIG_PHY_SMSC	 //使能SMSC公司的PHY驱动(LAN8720A是SMSC生产的)
#endif

⏩ Delete the driver code of 74LV595 in mx6ull_andyxi_emmc.c

/* NXP 官方I.MX6ULL EVK 开发板使用74LV595来扩展 IO,两个网络的复位引脚
 * 就是由74LV595来控制的,I.MX6U-ALPHA开发板并没有使用74LV595,因此删除掉
 */
/*######### 原始内容 ###############################*/
#define IOX_SDI IMX_GPIO_NR(5, 10)
#define IOX_STCP IMX_GPIO_NR(5, 7)
#define IOX_SHCP IMX_GPIO_NR(5, 11)
#define IOX_OE IMX_GPIO_NR(5, 8)
/*##### 修改后的内容:以上四行替换为以下两行 #######*/
/* ENET1 的复位引脚连接到 SNVS_TAMPER7 上,对应 GPIO5_IO07
 * ENET2 的复位引脚连接到 SNVS_TAMPER8 上,对应 GPIO5_IO08
 */
#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)

//删除74LV595的IO配置参数结构体
/*######### 删除以下内容 ###############################*/
static iomux_v3_cfg_t const iox_pads[] = {
    
    
  /* IOX_SDI */
  MX6_PAD_BOOT_MODE0__GPIO5_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
  /* IOX_SHCP */
  MX6_PAD_BOOT_MODE1__GPIO5_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
  /* IOX_STCP */
  MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
  /* IOX_nOE */
  MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
};

//删除74LV595的初始化函数
/*######### 删除以下内容 ###############################*/
static void iox74lv_init(void)
{
    
    
  int i;
  gpio_direction_output(IOX_OE, 0);
  for (i = 7; i >= 0; i--) {
    
    
    gpio_direction_output(IOX_SHCP, 0);
    gpio_direction_output(IOX_SDI, seq[qn_output[i]][0]);
    udelay(500);
    gpio_direction_output(IOX_SHCP, 1);
    udelay(500);
  }
  ......
  /*
   * shift register will be output to pins
   */
  gpio_direction_output(IOX_STCP, 1);
};

//删除iox74lv_set函数(用于控制74LV595的IO输出电平)
/*######### 删除以下内容 ###############################*/
void iox74lv_set(int index)
{
    
    
  int i;
  for (i = 7; i >= 0; i--) {
    
    
    gpio_direction_output(IOX_SHCP, 0);
    if (i == index)
      gpio_direction_output(IOX_SDI, seq[qn_output[i]][0]);
    else
      gpio_direction_output(IOX_SDI, seq[qn_output[i]][1]);
    udelay(500);
    gpio_direction_output(IOX_SHCP, 1);
    udelay(500);
  }
  ......
  /*
   * shift register will be output to pins
   */
  gpio_direction_output(IOX_STCP, 1);
};

/* 删除板子初始化函数 board_init 中的74lv595 的GPIO初始化代码 */
/*######### 删除部分代码 ###############################*/
int board_init(void)
{
    
    
  ......
  imx_iomux_v3_setup_multiple_pads(iox_pads, ARRAY_SIZE(iox_pads));//删除此行 
  iox74lv_init();  //删除此行
  ......
  return 0;
}

⏩ In the genphy_update_link function in drivers/net/phy/phy.c, add the SMSC PHY chip conditional compilation code segment

/*######### 修改后的内容 ###########################*/
int genphy_update_link(struct phy_device *phydev){
    
    
  unsigned int mii_reg;
//以下为添加的SMSC的PHY芯片条件编译代码段,只有使用SMSC的PHY才会执行
#ifdef CONFIG_PHY_SMSC
  static int lan8720_flag = 0;
  int bmcr_reg = 0;
  if (lan8720_flag == 0) {
    
    
    bmcr_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
    phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
    while(phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR) & 0X8000) {
    
    
      udelay(100);
    }	
    phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg);
    lan8720_flag = 1;
  }
#endif

  mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
  ......
  return 0;
}

At this point, the reset pin driver modification of the network is completed, recompile uboot, and then burn u-boot.bin into the SD card and start it. The uboot startup information is shown in the figure below:

insert image description here

It can be seen from the figure above that the network port (ENET2) of FEC1 is currently used, but the network address has not been set yet. Before uboot uses the network, the following network environment variables must be set

setenv ipaddr 192.168.10.50 	  //开发板IP地址
setenv ethaddr b8:ae:1d:01:00:00  //开发板网卡MAC地址
setenv gatewayip 192.168.10.1 	  //开发板默认网关
setenv netmask 255.255.255.0 	  //开发板子网掩码
setenv serverip 192.168.10.100 	  //服务器地址,也就是Ubuntu地址
saveenv 			  			  //保存环境变量

After setting the environment variables, you can use the network in uboot. Connect the ENET2 on the development board to the computer with a network cable to ensure that the development board and the computer are in the same network segment. Use the ping command to test the network connection. The command is as follows:

ping 192.168.1.100

The result is as shown in the figure below, indicating that the ping host is successful, so far the ENET2 network is working normally

insert image description here

Change the CONFIG_FEC_ENET_DEV parameter in mx6ull_andyxi_emmc.h to 0, then recompile uboot and burn it into the SD card to restart. Follow the above steps to test whether the network of ENET1 is working normally

1.3 Other modifications

There will be a sentence "Board: MX6ULL 14x14 EVK" in the uboot startup information, that is, the name of the board is "MX6ULL 14x14 EVK", which can be changed to our own name "MX6ULL ANDYXI EMMC"

⏩ In the checkboard function in mx6ull_andyxi_emmc.c, make the following modifications

/*######### 修改后的内容 ###########################*/
int checkboard(void)
{
    
    
  if (is_mx6ull_9x9_evk())
    puts("Board: MX6ULL 9x9 EVK\n");
  else
    puts("Board: MX6ULL ANDYXI EMMC\n");
  return 0;
}

After the modification is completed, recompile uboot and write it to the SD card for verification. The uboot startup information is as shown in the figure below. It can be seen that the name has been modified.

insert image description here

2. bootcmd and bootargs environment variables

There are two very important environment variables in uboot, bootcmd and bootargs, which are written in a similar shell scripting language. There are many environment variables defined by NXP in it. The macro CONFIG_EXTRA_ENV_SETTINGS in the file mx6ull_andyxi_emmc.h saves the default values ​​of these environment
variables , its content is as follows:

#if defined(CONFIG_SYS_BOOT_NAND)
#define CONFIG_EXTRA_ENV_SETTINGS \
  CONFIG_MFG_ENV_SETTINGS \
  "panel=TFT43AB\0" \
  "fdt_addr=0x83000000\0" \
  "fdt_high=0xffffffff\0" \
  ......
  "bootz ${loadaddr} - ${fdt_addr}\0"
#else
#define CONFIG_EXTRA_ENV_SETTINGS \
  CONFIG_MFG_ENV_SETTINGS \
  "script=boot.scr\0" \
  "image=zImage\0" \
  "console=ttymxc0\0" \
  "fdt_high=0xffffffff\0" \
  "initrd_high=0xffffffff\0" \
  "fdt_file=undefined\0" \
  ......
  "findfdt="\
  "if test $fdt_file = undefined; then " \
  "if test $board_name = EVK && test $board_rev = 9X9; then " \
  "setenv fdt_file imx6ull-9x9-evk.dtb; fi; " \
  "if test $board_name = EVK && test $board_rev = 14X14; then " \
  "setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \
  "if test $fdt_file = undefined; then " \
  "echo WARNING: Could not determine dtb to use; fi; " \
  "fi;\0" \

2.1 bootcmd environment variable

bootcmd saves the uboot default commands, which will be executed after the uboot countdown ends. It is generally used to start the kernel, such as reading the kernel image file and device tree file in EMMC or NAND Flash to DRAM, and then starting the kernel

You can enter the command line to set the value of the bootcmd environment variable after uboot starts. If the value of bootcmd is not saved in EMMC or NAND, then uboot will use the default value, and the board will use the default value to set the bootcmd environment variable when running uboot for the first time

Open the file include/env_default.h, which contains the following content:

......
#ifdef CONFIG_BOOTARGS
  "bootargs=" CONFIG_BOOTARGS "\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
  "bootcmd=" CONFIG_BOOTCOMMAND "\0"
#endif
......

The default values ​​of many environment variables are specified in env_default.h. For example, the default value of bootcmd is CONFIG_BOOTCOMMAND, and the default value of bootargs is CONFIG_BOOTARGS. We can set the default value of bootcmd by setting the macro CONFIG_BOOTCOMMAND in the mx6ull_andyxi_emmc.h file. The official CONFIG_BOOTCOMMAND value set by NXP is as follows:

#define CONFIG_BOOTCOMMAND \
  "run findfdt;" \
  "mmc dev ${mmcdev};" \
  "mmc dev ${mmcdev}; if mmc rescan; then " \
  "if run loadbootscript; then " \
  "run bootscript; " \
  "else " \
  "if run loadimage; then " \
  "run mmcboot; " \
  "else run netboot; " \
  "fi; " \
  "fi; " \
  "else run netboot; fi"

2.2 bootargs environment variable

bootargs saves the parameters passed by uboot to the Linux kernel, take the following command as an example

setenv bootargs console= ttymxc0, 115200 root= /dev/mmcblk1p2 rootwait rw

Commonly used parameters in bootargs are:

  • console: It is used to set the linux terminal, that is, what device is used to interact with Linux, whether it is a serial port or an LCD screen. Generally, the serial port is set as the Linux terminal, so that you can interact with linux on the computer through the serial port assistant
console= ttymxc0, 115200
//console 为 ttymxc0,因为 linux启动以后I.MX6ULL的串口1
//在linux下的设备文件就是/dev/ttymxc0
//ttymxc0 后面的“115200”,是设置串口的波特率
  • root: used to set the location of the root file system
root= /dev/mmcblk1p2 rootwait rw
// /dev/mmcblk1p2用于指明根文件系统存放在mmcblk1设备的分区2中
// /dev/mmcblkxpy(x=0~ n,y=1~ n)表示mmc设备x的分区y
// rootwait表示等待mmc设备初始化完成以后再挂载,否则的话会出错
// rw 表示根文件系统是可以读写的,不加rw的话可能只能读而无法进行写操作

rootfstype: generally used with root to specify the root file system type, if the root file system is in ext format, this option does not matter. If the root file system is yaffs, jffs or ubifs, you need to set this option to specify the type of root file system

3. U-Boot starts Linux test

After uboot has been transplanted, it is necessary to test whether uboot can complete its work: start the Linux kernel. Two methods of starting the Linux kernel are tested here, one is to start directly from EMMC, and the other is to start from the network

3.1 Start Linux from EMMC

Booting from EMMC is to save the compiled Linux image file zImage and device tree file in EMMC, and uboot reads these two files from EMMC and starts. This is the final booting method of the product. By default, the zImage file and device tree file have been programmed into EMMC, which can be read directly for testing

⏩ Use the command "ls mmc 1:1" to check whether there are related files in partition 1 of EMMC. The result in the figure below indicates that there are related files

insert image description here

⏩ Set the two environment variables bootargs and bootcmd

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000
imx6ull-andyxi-emmc.dtb; bootz 80800000 - 83000000;'
saveenv

⏩ Enter the "boot" command to start the kernel

3.2 Boot Linux from the network

The only purpose of booting a linux system from the network is for debugging! Regardless of whether it is for debugging the linux system or the driver under linux, every time you modify a linux system file or a certain driver under linux, you must burn it into EMMC for testing, which is too troublesome. It can be set to start from the network, and put the linux image file and root file system in the specified folder under Ubuntu, so that after recompiling the linux kernel or linux driver, you only need to copy it to the specified folder. , so that there is no need to frequently program EMMC

You can download zImage and device tree files from Ubuntu through nfs or tftp. This article uses tftp to download zImage and device tree files from Ubuntu. By default, zImage and device tree files have been placed in the tftp directory under Ubuntu.

⏩ Set the two environment variables bootargs and bootcmd

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-andyxi-emmc.dtb; bootz
80800000 - 83000000'
saveenv

⏩ Enter the "boot" command to start the kernel. The result in the figure below indicates that the kernel is started successfully

insert image description here

4. Summary of U-Boot transplantation

This is the end of the uboot porting, a brief summary of the uboot porting process:

  • Regardless of the development board purchased or made by yourself, basically refer to the dmeo board of the semiconductor manufacturer. The semiconductor manufacturer will transplant uboot, kernel and rootfs on their development board, and finally make a BSP package and provide it to the user. We can add our own board on the basis of the official BSP package, which is commonly known as transplantation
  • The purchased or self-made development board generally does not copy the demo board of the semiconductor manufacturer intact, and will make modifications according to the actual situation. Any modification will involve the transplantation of the driver under uboot
  • Generally, uboot needs to solve the serial port, NAND, EMMC or SD card, network and LCD movement, because the main purpose of uboot is to start the Linux kernel, so there is no need to consider too many peripheral drivers
  • Add your own development board information in uboot, and modify the driver in uboot according to the actual situation

Guess you like

Origin blog.csdn.net/Chuangke_Andy/article/details/126724626