orangepi制作sd卡启动镜像,并通过uenv加入动态更新uboot和内核功能

目录结构说明

一、基础说明

1、环境介绍

2、启动过程

3、相关地址布局

二、配置uboot支持uenv启动

1、修改menuconfig

2、编译uboot并准备文件

三、设置env.txt文件

0、了解bootcmd命令参数

1、mmc启动参数

2、设置tftp启动参数

3、设置tftp启动引导nfs参数

4、设置tftp更新uboot、kernel参数

5、设置uart串口更新uboot、kernel参数

6、整合成env.txt

四、制作SD卡img

1、准备文件

2、制作Fat分区img

3、制作Ext4分区img

4、制作uboot、spl和分区表镜像头

5、整合成脚本




一、基础说明

1、环境介绍

   首先这里我们需要安装一些基础的编译环境,安装tftp服务器,安装nfs服务器等,这里我们可以参考文章《orangpione利用usb共享网络(RNDIS)实现tftp加载内核挂载到NFS根文件系统》中的环境准备章节,自行安装相关服务,在这里不展开。后续的开发是基于tftp和nfs传输的条件下进行。

2、启动过程

   这里对应大多数的嵌入式linux系统的启动过程都是相似的。首先在开机后,片上的soc会把在存储设置中的SPL文件加载到RAM;然后SPL再加载存储设备中的BootLoader到RAM中,再由BootLoader加载Kernel到RAM中,最后由Kernel接管控制权,并挂载根文件系统,成功启动系统。其中有些还会使用initram,其实也是相当于内核接管控制权后,再把控制权移交给新的内核。

3、相关地址布局

  我们这里使用的orangpinone作为例子对相关的地址布局进行相应的描述,其中官网给出了一个相应的http://www.orangepi.org/Docs/Settingup.html,如下图所示。个人感觉,这个分区布局更适合spiflash的布局。


  我这里使用的分区表信息如下

1、前面的8k空间没有用,主要是预留给分区表用的
2、从8k开始的放了SPL,就是开机之后会被首先运行的文件
3、从40k开始放uboot-dtb,编译出来的uboot和dtb合并的固件。
4、从1M之后建立一个10M的Fat分区,主要是为了方便在windons和linux上进行修改,因为这个分区主要放的文件是env.txt、zImage和dtb文件,即这里主要放的都是启动时需要的env变量或者内核和内核设备树文件。
5、最后再建立一个ext4格式的根文件系统。

二、配置uboot支持uenv启动

  这里我们假设kernel、uboot和rootfs都已经编译过了

1、修改menuconfig

  要使uboot支持uenv参数配置,我们只需要通过修改uboot启动的命令行即可。
  基本思路是,uboot启动后,从mmc中加载env.txt文件到RAM中,在通过env import指令把env.txt的参数设置为uboot的环境参数,最后通过env.txt参数中的uenvboot启动命令开始加载内核。

  1. 通过fatload mmc 0 $kernel_addr_r env.txt;加载env.txt到内存中,
  2. 通过env import -t $kernel_addr_r $filesize;把内存中的env.txt设置为uboot的环境参数。
  3. 最后通过run uenvboot;开始加载内核
  4. 当加载出错的时候run distro_bootcmd;会被执行,则会按照默认的启动顺序启动
    主要配置为:
    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并准备文件

  1. 通过make重新编译uboot
  2. 准备好文件,env.txt、u-boot-dtb.bin、sunxi-spl.bin、zImage、sun8i-h3-orangepi-one.dtb和根文件系统
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 文件我们下一章节介绍

三、设置env.txt文件

0、了解bootcmd命令参数

  是uboot在启动后,需要执行的命令,一般可以固化到uboot编译中去,也可以在uboot终端输入执行,也能通过env.txt等参数设置文件传入给uboot执行。其中通过uEnv的执行方式最为灵活,可以在不重新编译的情况下直接修改设置参数,且只要env.txt的配置参数在相应分区中可以找到,就可以有uboot启动后自动执行。
  具体的代码定义可以在uboot源码目录下的include/config_distro_bootcmd.h文件中找到,里面定义了各种各样的启动参数配置,理论上说不管是从mmc启动还是flash启动,其配置的原理大致相同,不同的是SPL在引导uboot是产生的区别,已经不同环境的配置参数不同罢了。从config_distro_bootcmd.h文件中,不难发现,在include/configs/sunxi-common.h代码中已经固定定义好了几个参数变量,这个我们后续可以直接在env.txt中使用。比如kernel_addr_r、fdt_addr_r、filesize等,这里filesize需要特别强调一下,filesize是会返回前面一次操作返回的文件大小的值,在我们后续的env.txt中很有用。

1、mmc启动参数

在uboot终端输入

  1. 通过命令fatload mmc 0:1 zImage $kernel_addr_h从Fat格式分区加载zImage 内存内核中
  2. 通过命令fatload mmc 0:1 sun8i-h3-orangepi-one.dtb $fdt_addr_r从Fat格式分区加载sun8i-h3-orangepi-one.dtb内存设备树中
  3. 通过命令setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw设置启动之后的根文件系统为mmc的第2个分区(也就是我们的ext4分区)
  4. 通过命令bootz $kernel_addr_h - $fdt_addr_r启动内核
    最后把整个mmc的启动,当执行run boottommc是即可从mmc启动根文件系统。
    参数化到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、设置tftp启动参数

在uboot终端输入(相关ip设置参考之前的文章)

  1. 通过命令usb start;启动usb功能
  2. 通过命令setenv ethact usb_ether;设置usb网卡为第一网卡
  3. 通过命令setenv ipaddr 192.168.137.2;设置开发板ip
  4. 通过命令setenv netmask 255.255.255.0;设置开发板掩码
  5. 通过命令setenv gatewayip 192.168.137.1;设置网关ip
  6. 通过命令setenv serverip 10.8.24.111;设置服务器地址
  7. 通过命令tftp $kernel_addr_r zImage;加载zImage到内存中
  8. 通过命令tftp $fdt_addr_r sun8i-h3-orangepi-one.dtb 从Fat格式分区加载sun8i-h3-orangepi-one.dtb内存设备树中
  9. 通过命令setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw设置启动之后的根文件系统为mmc的第2个分区(也就是我们的ext4分区)
  10. 通过命令bootz $kernel_addr_h - $fdt_addr_r启动内核
    参数化到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、设置tftp启动引导nfs参数

在uboot终端输入(相关nfs设置参考之前的文章)

  1. ip设置部分参照“设置tftp启动参数”的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"设置nfs启动根文件系统
  3. 通过命令tftp $kernel_addr_r zImage;加载zImage到内存中
  4. 通过命令tftp $fdt_addr_r sun8i-h3-orangepi-one.dtb从Fat格式分区加载sun8i-h3-orangepi-one.dtb内存设备树中
  5. 通过命令setenv bootargs console=ttyS0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait rw设置启动之后的根文件系统为mmc的第2个分区(也就是我们的ext4分区)
  6. 通过命令bootz $kernel_addr_h - $fdt_addr_r启动内核
    参数化到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、设置tftp更新uboot、kernel参数

以更新uboot和更新kernel为例子,在uboot终端输入(这里我们选择kernel的内存地址作为暂存地址,因为后续kernel更新会覆盖

  1. ip设置部分参照“设置tftp启动参数”的1~6步
  2. 通命命令tftp $kernel_addr_r u-boot-dtb.bin;加载u-boot-dtb.bin到内存中
  3. 通过命令fatwrite mmc 0:1 $kernel_addr_r 50 3E8更新uboot(0x50 X 512 = 40K, 0x3E8 X 512 = 500K,默认uboot最多500k,可以适当修改小于1M-40K就行
  4. 通过命令tftp $kernel_addr_r zImage;加载zImage到内存中
  5. 通过命令fatwrite mmc 0:1 $kernel_addr_r zImage ${filesize};更新mmc中的内核
    参数化到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、设置uart串口更新uboot、kernel参数

以更新uboot和更新kernel为例子,PC使用SecureCRT通过Ymoden协议传输,在uboot终端输入

  1. 通过命令loady $kernel_addr_r;
  2. 在PC的SecureCRT选择发送Ymoden,并选中u-boot-dtb.bin文件,开始传输
  3. 传输完成后,通过命令fatwrite mmc 0:1 $kernel_addr_r 50 3E8更新uboot(0x50 X 512 = 40K, 0x3E8 X 512 = 500K,默认uboot最多500k,可以适当修改小于1M-40K就行
  4. 通过命令loady $kernel_addr_r;
  5. 在PC的SecureCRT选择发送Ymoden,并选中zImage文件,开始传输
  6. 传输完成后,通过命令fatwrite mmc 0:1 $kernel_addr_r zImage ${filesize};更新mmc中的内核
    参数化到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、准备文件

  按照分区信息表,我们这里需要的文件有:sunxi-spl.bin、u-boot-dtb.bin、env.txt、zImage、sun8i-h3-orangepi-one.dtb和根文件系统rootfs


2、制作Fat分区img

  1. dd if=/dev/zero of=img1 bs=1M count=10> /dev/null 2>&1生成一个 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分区img

  1. dd if=/dev/zero of=img2 bs=1M count=10> /dev/null 2>&1生成一个 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和分区表镜像头

  1. dd if=/dev/zero of=img1 bs=1M count=30> /dev/null 2>&1生成一个 30M的img镜像文件
  2. dd if=sunxi-spl.bin of=img seek=8 conv=notrunc bs=1k > /dev/null 2>&1把sunxi-spl.bin复制到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复制到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工具创建10M的fat和10M的ext4分区
  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信息复制到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"

你可能感兴趣的:(orangepi制作sd卡启动镜像,并通过uenv加入动态更新uboot和内核功能)