orangepi制作sd卡啟動(dòng)鏡像,并通過uenv加入動(dòng)態(tài)更新uboot和內(nèi)核功能

目錄結(jié)構(gòu)說明

一、基礎(chǔ)說明

1、環(huán)境介紹

2、啟動(dòng)過程

3、相關(guān)地址布局

二、配置uboot支持uenv啟動(dòng)

1、修改menuconfig

2、編譯uboot并準(zhǔn)備文件

三、設(shè)置env.txt文件

0、了解bootcmd命令參數(shù)

1、mmc啟動(dòng)參數(shù)

2、設(shè)置tftp啟動(dòng)參數(shù)

3、設(shè)置tftp啟動(dòng)引導(dǎo)nfs參數(shù)

4、設(shè)置tftp更新uboot、kernel參數(shù)

5、設(shè)置uart串口更新uboot、kernel參數(shù)

6、整合成env.txt

四、制作SD卡img

1、準(zhǔn)備文件

2、制作Fat分區(qū)img

3、制作Ext4分區(qū)img

4、制作uboot、spl和分區(qū)表鏡像頭

5、整合成腳本




一、基礎(chǔ)說明

1、環(huán)境介紹

?? 首先這里我們需要安裝一些基礎(chǔ)的編譯環(huán)境,安裝tftp服務(wù)器,安裝nfs服務(wù)器等,這里我們可以參考文章《orangpione利用usb共享網(wǎng)絡(luò)(RNDIS)實(shí)現(xiàn)tftp加載內(nèi)核掛載到NFS根文件系統(tǒng)》中的環(huán)境準(zhǔn)備章節(jié),自行安裝相關(guān)服務(wù),在這里不展開。后續(xù)的開發(fā)是基于tftp和nfs傳輸?shù)臈l件下進(jìn)行。

2、啟動(dòng)過程

?? 這里對(duì)應(yīng)大多數(shù)的嵌入式linux系統(tǒng)的啟動(dòng)過程都是相似的。首先在開機(jī)后,片上的soc會(huì)把在存儲(chǔ)設(shè)置中的SPL文件加載到RAM;然后SPL再加載存儲(chǔ)設(shè)備中的BootLoader到RAM中,再由BootLoader加載Kernel到RAM中,最后由Kernel接管控制權(quán),并掛載根文件系統(tǒng),成功啟動(dòng)系統(tǒng)。其中有些還會(huì)使用initram,其實(shí)也是相當(dāng)于內(nèi)核接管控制權(quán)后,再把控制權(quán)移交給新的內(nèi)核。

3、相關(guān)地址布局

??我們這里使用的orangpinone作為例子對(duì)相關(guān)的地址布局進(jìn)行相應(yīng)的描述,其中官網(wǎng)給出了一個(gè)相應(yīng)的http://www.orangepi.org/Docs/Settingup.html,如下圖所示。個(gè)人感覺,這個(gè)分區(qū)布局更適合spiflash的布局。


??我這里使用的分區(qū)表信息如下

1、前面的8k空間沒有用,主要是預(yù)留給分區(qū)表用的
2、從8k開始的放了SPL,就是開機(jī)之后會(huì)被首先運(yùn)行的文件
3、從40k開始放uboot-dtb,編譯出來的uboot和dtb合并的固件。
4、從1M之后建立一個(gè)10M的Fat分區(qū),主要是為了方便在windons和linux上進(jìn)行修改,因?yàn)檫@個(gè)分區(qū)主要放的文件是env.txt、zImage和dtb文件,即這里主要放的都是啟動(dòng)時(shí)需要的env變量或者內(nèi)核和內(nèi)核設(shè)備樹文件。
5、最后再建立一個(gè)ext4格式的根文件系統(tǒng)。

二、配置uboot支持uenv啟動(dòng)

??這里我們假設(shè)kernel、uboot和rootfs都已經(jīng)編譯過了

1、修改menuconfig

??要使uboot支持uenv參數(shù)配置,我們只需要通過修改uboot啟動(dòng)的命令行即可。
??基本思路是,uboot啟動(dòng)后,從mmc中加載env.txt文件到RAM中,在通過env import指令把env.txt的參數(shù)設(shè)置為uboot的環(huán)境參數(shù),最后通過env.txt參數(shù)中的uenvboot啟動(dòng)命令開始加載內(nèi)核。

  1. 通過fatload mmc 0 $kernel_addr_r env.txt;加載env.txt到內(nèi)存中,
  2. 通過env import -t $kernel_addr_r $filesize;把內(nèi)存中的env.txt設(shè)置為uboot的環(huán)境參數(shù)。
  3. 最后通過run uenvboot;開始加載內(nèi)核
  4. 當(dāng)加載出錯(cuò)的時(shí)候run distro_bootcmd;會(huì)被執(zhí)行,則會(huì)按照默認(rèn)的啟動(dòng)順序啟動(dòng)
    主要配置為:
    CONFIG_USE_BOOTCOMMAND=y
    CONFIG_BOOTCOMMAND="fatload mmc 0 $kernel_addr_r env.txt; env import -t $kernel_addr_r $filesize; run uenvboot; run distro_bootcmd;"

2、編譯uboot并準(zhǔn)備文件

  1. 通過make重新編譯uboot
  2. 準(zhǔn)備好文件,env.txt、u-boot-dtb.bin、sunxi-spl.bin、zImage、sun8i-h3-orangepi-one.dtb和根文件系統(tǒng)
u-boot-dtb.bin 在uboot編譯目錄下ubootbuild/u-boot-dtb.bin
sunxi-spl.bin 在uboot編譯目錄下ubootbuild/spl/sunxi-spl.bin
zImage 在kernel編譯目錄下linuxbuild/arch/arm/boot/zImage
sun8i-h3-orangepi-one.dtb 在kernel編譯目錄下linuxbuild/arch/arm/boot/dts/sun8i-h3-orangepi-one.dtb
env.txt 文件我們下一章節(jié)介紹

三、設(shè)置env.txt文件

0、了解bootcmd命令參數(shù)

??是uboot在啟動(dòng)后,需要執(zhí)行的命令,一般可以固化到uboot編譯中去,也可以在uboot終端輸入執(zhí)行,也能通過env.txt等參數(shù)設(shè)置文件傳入給uboot執(zhí)行。其中通過uEnv的執(zhí)行方式最為靈活,可以在不重新編譯的情況下直接修改設(shè)置參數(shù),且只要env.txt的配置參數(shù)在相應(yīng)分區(qū)中可以找到,就可以有uboot啟動(dòng)后自動(dòng)執(zhí)行。
??具體的代碼定義可以在uboot源碼目錄下的include/config_distro_bootcmd.h文件中找到,里面定義了各種各樣的啟動(dòng)參數(shù)配置,理論上說不管是從mmc啟動(dòng)還是flash啟動(dòng),其配置的原理大致相同,不同的是SPL在引導(dǎo)uboot是產(chǎn)生的區(qū)別,已經(jīng)不同環(huán)境的配置參數(shù)不同罷了。從config_distro_bootcmd.h文件中,不難發(fā)現(xiàn),在include/configs/sunxi-common.h代碼中已經(jīng)固定定義好了幾個(gè)參數(shù)變量,這個(gè)我們后續(xù)可以直接在env.txt中使用。比如kernel_addr_r、fdt_addr_r、filesize等,這里filesize需要特別強(qiáng)調(diào)一下,filesize是會(huì)返回前面一次操作返回的文件大小的值,在我們后續(xù)的env.txt中很有用。

1、mmc啟動(dòng)參數(shù)

在uboot終端輸入

  1. 通過命令fatload mmc 0:1 zImage $kernel_addr_h從Fat格式分區(qū)加載zImage 內(nèi)存內(nèi)核中
  2. 通過命令fatload mmc 0:1 sun8i-h3-orangepi-one.dtb $fdt_addr_r從Fat格式分區(qū)加載sun8i-h3-orangepi-one.dtb內(nèi)存設(shè)備樹中
  3. 通過命令setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw設(shè)置啟動(dòng)之后的根文件系統(tǒng)為mmc的第2個(gè)分區(qū)(也就是我們的ext4分區(qū))
  4. 通過命令bootz $kernel_addr_h - $fdt_addr_r啟動(dòng)內(nèi)核
    最后把整個(gè)mmc的啟動(dòng),當(dāng)執(zhí)行run boottommc是即可從mmc啟動(dòng)根文件系統(tǒng)。
    參數(shù)化到env.txt中有
mmcbootarg=setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw
mmcbootenv=fatload ${devname} ${devnum} $kernel_addr_r ${imagename}; fatload ${devname} ${devnum} $fdt_addr_r ${dtbna    me};
boottommc=run mmcbootenv; bootz $kernel_addr_r - $fdt_addr_r;

2、設(shè)置tftp啟動(dòng)參數(shù)

在uboot終端輸入(相關(guān)ip設(shè)置參考之前的文章)

  1. 通過命令usb start;啟動(dòng)usb功能
  2. 通過命令setenv ethact usb_ether;設(shè)置usb網(wǎng)卡為第一網(wǎng)卡
  3. 通過命令setenv ipaddr 192.168.137.2;設(shè)置開發(fā)板ip
  4. 通過命令setenv netmask 255.255.255.0;設(shè)置開發(fā)板掩碼
  5. 通過命令setenv gatewayip 192.168.137.1;設(shè)置網(wǎng)關(guān)ip
  6. 通過命令setenv serverip 10.8.24.111;設(shè)置服務(wù)器地址
  7. 通過命令tftp $kernel_addr_r zImage;加載zImage到內(nèi)存中
  8. 通過命令tftp $fdt_addr_r sun8i-h3-orangepi-one.dtb 從Fat格式分區(qū)加載sun8i-h3-orangepi-one.dtb內(nèi)存設(shè)備樹中
  9. 通過命令setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw設(shè)置啟動(dòng)之后的根文件系統(tǒng)為mmc的第2個(gè)分區(qū)(也就是我們的ext4分區(qū))
  10. 通過命令bootz $kernel_addr_h - $fdt_addr_r啟動(dòng)內(nèi)核
    參數(shù)化到env.txt中有
pcip=192.168.1.111
boardip=192.168.137.2
boardgw=192.168.137.1
boardmask=255.255.255.0
tftpenv=usb start; setenv ethact usb_ether; setenv ipaddr ${boardip}; setenv gatewayip ${boardgw}; setenv netmask ${boardmask}; setenv serverip ${pcip};
tftpgetimage=tftp $kernel_addr_r ${imagename}; tftp $fdt_addr_r ${dtbname};
mmcbootarg=setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw
tftpboottommc=run tftpenv; run tftpgetimage; run mmcbootarg; bootz $kernel_addr_r - $fdt_addr_r;

3、設(shè)置tftp啟動(dòng)引導(dǎo)nfs參數(shù)

在uboot終端輸入(相關(guān)nfs設(shè)置參考之前的文章)

  1. ip設(shè)置部分參照“設(shè)置tftp啟動(dòng)參數(shù)”的1~6步
  2. 通過命令setenv bootargs "root=/dev/nfs rw rootpath=/home/vencol/code/nfs nfsroot=192.168.1.111:/home/vencol/code/nfs,nolock ip=192.168.137.2:192.168.1.111:192.168.137.1:255.255.255.0 console=${console} nfsvers=2"設(shè)置nfs啟動(dòng)根文件系統(tǒng)
  3. 通過命令tftp $kernel_addr_r zImage;加載zImage到內(nèi)存中
  4. 通過命令tftp $fdt_addr_r sun8i-h3-orangepi-one.dtb從Fat格式分區(qū)加載sun8i-h3-orangepi-one.dtb內(nèi)存設(shè)備樹中
  5. 通過命令setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw設(shè)置啟動(dòng)之后的根文件系統(tǒng)為mmc的第2個(gè)分區(qū)(也就是我們的ext4分區(qū))
  6. 通過命令bootz $kernel_addr_h - $fdt_addr_r啟動(dòng)內(nèi)核
    參數(shù)化到env.txt中有
pcip=192.168.1.111
boardip=192.168.137.2
boardgw=192.168.137.1
boardmask=255.255.255.0
nfspath=/home/vencol/code/nfs
tftpenv=usb start; setenv ethact usb_ether; setenv ipaddr ${boardip}; setenv gatewayip ${boardgw}; setenv netmask ${boardmask}; setenv serverip ${pcip};
nfsbootarg=setenv bootargs root=/dev/nfs rw rootpath=${nfspath} nfsroot=${pcip}:${nfspath},nolock ip=${boardip}:${pcip}:${boardgw}:${boardmask} console=ttyS0,115200 nfsvers=2
tftpgetimage=tftp $kernel_addr_r ${imagename}; tftp $fdt_addr_r ${dtbname};
tftpboottonfs=run tftpenv; run tftpgetimage;  run nfsbootarg;  run tftpgetimage; bootz $kernel_addr_r - $fdt_addr_r;

4、設(shè)置tftp更新uboot、kernel參數(shù)

以更新uboot和更新kernel為例子,在uboot終端輸入(這里我們選擇kernel的內(nèi)存地址作為暫存地址,因?yàn)楹罄m(xù)kernel更新會(huì)覆蓋

  1. ip設(shè)置部分參照“設(shè)置tftp啟動(dòng)參數(shù)”的1~6步
  2. 通命命令tftp $kernel_addr_r u-boot-dtb.bin;加載u-boot-dtb.bin到內(nèi)存中
  3. 通過命令fatwrite mmc 0:1 $kernel_addr_r 50 3E8更新uboot(0x50 X 512 = 40K, 0x3E8 X 512 = 500K,默認(rèn)uboot最多500k,可以適當(dāng)修改小于1M-40K就行
  4. 通過命令tftp $kernel_addr_r zImage;加載zImage到內(nèi)存中
  5. 通過命令fatwrite mmc 0:1 $kernel_addr_r zImage ${filesize};更新mmc中的內(nèi)核
    參數(shù)化到env.txt中有
devname=mmc
devnum=0
bootpart=1
saveenvname=uboot.env
envname=env.txt
splname=sunxi-spl.bin
bootname=u-boot-dtb.bin
imagename=zImage
dtbname=sun8i-h3-orangepi-one.dtb
bytftpupspl=tftp $kernel_addr_r ${splname}; ${devname} write $kernel_addr_r 10 40;
bytftpupuboot=tftp $kernel_addr_r ${bootname};${devname} write $kernel_addr_r 50 3E8;
bytftpupenv=tftp $kernel_addr_r ${envname};fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${envname} ${filesize};
bytftpupdtb=tftp $kernel_addr_r ${dtbname};fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${dtbname} ${filesize};
bytftpupimg=tftp $kernel_addr_r ${imagename};fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${imagename} ${filesize};

5、設(shè)置uart串口更新uboot、kernel參數(shù)

以更新uboot和更新kernel為例子,PC使用SecureCRT通過Ymoden協(xié)議傳輸,在uboot終端輸入

  1. 通過命令loady $kernel_addr_r;
  2. 在PC的SecureCRT選擇發(fā)送Ymoden,并選中u-boot-dtb.bin文件,開始傳輸
  3. 傳輸完成后,通過命令fatwrite mmc 0:1 $kernel_addr_r 50 3E8更新uboot(0x50 X 512 = 40K, 0x3E8 X 512 = 500K,默認(rèn)uboot最多500k,可以適當(dāng)修改小于1M-40K就行
  4. 通過命令loady $kernel_addr_r;
  5. 在PC的SecureCRT選擇發(fā)送Ymoden,并選中zImage文件,開始傳輸
  6. 傳輸完成后,通過命令fatwrite mmc 0:1 $kernel_addr_r zImage ${filesize};更新mmc中的內(nèi)核
    參數(shù)化到env.txt中有
devname=mmc
devnum=0
bootpart=1
saveenvname=uboot.env
envname=env.txt
splname=sunxi-spl.bin
bootname=u-boot-dtb.bin
imagename=zImage
dtbname=sun8i-h3-orangepi-one.dtb
byuartupspl=loady $kernel_addr_r; ${devname} write $kernel_addr_r 10 40;
byuartupuboot=loady $kernel_addr_r; ${devname} write $kernel_addr_r 50 3E8;
byuartupenv=loady $kernel_addr_r; fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${envname} ${filesize};
byuartupdtb=loady $kernel_addr_r; fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${dtbname} ${filesize};
byuartupimg=loady $kernel_addr_r; fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${imagename} ${filesize};

6、整合成env.txt

devname=mmc
devnum=0
bootpart=1
saveenvname=uboot.env
envname=env.txt
splname=sunxi-spl.bin
bootname=u-boot-dtb.bin
imagename=zImage
dtbname=sun8i-h3-orangepi-one.dtb
#tftp boot param
pcip=192.168.1.111
boardip=192.168.137.2
boardgw=192.168.137.1
boardmask=255.255.255.0
nfspath=/home/vencol/code/nfs

#mmc boot param
mmcbootarg=setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw
mmcbootenv=fatload ${devname} ${devnum} $kernel_addr_r ${imagename}; fatload ${devname} ${devnum} $fdt_addr_r ${dtbname};
boottommc=run mmcbootenv; bootz $kernel_addr_r - $fdt_addr_r;

#tftp and nfs
tftpenv=usb start; setenv ethact usb_ether; setenv ipaddr ${boardip}; setenv gatewayip ${boardgw}; setenv netmask ${boardmask}; setenv serverip ${pcip};
nfsbootarg=setenv bootargs root=/dev/nfs rw rootpath=${nfspath} nfsroot=${pcip}:${nfspath},nolock ip=${boardip}:${pcip}:${boardgw}:${boardmask} console=ttyS0,115200 nfsvers=2
tftpgetimage=tftp $kernel_addr_r ${imagename}; tftp $fdt_addr_r ${dtbname};

#set uart update env ymoden
byuartupspl=loady $kernel_addr_r; ${devname} write $kernel_addr_r 10 40;
byuartupuboot=loady $kernel_addr_r; ${devname} write $kernel_addr_r 50 3E8;
byuartupenv=loady $kernel_addr_r; fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${envname} ${filesize};
byuartupdtb=loady $kernel_addr_r; fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${dtbname} ${filesize};
byuartupimg=loady $kernel_addr_r; fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${imagename} ${filesize};

#set tftp update env
bytftpupspl=tftp $kernel_addr_r ${splname}; ${devname} write $kernel_addr_r 10 40;
bytftpupuboot=tftp $kernel_addr_r ${bootname};${devname} write $kernel_addr_r 50 3E8;
bytftpupenv=tftp $kernel_addr_r ${envname};fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${envname} ${filesize};
bytftpupdtb=tftp $kernel_addr_r ${dtbname};fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${dtbname} ${filesize};
bytftpupimg=tftp $kernel_addr_r ${imagename};fatwrite ${devname} ${devnum}:${bootpart} $kernel_addr_r ${imagename} ${filesize};
#updatebytftp=run updatespl; run updateenv; run updatedtb; run updateimg; run updateuboot;

#set define env
debugprint=echo "saveip ${serverip} setip ${pcip}";
cleanenv=setenv rmenv "env default -a; fatrm ${devname} ${devnum}:${bootpart} ${saveenvname};"
savedefenv=run cleanenv; run tftpenv; run mmcbootarg; saveenv;
saveenvfirst=if test "${serverip}_IP" = "${pcip}_IP"; then run debugprint; else run savedefenv; fi;

#boot selection
boottommc=run saveenvfirst; bootz $kernel_addr_r - $fdt_addr_r;
tftpboottommc=run saveenvfirst; run tftpgetimage; bootz $kernel_addr_r - $fdt_addr_r;
tftpboottonfs=run saveenvfirst; run nfsbootarg;  run tftpgetimage; bootz $kernel_addr_r - $fdt_addr_r;

#select boot
uenvboot=run tftpboottonfs;
#uenvboot=run boottommc;
#uenvboot=run tftpboottommc;

#must have the last line

四、制作SD卡img

1、準(zhǔn)備文件

??按照分區(qū)信息表,我們這里需要的文件有:sunxi-spl.bin、u-boot-dtb.bin、env.txt、zImage、sun8i-h3-orangepi-one.dtb和根文件系統(tǒng)rootfs


2、制作Fat分區(qū)img

  1. dd if=/dev/zero of=img1 bs=1M count=10> /dev/null 2>&1生成一個(gè) 10M的img1鏡像文件
  2. sudo mkfs -t vfat -F 32 -n BOOT img1 > /dev/null 2>&1格式化img1為Fat32格式,命名為BOOT
  3. sudo mount img1 bootdir;掛載img1鏡像到bootdir目錄下
  4. 拷貝env.txt、zImage、sun8i-h3-orangepi-one.dtb到bootdir目錄下
  5. sudo umount bootdir;卸載img1鏡像

3、制作Ext4分區(qū)img

  1. dd if=/dev/zero of=img2 bs=1M count=10> /dev/null 2>&1生成一個(gè) 10M的img2鏡像文件
  2. sudo mkfs -F -t ext4 -L ROOTFS img2 > /dev/null 2>&1格式化img2為Ext4格式,命名為ROOTFS
  3. sudo mount img2 linuxdir;掛載img2鏡像到linuxdir目錄下
  4. sudo cp -rfa rootfs/* linuxdir > /dev/null 2>&1拷貝rootfs下所有文件到linuxdir目錄下
  5. sudo umount linuxdir ;卸載img2鏡像

4、制作uboot、spl和分區(qū)表鏡像頭

  1. dd if=/dev/zero of=img1 bs=1M count=30> /dev/null 2>&1生成一個(gè) 30M的img鏡像文件
  2. dd if=sunxi-spl.bin of=img seek=8 conv=notrunc bs=1k > /dev/null 2>&1把sunxi-spl.bin復(fù)制到img鏡像8K之后
  3. dd if=u-boot-dtb.bin of=img seek=1 conv=notrunc bs=40k > /dev/null 2>&1把u-boot-dtb.bin復(fù)制到img鏡像40K之后
  4. echo -e "n\np\n1\n2048\n+10M\nn\np\n2\n \n+10M\nt\n1\nc\na\n2\nw\n" | sudo fdisk ${SDIMG} > /dev/null 2 >&1通過fdisk工具創(chuàng)建10M的fat和10M的ext4分區(qū)
  5. dd if=img of=imgt bs=512 count=2048 > /dev/null 2>&1把img的頭1M備份到imgt鏡像中
  6. dd if=imgt of=img bs=512 count=2048 > /dev/null 2>&1把imgt信息復(fù)制到img中
  7. dd if=img1 of=img bs=1M conv=notrunc oflag=append > /dev/null 2>&1把img1信息拼接到img中
  8. dd if=img2 of=img bs=1M conv=notrunc oflag=append > /dev/null 2>&1把img2信息拼接到img中

5、整合成腳本

#! /bin/bash
JOBNUM=4
NPWD=`realpath .`
CODETOP=`realpath ../../`
export ARCH=arm
export CROSS_COMPILE=$CODETOP/gcc/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
CONFIG_BOARD="OPIONE"
#CONFIG_BOARD="BBB"


mkdir -p images
cd images
mkdir -p bootfile
mkdir -p bootdir
mkdir -p linuxdir
echo $PWD
SDIMG="sd.img"
BOOTPARTSIZE=10
FSPARTSIZE=10
if [ $BOOTPARTSIZE -lt 10 ];then
        echo "boot part size must larget than 10M"
        exit 1
fi
if [ $FSPARTSIZE -lt 10 ];then
        echo "rootfs part size must larget than 10M"
        exit 1
fi

#boot partion
dd if=/dev/zero of=${SDIMG}1 bs=1M count=$BOOTPARTSIZE > /dev/null 2>&1
echo "Formating fat partition for boot..."
sudo mkfs -t vfat -F 32 -n BOOT ${SDIMG}1 > /dev/null 2>&1
if [ $? -ne 0 ]; then
        echo "ERROR formating fat boot partition."
        exit 0
fi
vfatuuid=`sudo blkid -s UUID -o value ${SDIMG}1`
echo "  fat boot partition formated."
if ! sudo mount ${SDIMG}1 bootdir; then
        echo "ERROR mounting fat boot partitions..."
        exit 1
fi
if [ "${CONFIG_BOARD}_x" == "BBB_x" ];then
        sudo cp -rf $NPWD/ubootbuild/MLO $NPWD/images/bootdir/
        sudo cp -rf $NPWD/ubootbuild/u-boot.img $NPWD/images/bootdir/
        sudo cp -rf $NPWD/linuxbuild/arch/arm/boot/zImage $NPWD/images/bootdir/
        sudo cp -rf $NPWD/linuxbuild/arch/arm/boot/dts/am335x-boneblack.dtb $NPWD/images/bootdir/
        sudo cp -rf $NPWD/ubootbuild/MLO $NPWD/images/bootfile/
        sudo cp -rf $NPWD/ubootbuild/u-boot.img $NPWD/images/bootfile/
elif [ "${CONFIG_BOARD}_x" == "OPIONE_x" ];then
        sudo cp -rf $NPWD/linuxbuild/arch/arm/boot/zImage $NPWD/images/bootdir/
        sudo cp -rf $NPWD/linuxbuild/arch/arm/boot/dts/sun8i-h3-orangepi-one.dtb $NPWD/images/bootdir/
elif [ "${CONFIG_BOARD}_x" == "OPIWIN_x" ];then
        sudo cp -rf $NPWD/linuxbuild/arch/arm64/boot/Image $NPWD/images/bootdir/
        sudo cp -rf $NPWD/linuxbuild/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dtb $NPWD/images/bootdir/
fi
sudo cp -rf $NPWD/env.txt $NPWD/images/bootdir/
sync
if ! sudo umount bootdir; then
        echo "ERROR unmounting fat boot partition."
fi

#rootfs partion
dd if=/dev/zero of=${SDIMG}2 bs=1M count=$FSPARTSIZE > /dev/null 2>&1
echo "Formating rootfs linux partition ..."
sudo mkfs -F -t ext4 -L ROOTFS ${SDIMG}2 > /dev/null 2>&1
#sudo mkfs -F -t ext4 -b 4096 -E stride=2,stripe-width=1024  -L ROOTFS ${SDIMG}2 > /dev/null 2>&1
if [ $? -ne 0 ]; then
        echo "ERROR formating rootfs linux partition."
        exit 0
fi
vfatuuid=`sudo blkid -s UUID -o value ${SDIMG}2`
echo "  rootfs linux partition formated."
if ! sudo mount ${SDIMG}2 linuxdir; then
        echo "ERROR mounting rootfs linux partitions..."
        exit 1
fi
sudo rm -rf $NPWD/rootfs/root/*
sudo cp -rf $NPWD/env.txt $NPWD/rootfs/root
sudo cp -rfa $NPWD/rootfs/* linuxdir > /dev/null 2>&1
#sudo rsync -r -t -p -o -g -x --delete -l -H -D --numeric-ids -s --stats $NPWD/rootfs/ linuxdir > /dev/null 2>&1
sync
if ! sudo umount linuxdir; then
        echo "ERROR unmounting rootfs linux partitions."
fi



#create img to burn
TABLESIZE=2048
FATSIZE=+${BOOTPARTSIZE}M
EXTSIZE=+${FSPARTSIZE}M
TOTALSIZE=$(expr ${BOOTPARTSIZE} + ${FSPARTSIZE} + 2)
dd if=/dev/zero of=${SDIMG} bs=1M count=$TOTALSIZE > /dev/null 2>&1


#cp SPL and bootloade to sd
echo "create partition table"
if [ "${CONFIG_BOARD}_x" == "BBB_x" ];then
#beaglebonblack first part
        dd if=$NPWD/images/bootfile/MLO of=${SDIMG} count=1 seek=1 conv=notrunc bs=128k > /dev/null 2>&1
        dd if=$NPWD/images/bootfile/u-boot.img of=${SDIMG} count=2 seek=1 conv=notrunc bs=384k > /dev/null 2>&1

elif [ "${CONFIG_BOARD}_x" == "OPIONE_x" ];then
#orangepi
        #dd if=$NPWD/ubootbuild/u-boot-sunxi-with-spl.bin of=${SDIMG} seek=1 conv=notrunc bs=8k > /dev/null 2>&1
        #CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x50 so x050*512/1024=40k
        dd if=$NPWD/ubootbuild/spl/sunxi-spl.bin of=${SDIMG} seek=8 conv=notrunc bs=1k  > /dev/null 2>&1
        dd if=$NPWD/ubootbuild/u-boot-dtb.bin of=${SDIMG} seek=1 conv=notrunc bs=40k > /dev/null 2>&1
elif [ "${CONFIG_BOARD}_x" == "OPIWIN_x" ];then
        #orangepi win
        #dd if=$NPWD/ubootbuild/spl/sunxi-spl.bin of=${SDIMG} seek=1 count=4 conv=notrunc bs=8k > /dev/null 2>&1
        #dd if=$NPWD/ubootbuild/u-boot.itb of=${SDIMG} seek=1 count=20 conv=notrunc bs=40k > /dev/null 2>&1
        dd if=$NPWD/ubootbuild/u-boot-sunxi-with-spl.bin of=${SDIMG} seek=1 conv=notrunc bs=8k  > /dev/null 2>&1
fi

#create img partition table
echo -e "n\np\n1\n$TABLESIZE\n$FATSIZE\nn\np\n2\n \n$EXTSIZE\nt\n1\nc\na\n2\nw\n" | sudo fdisk ${SDIMG} > /dev/null 2>&1
sync
sleep 2
partprobe -s ${SDIMG}  > /dev/null 2>&1
if [ $? -ne 0 ]; then
        echo "make img partition table error"
        exit 1
fi
dd if=${SDIMG} of=${SDIMG}t bs=512 count=$TABLESIZE > /dev/null 2>&1
rm -rf ${SDIMG}
echo "  create partition table success"

#merge imgt and img1 and img2 to img
echo "mergeing image "
if [ ! -f ${SDIMG}t ]; then
        echo "error there is not ${SDIMG}t"
        exit 1
fi
if [ ! -f ${SDIMG}1 ]; then
        echo "error there is not ${SDIMG}1"
        exit 1
fi
if [ ! -f ${SDIMG}2 ]; then
        echo "error there is not ${SDIMG}2"
        exit 1
fi
dd if=${SDIMG}t of=${SDIMG} bs=512 count=$TABLESIZE  > /dev/null 2>&1
dd if=${SDIMG}1 of=${SDIMG} bs=1M conv=notrunc oflag=append > /dev/null 2>&1
dd if=${SDIMG}2 of=${SDIMG} bs=1M conv=notrunc oflag=append > /dev/null 2>&1
sync
sleep 2
partprobe -s ${SDIMG}
if [ $? -ne 0 ]; then
        echo "make img partition table error"
        exit 1
fi
echo "create successful"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容