20171024_jeffrey - silenceuncrio/diary GitHub Wiki
早上幫女兒報完戶口了
來整理目前 emmc 可開機的 uboot env
printenv
的結果如下
baudrate=115200
boot_fdt=try
bootcmd=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
bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};
bootdelay=3
bootscript=echo Running bootscript from mmc ...; source
console=ttymxc0
ethact=FEC1
ethprime=FEC
fdt_addr=0x83000000
fdt_file=imx6ul-14x14-evk.dtb
fdt_high=0xffffffff
image=zImage
initrd_addr=0x83800000
initrd_high=0xffffffff
ip_dyn=yes
loadaddr=0x80800000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" clk_ignore_unused
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
mmcdev=1
mmcpart=1
mmcroot=/dev/mmcblk1p2 rootwait rw
netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
panel=TFT43AB
script=boot.scr
Environment size: 2059/8188 bytes
=>
來整理一下
從 bootcmd
開始
bootcmd=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
整理成方便看的樣子
bootcmd=
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
分析 mmc dev ${mmcdev};
利用 printenv mmcdev
得到 ${mmcdev}
的值
=> printenv mmcdev
mmcdev=1
所以 mmc dev ${mmcdev};
等同於 mmc dev 1;
mmc dev
指令說明如下
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc dev 1
執行結果如下
=> mmc dev 1
switch to partitions #0, OK
mmc1(part 0) is current device
=>
但不明白為何 bootcmd
一開始就要執行兩次的 mmc dev 1
mmc rescan
沒有什麼說明
不過透過以下的指令可確認 mmc rescan
的執行結果是 true
=> setenv xxx 'if mmc rescan; then echo mmc rescan ok; else echo mmc recan fail; fi'
=> printenv xxx
xxx=if mmc rescan; then echo mmc rescan ok; else echo mmc recan fail; fi
=> run xxx
mmc rescan ok
=>
所以可以再化簡下述的 block
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
變成
if run loadbootscript;
then run bootscript;
else if run loadimage;
then run mmcboot;
else run netboot;
fi;
fi;
檢查 loadbootscript
=> printenv loadbootscript
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
直接來判定一下 run loadbootscript
會怎樣好了
=> setenv yyy 'if run loadbootscript; then echo loadbootscript ok; else echo loadbootscript fail; fi;'
=> run yyy
reading boot.scr
** Unable to read file boot.scr **
loadbootscript fail
繼續化簡
if run loadbootscript;
then run bootscript;
else if run loadimage;
then run mmcboot;
else run netboot;
fi;
fi;
變成
if run loadimage;
then run mmcboot;
else run netboot;
fi;
檢查 loadimage
=> printenv loadimage
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
=>
把需要的變數解開
-
${mmcdev}
= 1 -
${mmcpart}
= 1 -
${loadaddr}
= 0x80800000 -
${image}
= zImage
得到 loadimage
= fatload mmc 1:1 0x80800000 zImage
fatload
說明如下
fatload - load binary file from a dos filesystem
Usage:
fatload <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
- Load binary file 'filename' from 'dev' on 'interface'
to address 'addr' from dos filesystem.
'pos' gives the file position to start loading from.
If 'pos' is omitted, 0 is used. 'pos' requires 'bytes'.
'bytes' gives the size to load. If 'bytes' is 0 or omitted,
the load stops on end of file.
If either 'pos' or 'bytes' are not aligned to
ARCH_DMA_MINALIGN then a misaligned buffer warning will
be printed and performance will suffer for the load.
參考 fatload
的說明來幫 fatload mmc 1:1 0x80800000 zImage
解釋一下
Load binary file
zImage
from1:1
onmmc
to address0x80800000
from dos filesystem.
判定一下 run loadimage
會怎樣好了
=> setenv zzz 'if run loadimage; then echo loadimage ok; else echo loadimage fail; fi;'
=> run zzz
reading zImage
4993904 bytes read in 126 ms (37.8 MiB/s)
loadimage ok
化簡
if run loadimage;
then run mmcboot;
else run netboot;
fi;
變成
run loadimage;
run mmcboot;
檢查 mmcboot
=> printenv mmcboot
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
一樣整理成容易解析的格式
mmcboot=
echo Booting from mmc ...;
run mmcargs;
if test ${boot_fdt} = yes || test ${boot_fdt} = try;
then if run loadfdt;
then bootz ${loadaddr} - ${fdt_addr};
else if test ${boot_fdt} = try;
then bootz; else echo WARN: Cannot load the DT;
fi;
fi;
else bootz;
fi;
檢查 mmcargs
=> printenv mmcargs
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
解開變數
-
${console}
= ttymxc0 -
${baudrate}
= 115200 -
${mmcroot}
= /dev/mmcblk1p2 rootwait rw
得到 mmcargs
= setenv bootargs console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw
解析
if test ${boot_fdt} = yes || test ${boot_fdt} = try;
then if run loadfdt;
then bootz ${loadaddr} - ${fdt_addr};
else if test ${boot_fdt} = try;
then bootz; else echo WARN: Cannot load the DT;
fi;
fi;
else bootz;
fi;
檢查 boot_fdt
=> printenv boot_fdt
boot_fdt=try
可以化簡
if test ${boot_fdt} = yes || test ${boot_fdt} = try;
then if run loadfdt;
then bootz ${loadaddr} - ${fdt_addr};
else if test ${boot_fdt} = try;
then bootz; else echo WARN: Cannot load the DT;
fi;
fi;
else bootz;
fi;
變成
if run loadfdt;
then bootz ${loadaddr} - ${fdt_addr};
else if test ${boot_fdt} = try;
then bootz; else echo WARN: Cannot load the DT;
fi;
fi;
檢查 loadfdt
=> printenv loadfdt
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
解開變數
-
${mmcdev}
= 1 -
${mmcpart}
= 1 -
${fdt_addr}
= 0x83000000 -
${fdt_file}
= 14x14-evk.dtb
得到 loadfdt
= fatload mmc 1:1 0x83000000 14x14-evk.dtb
參考 fatload
的說明來解釋一下
Load binary file
14x14-evk.dtb
from1:1
onmmc
to address0x83000000
from dos filesystem.
可以再化簡
if run loadfdt;
then bootz ${loadaddr} - ${fdt_addr};
else if test ${boot_fdt} = try;
then bootz; else echo WARN: Cannot load the DT;
fi;
fi;
變成
run loadfdt;
bootz ${loadaddr} - ${fdt_addr};
也就是
run loadfdt;
bootz 0x80800000 - 0x83000000;
俐落地從 bootcmd
再開始整理最簡單的樣子
bootcmd=
mmc dev ${mmcdev};
mmc dev ${mmcdev};
mmc rescan;
run loadimage;
run mmcboot;
整理 loadimage
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
整理 mmcboot
mmcboot=
echo Booting from mmc ...;
run mmcargs;
run loadfdt;
bootz ${loadaddr} - ${fdt_addr};
整理 mmcargs
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
整理 loadfdt
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
把 mmcboot
裡 run
的敘述展開得到
整理 mmcboot
mmcboot=
echo Booting from mmc ...;
setenv bootargs console=${console},${baudrate} root=${mmcroot}
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
bootz ${loadaddr} - ${fdt_addr};
再把 bootcmd
裡 run
的敘述展開
bootcmd=
mmc dev ${mmcdev};
mmc dev ${mmcdev};
mmc rescan;
fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
echo Booting from mmc ...;
setenv bootargs console=${console},${baudrate} root=${mmcroot}
fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
bootz ${loadaddr} - ${fdt_addr};
重新整理一下 bootcmd
bootcmd=
mmc dev ${mmcdev};
mmc dev ${mmcdev};
mmc rescan;
setenv bootargs console=${console},${baudrate} root=${mmcroot}
fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
bootz ${loadaddr} - ${fdt_addr};
也就是 emmc 裡的 uboot 做了下述這些事
- mmc dev ${mmcdev};
- mmc dev ${mmcdev};
- mmc rescan;
- setenv bootargs console=${console},${baudrate} root=${mmcroot}
- fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
- fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
- bootz ${loadaddr} - ${fdt_addr};
慶幸的是 uboot 並不用參與 emmc 怎麼切割 partition
dual image 的實作在 uboot 上應該只要控制 mmcroot
和 mmcpart
就可以了
mfgtool 要負責把 emmc 切割成我們要的 partition layout
再來應該都是我們自己軟體應用層面的事了
剛剛跟 ariel 聊一下關於 4GB emmc 的初步 partition 規劃
有以下的幾個結論
- 我們的應用就佔 1GB 就好
- uboot
- kernel
- rootfs
- dual image layout
- 剩下的就切成一整個, format 成 ext3 格式方便後續利用
- user data
就朝這個結論來規劃一下實作面的 layout 吧
一樣先拿 SD 卡搭 隨身碟來做實驗
利用 dd if=/dev/zero of=/dev/sdb bs=1024 count=1
清掉分割表
➜ OS Firmware git:(develop) ✗ cat /proc/partitions
major minor #blocks name
11 0 1048575 sr0
8 0 125829120 sda
8 1 123730944 sda1
8 2 1 sda2
8 5 2095104 sda5
8 16 7761920 sdb
8 17 512000 sdb1
8 18 368640 sdb2
8 19 6713344 sdb3
➜ OS Firmware git:(develop) ✗ sudo dd if=/dev/zero of=/dev/sdb bs=1024 count=1
[sudo] password for jeffrey:
1+0 records in
1+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.157767 s, 6.5 kB/s
➜ OS Firmware git:(develop) ✗ cat /proc/partitions
major minor #blocks name
11 0 1048575 sr0
8 0 125829120 sda
8 1 123730944 sda1
8 2 1 sda2
8 5 2095104 sda5
8 16 7761920 sdb
利用 sfdisk 分割 partition 要突破 4 個 partition 的限制需要一點小技巧
參考 Issues while eMMC partitioned using sfdisk
搭配以下的 mksdcard.sh
#!/bin/sh
# partition size in MB
BOOT_ROM_SIZE=10
# wait for the SD/MMC device node ready
while [ ! -e $1 ]
do
sleep 1
echo “wait for $1 appear”
done
# call sfdisk to create partition table
# destroy the partition table
node=$1
dd if=/dev/zero of=${node} bs=1024 count=1
sfdisk --force ${node} << EOF
${BOOT_ROM_SIZE}M,40M,C
50M,40M,C
90M,,E
100M,400M,L
500M,400M,L
900M,40M,L
940M,40M,L
1G,,L
EOF
我可以成功的把 emmc 分割成以下樣子
Disk /dev/mmcblk1: 3.6 GiB, 3850371072 bytes, 7520256 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x464ae3d5
Device Boot Start End Sectors Size Id Type
/dev/mmcblk1p1 20480 102399 81920 40M c W95 FAT32 (LBA)
/dev/mmcblk1p2 102400 184319 81920 40M c W95 FAT32 (LBA)
/dev/mmcblk1p3 184320 7520255 7335936 3.5G 5 Extended
/dev/mmcblk1p5 204800 1023999 819200 400M 83 Linux
/dev/mmcblk1p6 1024000 1843199 819200 400M 83 Linux
/dev/mmcblk1p7 1843201 1925119 81919 40M 83 Linux
/dev/mmcblk1p8 1925121 2007039 81919 40M 83 Linux
/dev/mmcblk1p9 2097152 7520255 5423104 2.6G 83 Linux