环境:petalinux 2018.3
实现目的:在Petalinux下,qspiflash存储BOOT.bin,EMMC的blk0存储image.ub,blk1存储rootfs。
前提:该文档描述的方式需要开发板支持SD卡启动。即ZYNQ的SDC0接SD卡,SDC1接EMMC。
petalinux-config
->Subsystem AUTO Hardware Setting
-> Advanced bootable images storage settings
-> boot image settings;
选择primary flash,这里是将BOOT.bin设置为从qspi flash启动
->Subsystem AUTO Hardware Setting
->Advanced bootable images storage settings
->kernel image settings;
选择primary sd,实际就是设置image.ub的存放区域。
Subsystem AUTO Hardware Settings ---> SD/SDIO Settings ---> Primary SD/SDIO
从SD卡启动的系统选择:
Primary SD/SDIO (ps7_sd_0)
从eMMC引导的系统选择:
Primary SD/SDIO (ps7_sd_1)
对于从eMMC引导的系统,即便选择了Primary SD/SDIO (psu_sd_1),仍然不能完全启动,需要从文件
/project-spec/meta-plnx-generated/recipes-bsp/u-boot/configs/platform-auto.h
里,复制U-boot环境参数定义部分内容:
#define CONFIG_EXTRA_ENV_SETTINGS 该宏的参数
到文件
/project-spec/meta-user/recipes-bsp/u-boot/files/platform-top.h
中,并将后者全部 “mmcinfo” 修改为 “mmc dev ${sdbootdev}” ,共5处
首先需要明确:
在petalinux配置里看到的parttion0,1,2,3 的字样,其实就是在linux系统里面对应的设备是/dev/mtd0,/dev/mtd1,/dev/mtd2,/dev/mtd3。
格式化EMMC第一个BOOT分区为FAT32,用于存放image.ub。第二个分区为EXT4格式用于存放根文件系统。
切记输入 w保存配置。。。。。。
格式化之前如果之前已经分区过,首先需要umount,然后使用fdisk删除分区(d指令)
mkdosfs -F 32 /dev/mmcblk1p1 格式化为FAT32格式。
mkfs.ext4 /dev/mmcblk1p2 格式化为EXT4格式
格式化第一块分区,为FAT32格式,大小为128MB
root@MZ702P_FEP:~# fdisk /dev/mmcblk1
Device contains neither a valid DOS partition table, nor Sun, SGI, OSF or GPT disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that the previous content
won't be recoverable.
``
``
The number of cylinders for this disk is set to 232448.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
\1) software that runs at boot time (e.g., old versions of LILO)
\2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
``
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-232448, default 1): 1
Last cylinder or +size or +sizeM or +sizeK (1-232448, default 232448): +128M
``
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): l
``
0 Empty 1b Hidden Win95 FAT32 9f BSD/OS
1 FAT12 1c Hidden W95 FAT32 (LBA) a0 Thinkpad hibernation
4 FAT16 <32M 1e Hidden W95 FAT16 (LBA) a5 FreeBSD
5 Extended 3c Part.Magic recovery a6 OpenBSD
6 FAT16 41 PPC PReP Boot a8 Darwin UFS
7 HPFS/NTFS 42 SFS a9 NetBSD
a OS/2 Boot Manager 63 GNU HURD or SysV ab Darwin boot
b Win95 FAT32 80 Old Minix b7 BSDI fs
c Win95 FAT32 (LBA) 81 Minix / old Linux b8 BSDI swap
e Win95 FAT16 (LBA) 82 Linux swap be Solaris boot
f Win95 Ext'd (LBA) 83 Linux eb BeOS fs
11 Hidden FAT12 84 OS/2 hidden C: drive ee EFI GPT
12 Compaq diagnostics 85 Linux extended ef EFI (FAT-12/16/32)
14 Hidden FAT16 <32M 86 NTFS volume set f0 Linux/PA-RISC boot
16 Hidden FAT16 87 NTFS volume set f2 DOS secondary
17 Hidden HPFS/NTFS 8e Linux LVM fd Linux raid autodetect
Hex code (type L to list codes): b
Changed system type of partition 1 to b (Win95 FAT32)
``
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table
mmcblk1: p1
root@MZ702P_FEP:~# mkdosfs -F 32 /dev/mmcblk1p1
root@MZ702P_FEP:~#
root@MZ702P_FEP:~# fdisk /dev/mmcblk1
Device contains neither a valid DOS partition table, nor Sun, SGI, OSF or GPT disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that the previous content
won't be recoverable.
The number of cylinders for this disk is set to 232448.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
\1) software that runs at boot time (e.g., old versions of LILO)
\2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (1-232448, default 1): 回车
Last cylinder or +size or +sizeM or +sizeK (1-232448, default 232448): 回车
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table
mmcblk1: p1
root@MZ702P_FEP:~# mkfs.ext4 /dev/mmcblk1p2
root@MZ702P_FEP:~#
df -h
使用tftp更新
服务器的IP为192.168.0.100
板子的IP为192.168.0.10
tftp 用于把服务器的BOOT.BIN文件传输到嵌入式板子
tftp -r /BOOT.BIN -l ./BOOT.BIN -g 192.168.0.100:69
查看FLASH分区
cat /proc/mtd
我们在linux将文件BOO.bin拷贝到qspi flash的mtd0分区中
擦除flash设备
flash_erase /dev/mtd0 0 0
之后执行flash拷贝命令
flashcp BOOT.bin /dev/mtd0
tftp -r /BOOT.BIN -l ./BOOT.BIN -g 192.168.0.100:69
flash_erase /dev/mtd0
flashcp BOOT.BIN /dev/mtd0
查看系统挂载
root@MZ702P_FEP:~# df -h
Filesystem Size Used Available Use% Mounted on
devtmpfs 491.2M 4.0K 491.2M 0% /dev
tmpfs 503.1M 116.0K 502.9M 0% /run
tmpfs 503.1M 52.0K 503.0M 0% /var/volatile
/dev/mmcblk0p2 14.3G 53.2M 13.5G 0% /run/media/mmcblk0p2
/dev/mmcblk0p1 97.5M 15.1M 82.4M 15% /run/media/mmcblk0p1
/dev/mmcblk1p1 120.2M 3.8M 116.4M 3% /run/media/mmcblk1p1
/dev/mmcblk1p2 6.8G 33.5M 6.4G 1% /run/media/mmcblk1p2
/run/media/mmcblk1p1 目录用于存放image.ub
/run/media/mmcblk1p1 目录用于存放根文件系统
cd /run/media/mmcblk1p1
tftp -r /image.ub -l ./image.ub -g 192.168.0.100:69
cd /run/media/mmcblk1p2
tftp -r /rootfs.tar.gz -l ./rootfs.tar.gz -g 192.168.0.100:69
tar -zxvpf rootfs.tar.gz
rm -rf rootfs.tar.gz
petalinux默认配置的文件系统不支持mkfs.ext4指令。
新增命令
petalinux没有配置busybox的命令,但是可以通过
petalinux-config -c rootfs
来配置系统下的内嵌命令。
新增mkfs.ext4命令
petalinux-config -c rootfs
-> Filesystem Packages
-> base
-> e2fsprogs
enable e2fsprogs
enable e2fsprogs-mke2fs
问题描述
petalinux2018.3中会有一个这样的bug(实际上之前也存在,官方修复还是有漏洞),当像我们这样SD0接入SD卡,SD1接入eMMC时,当SD卡没有插入时启动,尽管配置petalinux的主sd为ps7_sd_1,但是其uboot启动时会报错找不到mmc 0。
当同时激活 SD0 (对应SD卡座) 和 SD1 (对应板载 emmc) 时,当从 emmc 启动,报如下错误,
U-Boot 2018.01 (Mar 25 2022 - 14:08:43 +0000) Xilinx Zynq ZC702
Board: Xilinx Zynq
Silicon: v3.1
I2C: ready
DRAM: ECC disabled 1 GiB
MMC: Card did not respond to voltage select!
mmc_init: -95, time 22
mmc@e0100000 - probe failed: -95
sdhci_transfer_data: Error detected in status(0x208000)!
Card did not respond to voltage select!
mmc_init: -95, time 23
SF: Detected n25q128 with page size 256 Bytes, erase size 64 KiB, total 16 MiB
*** Warning - bad CRC, using default environment
In: serial@e0001000
Out: serial@e0001000
Err: serial@e0001000
Board: Xilinx Zynq
Silicon: v3.1
Net: ZYNQ GEM: e000b000, phyaddr 0, interface rgmii-id
Warning: ethernet@e000b000 (eth4) using random MAC address - 8e:05:c1:a3:31:86
eth4: ethernet@e000b000
U-BOOT for MZ702P_FEP
Hit any key to stop autoboot: 0
Card did not respond to voltage select!
mmc_init: -95, time 24
** Bad device mmc 0 **
no mmc device at slot 0
Zynq>
Zynq>
解决方法
配置 Primary SD 为 SD1 后,对应的更改没有更新到 u-boot 中去。
打开
/project-spec/meta-plnx-generated/recipes-bsp/u-boot/configs
下的文件platform-auto.h,有如下宏,
/* BOOTCOMMAND */
\#define CONFIG_BOOTCOMMAND "run default_bootcmd"
\#endif /* __PLNX_CONFIG_H */
打开
**/project-spec/meta-user/recipes-bsp/u-boot/files**
下的文件platform-top.h,添加如下内容 (对上述宏作一个重置),
/*************************************************************************************************************************************/
/* fix SD0 is sd card, SD1 is emmc, if no card insert into SD0 slot, zynq cannot detect SD1 emmc. (Vivado 2018.2 + Petalinux 2018.2) */
/*************************************************************************************************************************************/
\#ifdef CONFIG_BOOTCOMMAND
\#undef CONFIG_BOOTCOMMAND
\#define CONFIG_BOOTCOMMAND "mmc dev ${sdbootdev}; run default_bootcmd"
\#endif
/*************************************************************************************************************************************/
并把下面的内容拷贝到
**/project-spec/meta-user/recipes-bsp/u-boot/files/platform-top.h**
该文件中。
要拷贝的内容
/* Extra U-Boot Env settings */
\#define CONFIG_EXTRA_ENV_SETTINGS \
SERIAL_MULTI \
CONSOLE_ARG \
DFU_ALT_INFO_RAM \
DFU_ALT_INFO_MMC \
PSSERIAL0 \
"nc=setenv stdout nc;setenv stdin nc;\0" \
"ethaddr=00:0a:35:00:1e:53\0" \
"bootenv=uEnv.txt\0" \
"importbootenv=echo \"Importing environment from SD ...\"; " \
"env import -t ${loadbootenv_addr} $filesize\0" \
"loadbootenv=load mmc $sdbootdev:$partid ${loadbootenv_addr} ${bootenv}\0" \
"sd_uEnvtxt_existence_test=test -e mmc $sdbootdev:$partid /uEnv.txt\0" \
"uenvboot=" \
"if run sd_uEnvtxt_existence_test; then " \
"run loadbootenv; " \
"echo Loaded environment from ${bootenv}; " \
"run importbootenv; " \
"fi; " \
"if test -n $uenvcmd; then " \
"echo Running uenvcmd ...; " \
"run uenvcmd; " \
"fi\0" \
"autoload=no\0" \
"sdbootdev=1\0" \
"clobstart=0x10000000\0" \
"netstart=0x10000000\0" \
"dtbnetstart=0x23fff000\0" \
"loadaddr=0x10000000\0" \
"bootsize=0x500000\0" \
"bootstart=0x0\0" \
"boot_img=BOOT.BIN\0" \
"load_boot=tftpboot ${clobstart} ${boot_img}\0" \
"update_boot=setenv img boot; setenv psize ${bootsize}; setenv installcmd \"install_boot\"; run load_boot test_img; setenv img; setenv psize; setenv installcmd\0" \
"sd_update_boot=echo Updating boot from SD; mmc dev ${sdbootdev} && fatload mmc ${sdbootdev}:1 ${clobstart} ${boot_img} && run install_boot\0" \
"install_boot=sf probe 0 && sf erase ${bootstart} ${bootsize} && " \
"sf write ${clobstart} ${bootstart} ${filesize}\0" \
"bootenvsize=0x20000\0" \
"bootenvstart=0x500000\0" \
"eraseenv=sf probe 0 && sf erase ${bootenvstart} ${bootenvsize}\0" \
"jffs2_img=rootfs.jffs2\0" \
"load_jffs2=tftpboot ${clobstart} ${jffs2_img}\0" \
"update_jffs2=setenv img jffs2; setenv psize ${jffs2size}; setenv installcmd \"install_jffs2\"; run load_jffs2 test_img; setenv img; setenv psize; setenv installcmd\0" \
"sd_update_jffs2=echo Updating jffs2 from SD; mmc dev ${sdbootdev} && fatload mmc ${sdbootdev}:1 ${clobstart} ${jffs2_img} && run install_jffs2\0" \
"install_jffs2=sf probe 0 && sf erase ${jffs2start} ${jffs2size} && " \
"sf write ${clobstart} ${jffs2start} ${filesize}\0" \
"kernel_img=image.ub\0" \
"load_kernel=tftpboot ${clobstart} ${kernel_img}\0" \
"update_kernel=setenv img kernel; setenv psize ${kernelsize}; setenv installcmd \"install_kernel\"; run load_kernel ${installcmd}; setenv img; setenv psize; setenv installcmd\0" \
"install_kernel=mmc dev ${sdbootdev} && fatwrite mmc ${sdbootdev} ${clobstart} ${kernel_img} ${filesize}\0" \
"cp_kernel2ram=mmc dev ${sdbootdev} && fatload mmc ${sdbootdev} ${netstart} ${kernel_img}\0" \
"dtb_img=system.dtb\0" \
"load_dtb=tftpboot ${clobstart} ${dtb_img}\0" \
"update_dtb=setenv img dtb; setenv psize ${dtbsize}; setenv installcmd \"install_dtb\"; run load_dtb test_img; setenv img; setenv psize; setenv installcmd\0" \
"sd_update_dtb=echo Updating dtb from SD; mmc dev ${sdbootdev} && fatload mmc ${sdbootdev}:1 ${clobstart} ${dtb_img} && run install_dtb\0" \
"loadbootenv_addr=0x00100000\0" \
"fault=echo ${img} image size is greater than allocated place - partition ${img} is NOT UPDATED\0" \
"test_crc=if imi ${clobstart}; then run test_img; else echo ${img} Bad CRC - ${img} is NOT UPDATED; fi\0" \
"test_img=setenv var \"if test ${filesize} -gt ${psize}\\; then run fault\\; else run ${installcmd}\\; fi\"; run var; setenv var\0" \
"netboot=tftpboot ${netstart} ${kernel_img} && bootm\0" \
"default_bootcmd=run uenvboot; run cp_kernel2ram && bootm ${netstart}\0" \
""
重新编译工程即可。
" \
“sd_update_dtb=echo Updating dtb from SD; mmc dev ${sdbootdev} && fatload mmc ${sdbootdev}:1 ${clobstart} ${dtb_img} && run install_dtb\0” \
“loadbootenv_addr=0x00100000\0” \
“fault=echo ${img} image size is greater than allocated place - partition ${img} is NOT UPDATED\0” \
“test_crc=if imi ${clobstart}; then run test_img; else echo ${img} Bad CRC - ${img} is NOT UPDATED; fi\0” \
“test_img=setenv var “if test ${filesize} -gt ${psize}\; then run fault\; else run ${installcmd}\; fi”; run var; setenv var\0” \
“netboot=tftpboot ${netstart} ${kernel_img} && bootm\0” \
“default_bootcmd=run uenvboot; run cp_kernel2ram && bootm ${netstart}\0” \
“”
重新编译工程即可。