系统启动后更新u-boot.bin zImage

    系统启动后更新u-boot.bin zImage  rootf.img
    避免掉电时的风险






分区情况
256M分为7个区

        u-boot  params  logo    kernel  yaffs_1 yaffs_2 config
size    1M      1M      4M      10M     100M    100M    40
58648656
SMDK # mtdparts default
SMDK # mtd
device nand0 <nandflash0>, # parts = 7
 #: name                        size            offset          mask_flags
 0: u-boot              0x00100000      0x00000000      0
 1: params              0x00100000      0x00100000      0
 2: logo                0x00400000      0x00200000      0
 3: kernel              0x00a00000      0x00600000      0
 4: yaffs_1             0x06400000      0x01000000      0
 5: yaffs_2             0x06400000      0x07400000      0
 6: config              0x02800000      0x0d800000      0

active partition: nand0,0 - (u-boot) 0x00100000 @ 0x00000000

defaults:
mtdids  : nand0=nandflash0
mtdparts: mtdparts=nandflash0:1m@0(u-boot),1m(params),4m(logo),10m(kernel),100m(yaffs_1),100m(yaffs_2),-(config)


前提:
设置bootargs的u-boot.bin,zImage,rootfs.img的更新标志,不清除标志,系统启动后用dd命令(dd if=/dev/mtd1 of=/uboot_para)备份为uboot_para
(oob和write_page为编写的更新分区的应用程序和页对齐的应用程序,见最下面的代码区)

1.如需要更新zImage时,将编译好的zImage用软件write_page写为页对齐的zImage.bin(/write_page /zImage /zImage.bin),再用软件(/oob  /zImage.bin  /dev/mtd5)写到mtd5区,(/oob  /uboot_para  /dev/mtd1)写到params区,重启
2.
u-boot启动时读取params的参数,当有更新u-boot.bin或zImage或rootfs.img的标志时,从对应的config或者yaffs_2读到内存中,然后更新到u-boot.bin zImage yaffs_1对应的区,除了u-boot.bin有掉电写入风险外,zImage和yaffs写入都没有风险.
3.更新完成后将对应的标志清零,保存到env区,然后启动系统即完成了zImage的更新
当运行中掉电时,不影响更新,会再次执行


内存64m,设置读取10m的rootfs

//nfs挂载方式测试
set bootargs console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.117:/opt/rootfs,tcp ip=192.168.1.50:192.168.1.117:192.168.1.1:255.255.255.0:haozi:eth0:off
//实际使用
set bootargs console=ttySAC0,115200 root=/dev/mtdblock4 init=/linuxrc


比用软件直接更新内核区要安全,避免掉电发生时,无法启动系统(除uboot外)
提前设置环境变量

set bootargs console=ttySAC0,115200 root=/dev/mtdblock4 init=/linuxrc

set act_update_uboot nand read 30000000 7400000 100000\;nand erase 0 100000\;nand write 30000000 0 100000\;run act_save_uflag
set act_save_uflag set update_uboot_flag 0\;save\;run bootcmd

set act_update_zImage nand read 30000000 7400000 a00000\;nand erase 600000 a00000\;nand write 30000000 600000 a00000\;run act_save_zflag
set act_save_zflag set update_zImage_flag 0\;save\;run bootcmd

set act_update_rootfs nand read 30000000 7400000 a00000\;nand erase 1000000 a00000\;nand write 30000000 1000000 a00000\;run act_save_rflag
set act_save_rflag set update_rootfs_flag 0\;save\;run bootcmd


set update_zImage_flag 1
set update_rootfs_flag 1
set update_uboot_flag 1

set bootcmd nand read 30008000 600000 a00000\;go 30008000


更新zImage和rootfs.img

uboot所需逻辑
1.判断
update_zImage_flag=1

2.为0时执行run bootcmd
为1时执行run act_update_zImage





main.c中的main_loop中添加my_fun()

void my_fun(void) {

	char *s;
	int i;
	char buf[10] = {0};
	s = getenv("update_zImage_flag");
	strcpy(buf, s);
	i = simple_strtoul(buf, NULL, 10);	
	printf("i is %d\n", i);

	if (i == 1) {
		s = getenv ("act_update_zImage");

	} else {
		s = getenv ("bootcmd");
		
	}
	run_command (s, 0);

}


以上仅做了zImage在nfs的测试,其他类似



oob中添加了写入oob的信息,否则uboot无法读取(mtd-util和dd命令没有此功能不能用)


未做处理的部分
1.uboot写时遇到坏块的处理
读时遇到坏块的处理
2.应用程序更新时写到mtd时遇到坏块的处理,ecc处理,越过坏块的处理



write_page.c

#include <stdio.h>


#define         CONTROL_SIZE    (2048)

int main(int argc, char **argv) {
    FILE *fp1, *fp2;
    int size;
    char buf[CONTROL_SIZE];
    int yu;
    int i;
    char extra[CONTROL_SIZE];

    if (argc != 3) {
        printf("usage:write_page [source] [target]\n");
        return 0;
    }
    fp1 = fopen(argv[1], "rb");
    if (fp1 == NULL) {
        fprintf(stderr, "open fail %s\n", argv[1]);
        return 0;
    }
    fp2 = fopen(argv[2], "wb+");
    if (fp2 == NULL) {
        fprintf(stderr, "open fail %s\n", argv[2]);
        return 0;
    }

    do {
        size = fread(buf, 1, CONTROL_SIZE, fp1);
        if (size > 0) {
            yu = fwrite(buf, 1, size, fp2);
        } else {
            printf("write over here\n");
            break;
        }
        if (size != CONTROL_SIZE) {
            printf("over here\n");
            break;
        }

    } while (1);


    if (size != 0) {
        size = CONTROL_SIZE - size;
        for (i = 0; i < size; i++) {
            extra[i] = 0xff;
        }
        yu = fwrite(extra, 1, size, fp2);
    }


    fclose(fp1);
    fclose(fp2);

    return 0;
}

oob.c如下


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值