uboot中的参数——nandflash

uboot中的参数——nandflash

#ifdef CONFIG_SYS_USE_NAND
#define CONFIG_MFG_NAND_PARTITION "mtdparts=gpmi-nand:4m(u-boot),256k(env),1m(logo),1m(dtb),8m(kernel),-(rootfs) "
#else
#define CONFIG_MFG_NAND_PARTITION ""
#endif

给nandflash分区,4m uboot,256k env,1m logo,1m dtb,8m kernel,余下的为rootfs
使用命令查看分区情况:
image

可以看到每个分区的size与设置对应,erasesize为nandflash最小的可擦除扇区。0x40000为256KB。

📌正点原子的nandflash的erasesize为0x20000,所以正点原子的uboot的env大小为128K。所以在没有修改的情况下,对现有的nandflash进行分区就会导致错误。
ubi0: MTD device 5 is write-protected, attach in read-only mode
这是由于分区表未与nor flash的物理擦除块边界对齐而导致的,因此调整分区表即可解决此问题,所以这里调整为256k。

uboot的bootcmd会加载zImage和设备树到内存中,所以还需要调整zImage和设备树的地址。

#if defined(CONFIG_SYS_USE_NAND) && !defined(CONFIG_SYS_BOOT_SD)
#define CONFIG_EXTRA_ENV_SETTINGS \
  CONFIG_MFG_ENV_SETTINGS \
  "panel=TFT50AB\0" \
  "fdt_addr=0x83000000\0" \
  "fdt_high=0xffffffff\0"    \
  "console=ttymxc0\0" \
  "splashimage=0x88000000\0" \
  "splashpos=m,m\0" \
  "logo_offset=0x420000\0" \
  "logo_size=0x100000\0" \
  "fdt_offset=0x5a0000\0" \
  "bootargs=console=ttymxc0,115200 ubi.mtd=5 "  \
    "root=ubi0:rootfs rw rootfstype=ubifs "         \
    CONFIG_BOOTARGS_CMA_SIZE \
    "mtdparts=gpmi-nand:4m(u-boot),256k(env),1m(logo),1m(dtb),8m(kernel),-(rootfs)\0" \
  "bootcmd=nand read ${loadaddr} 0x640000 0x800000;"\
    "nand read ${fdt_addr} ${fdt_offset} 0x20000;"\
    "bootz ${loadaddr} - ${fdt_addr}\0"

可以看到:

bootcmd=nand read ${loadaddr} 0x640000 0x800000;"\
    "nand read ${fdt_addr} ${fdt_offset} 0x20000;"\
    "bootz ${loadaddr} - ${fdt_addr}\0"

loadaddr:0x83000000,
0x640000为zImage在nandlflash中的偏移位置了:4m(u-boot)+256k(env)+1m(logo)+1m(dtb)
0x800000 为大小 8M 对应 “8m(kernel)”。

设备树的地址也需要修改,正点原子的修改函数:

正点原子根据LCD的引脚情况,选择加载哪个设备树,这里因为手头是7_1024x600的屏幕,所以默认设置为这个。

void select_display_dev (void) {
  int idcode = CONFIG_LCD_7_1024x600;

  /* IOMUXC init */
  //imx_iomux_v3_setup_multiple_pads(lcd_id_pads, ARRAY_SIZE(lcd_id_pads));

  /* gpio init */
  //gpio_direction_output(IMX_GPIO_NR(3, 3), 1);  /* Enable connector */
  //gpio_direction_input(IMX_GPIO_NR(3, 28));
  //gpio_direction_input(IMX_GPIO_NR(3, 20));
  //gpio_direction_input(IMX_GPIO_NR(3, 12));

  // idcode = ((gpio_get_value(IMX_GPIO_NR(3, 28)) << 2) |
  //     (gpio_get_value(IMX_GPIO_NR(3, 20)) << 1) |
  //     (gpio_get_value(IMX_GPIO_NR(3, 12)))) & 0x7U;

  switch (idcode) {
#ifdef CONFIG_ENV_IS_IN_NAND
        case CONFIG_VGA_DISPLAY: /* 7 */
            setenv("fdt_offset","0x600000");
            setenv("panel","VGA-DISPLAY");
      break;

    case CONFIG_HDMI_DISPLAY: /* 6 */
            setenv("fdt_offset","0x5e0000");
            setenv("panel","HDMI-DISPLAY");
            break;

    case CONFIG_LCD_10_1_1280x800: /* 5 */
      setenv("fdt_offset","0x5c0000");
      setenv("panel","LCD-10.1-1280x800");
      break;

    case CONFIG_LCD_7_1024x600: /* 2 */
      setenv("fdt_offset","0x5a0000");
      setenv("panel","LCD-7-1024x600");
      break;

    case CONFIG_LCD_7_800x480: /* 4 */
      setenv("fdt_offset","0x580000");
      setenv("panel","LCD-7-800x480");
      break;

        case CONFIG_LCD_4_3_800x480: /* 1 */
             setenv("fdt_offset","0x560000");
             setenv("panel","LCD-4.3-800x480");
          break;

    case CONFIG_LCD_4_3_480x272: /* 0 */
      setenv("fdt_offset","0x540000");
      setenv("panel","LCD-4.3-480x272");
      break;

    default:
      printf("*** This LCD id does not exist! Use the default LCD. ***\n");
                        setenv("fdt_offset","0x560000");
                        setenv("panel","LCD-7-800x480");
      break;

#else
        case CONFIG_VGA_DISPLAY: /* 7 */
            setenv("fdt_file","imx6ull-14x14-emmc-vga.dtb");
            setenv("panel","VGA-DISPLAY");
          break;
        case CONFIG_HDMI_DISPLAY: /* 6 */
            setenv("fdt_file","imx6ull-14x14-emmc-hdmi.dtb");
            setenv("panel","HDMI-DISPLAY");
        break;
        case CONFIG_LCD_10_1_1280x800: /* 5 */
            setenv("fdt_file","imx6ull-14x14-emmc-10.1-1280x800-c.dtb");
            setenv("panel","LCD-10.1-1280x800");
          break;
        case CONFIG_LCD_7_1024x600: /* 2 */
            setenv("fdt_file","imx6ull-14x14-emmc-7-1024x600-c.dtb");
            setenv("panel","LCD-7-1024x600");
          break;
        case CONFIG_LCD_7_800x480: /* 4 */
            setenv("fdt_file","imx6ull-14x14-emmc-7-800x480-c.dtb");
            setenv("panel","LCD-7-800x480");
          break;
        case CONFIG_LCD_4_3_800x480: /* 1 */
            setenv("fdt_file","imx6ull-14x14-emmc-4.3-800x480-c.dtb");
            setenv("panel","LCD-4.3-800x480");
          break;
        case CONFIG_LCD_4_3_480x272: /* 0 */
            setenv("fdt_file","imx6ull-14x14-emmc-4.3-480x272-c.dtb");
            setenv("panel","LCD-4.3-480x272");
          break;
        default:
            printf("*** This LCD id does not exist! Use the default LCD. ***\n");
            setenv("fdt_file","imx6ull-14x14-emmc-7-800x480-c.dtb");
            setenv("panel","LCD-7-800x480");
          break;
#endif
  }
}

int board_late_init(void)
{
  ...
  select_display_dev();
  return 0;
}

最终执行:

setenv("fdt_offset","0x5a0000");
setenv("panel","LCD-7-1024x600");

那么为什么是0x5a0000?这其实跟烧写设备树的地址有关。首先,我们这样对nandflash分区:

mtdparts=gpmi-nand:4m(u-boot),256k(env),1m(logo),1m(dtb),8m(kernel),-(rootfs)\0"

在imx6mknandboot.sh中烧写设备树:

echo "正在擦除设备树分区..."
flash_erase /dev/mtd3 0 0
echo "正在烧写设备树..."
nandwrite -p /dev/mtd3 $sdkdir/boot/imx6ull-14x14-nand-4.3-480x272-c.dtb >/dev/null 2>&1
nandwrite -s 0x20000 -p /dev/mtd3 $sdkdir/boot/imx6ull-14x14-nand-4.3-800x480-c.dtb >/dev/null 2>&1
nandwrite -s 0x40000 -p /dev/mtd3 $sdkdir/boot/imx6ull-14x14-nand-7-800x480-c.dtb >/dev/null 2>&1
nandwrite -s 0x60000 -p /dev/mtd3 $sdkdir/boot/imx6ull-14x14-nand-7-1024x600-c.dtb >/dev/null 2>&1
nandwrite -s 0x80000 -p /dev/mtd3 $sdkdir/boot/imx6ull-14x14-nand-10.1-1280x800-c.dtb >/dev/null 2>&1
nandwrite -s 0xa0000 -p /dev/mtd3 $sdkdir/boot/imx6ull-14x14-nand-hdmi.dtb >/dev/null 2>&1
nandwrite -s 0xc0000 -p /dev/mtd3 $sdkdir/boot/imx6ull-14x14-nand-vga.dtb >/dev/null 2>&1

可以看到每隔0x20000依次烧写一个设备树文件,所以select_display_dev 函数中只要按照这个次序,设定fdt_offset即可。
sd卡,和emmc只要指定设备树的文件名就可以了。

posted @ 2022-08-05 17:05  不明白就去明白  阅读(1196)  评论(0编辑  收藏  举报