您的位置:首页 > 其它

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

2015-10-10 20:57 295 查看
系统启动后更新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如下
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: