不用各种板商的工具,因为用了不知道为什么。。。除了烧写uboot没办法。。。
使用tftp、nand等uboot自带操作,操作完成内核、设备树、文件系等下载烧写
实际uboot启动后,tftp从远程机器获取的数据,是往ram上传递的,一般需要配置server ip 和 本机ip:
setenv ipaddr 192.168.22.248
setenv netmask 255.255.255.0
setenv serverip 192.168.21.199
saveenv
//通过tftp下载到目标文件数据到ram上,这个目标文件二进制格式即可,有uImage,dtb,yaffs2等。
tftp 0x80100000 Image.gz
tftp 0x80070000 tegra194-p2972-0000.dtb
//不过uboot中的tftp还有的叫做tftpboot的,功能貌似是一样的
东西下载到ram中后,在实际使用中,需要固化到nand中去,所以需要ram往nand中写操作。
注意一个点:nand写之前先擦除下。由于flash的工作原理,故支持从1写0,不支持从0写1,利用这一点,最终只要保证我们要擦除、或将来写数据的地址为全ff即可。所谓擦除就是全充电成0xff。
写入之前强烈建议先擦初以前没这个习惯
擦除、写入、读取,基本格式:nand write/read raw_addr flash_addr size nand erase flash_addr size
但实际遇到的:nand write 0x8801000000 kernel 0x3200000
nand write 0x8800070000 device_tree 0x1200000
显然很费解,这里的读写nand中nand的起始地址直接用kernel和device_tree代替,这是在nand分区中已经指定。什么是nand分区呢?
首先需要引入分区的概念,分区的配置在uboot和kernel两边都有,是以代码的方式写死。
下面两图是两个版本的uboot侧,内核区一个给了2m一个给了4m,另一个多了device_tree区:
0~256K:为在nandflash上,从0开始的256k空间
接着的256k为device_tree数据或者params数据
接着的为内核数据
余下来的就是rootfs空间。
由此他的标签kernel、device_tree即代表起始地址,也代表了大小。
内核代码侧也有这样的对应配置,不过在进入设备树后,这块确实不应该在这里出现代码化,应该卸载dts中传递:
可以直接在uboot下用:mtd命令查看:可见每块的起始偏移地址和块大小。
看上表,一开始的0x00000000是offset,先不要纠结这个是cpu的寻址0还是啥。不过总大小根据最后一块0x480000+0xfb80000=256MB,确实这块flash是这么大。
根据上图:nand read.jffs2 0x30007FC0 kernel 其实就是 nand read.jffs2 0x30007FC0 0x00080000 0x00400000
注意有nand write.jffs2、nand write.yaffs、nand write, 处理jffs2\yaffs格式写入,而内核的写入我猜测应该是和jffs2类似,因为没有自带ecc,所以需要主动写入ecc,所以采用read.jffs2。单独的nand write涉及page write限制,故不采用。
uboot下键入这个可以获取nand使用帮助:? nand
重启后,由于uboot分区表kernel就是从0x60000开始的,bootcmd会去nand使用分区表的kernel符号就能从nandflash搬出内核了,然后bootm 0x30007FC0
Data Load Address : kernel的加载地址,即表示运行这个内核时,要先把内核放在ram地址的哪里。
Entry Point Address:运行这个内核要一开始要去到哪个位置开始运行。
以上完成了tftp下载内核到本机ram,然后从ram烧录进合适的nandflash地址,重启后能正确搬出内核到内存上,并执行。
但是文件系统使用同套路出现了问题,目前解决了:
jffs2和yaffs存在ecc校验数据这方面的不同,由此写入数据的不同的,看那个opts格式就不同。
开发板厂家的自带menu功能展开成具体指令:
由此写入读出有文件格式区分(不同开发板的tftp指令可能不同,这里是tftpboot):
tftpboot 0x30000000 fs_mini.yaffs2
nand erase 0x260000 0x0fda0000 / nand erase root
nand write.yaffs 0x30000000 0x260000 0x8607c0
//nand write.yaffs 0x30000000 0x260000 8607c0 s3c开发板好像存在bug,文件长度不能加0x头
tftpboot 0x30000000 fs_mini.jffs2
nand erase 0x260000 0x0fda0000 / nand erase root
nand write.jffs2 0x30000000 0x260000 0x8607c0
nand write.jffs2 0x30000000 0x260000 8607c0
tftpboot 0x30000000 uImage_4.3
nand erase 0x60000 0x200000
nand write.jffs2 0x30000000 0x60000 0x1c35d8
到此表示tftp+nand 是可以解决多有二进制格式的烧写的,各种开发板商写的一堆自己的menu完全是在误导人。
setenv bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200:
/dev/mtdblock3即根据mtd来的,bootloader=block0 params=block1 kernel=block2 rootfs=block3
还有个知识点要记得,内核启动完毕,内核代码中的设备探测代码挂接后,才会去挂载rootfs所在的blockX
下图即tftp+nand 的文件系统的下载写入操作执行:
下图是jz2440的厂商uboot中的一堆整合指令的详细分解。
注意第一句usbslave …; 是usb操作,而我是用tftp下载的:
看看这些uboot源码理清挺多东西的。
我uboot中help 看到还有这些,貌似tftp不行的话,可以用串口传数据,有空可以尝试下。