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
使用命令查看分区情况:
可以看到每个分区的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只要指定设备树的文件名就可以了。