uboot移植之剪裁和烧写文件系统

通过前面几节的内容,uboot基本上已经移植成功了,把它烧入单板中可以成功启动,并且具备网络下载功能,如果也已经烧录了内核和文件系统,启动是没有问题的,今天这一节来做最后的事情,就是uboot的剪裁和一些结尾,之前我们编译好的uboot很大,有500多k,因为它里边包含了很多我们用不上的模块,就需要剪裁uboot,去掉那些不需要的模块,减小它的大小
在之前的启动信息里,有如下的错误警告
** Warning - bad CRC, using default environment**
它的意思是我们的环境参数没有存储在flash里,所以使用的是默认的参数,在网络配置那一节中,我们可以设置环境参数,从而执行tftp的下载,但是没有执行save命令,也不能去执行save命令,因为那时候还没有划分uboot的分区,所以环境参数会保存到我们不知道的地址中去,很有可能会破坏掉数据,我们来寻找这个警告产生的位置
在这里插入图片描述
这个警告信息是在set_default_env这个函数中产生的,函数里会设置default_environment这些环境参数,跟过去看一下是怎么定义的
在这里插入图片描述
是一个数组,数组项是各种环境参数,而且如果定义了对应的宏,才会执行环境参数的赋值,找到几个我们需要的环境参数,在smdk2440.h中进行定义

//uboot给内核传递的参数
#define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
//uboot启动内核的命令
#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel;bootm 30000000"
//网络掩码
#define CONFIG_NETMASK  255.255.255.0
//ip地址
#define CONFIG_IPADDR  192.168.1.110
//服务器的Ip tftp
#define CONFIG_SERVERIP  192.168.1.100
//mac地址
#define CONFIG_ETHADDR  00:0c:29:64:4d:19

定义好了之后,在smdk2440.h中阅览一遍,把我们不需要的模块去掉**(emmm,说是剪裁,其实做起来很简单,在配置文件中把定义的宏去掉,那么根据惯例,对应的模块就不会被编译进去)**
去掉usb和RTC
在这里插入图片描述
这些奇奇怪怪的内容好像也不需要
在这里插入图片描述
在这里插入图片描述
好了,差不多就是这些,如果还有哪些不需要做法类似,编译,如果之前的编译有错需要清除重新编译
make distclean
make smdk2440_config
make
编译生成的uboot这时候才200多K,比之前少了一半,启动之后可以查看环境参数已经变化了
在这里插入图片描述
但是这个时候还是不能使用save命令把这些环境参数保存到flash中去,因为还没有在uboot中指定环境变量要保存的位置,所以接下来是uboot分区的划分,uboot一个典型的内存划分如下
在这里插入图片描述
我们就按照这个这个分区来做,在内核启动的时候它会打印出分区信息,其实和uboot是一样的
在这里插入图片描述
首先要解决的就是save命令保存的地址,save命令对应的函数是saveenv(),它在env_nand.c里定义
在这里插入图片描述
分析上面的代码,在写环境参数的时候是写到了CONFIG_ENV_OFFSET的偏移地址去的,根据上面的分区信息,可以知道环境参数在Uboot中保存的位置是0x00040000,环境参数分区的大小是宏CONFIG_ENV_SIZE,它的值是0x20000,CONFIG_ENV_RANGE表示擦除的范围,应该是和这个分区一样大的,所以,一些宏的定义如下
在这里插入图片描述
save命令的函数基本上就修改到这里,这个时候要注意要在编译的时候把这个文件选择进去,在common/Makefile中找到该文件的编译选择
在这里插入图片描述
在smdk2440.h中定义该宏,编译env_nand.c,编译,下载,这个时候去uboot中去执行save这个命令,再去重启就会发现没有没有了那个警告信息,接下来要做的是在代码里定义分区,它依赖的是uboot的mtdpart命令,命令对应的函数是在common/cmd_mtdpart.c,和上面一样,根据makefile定义 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
首先会执行mtdparts_init函数,大概看一下这个函数,找到其中的分区信息
在这里插入图片描述
跟踪变量mtdids_default
在这里插入图片描述
如果定义了这个宏,就会配置分区信息,我们搜索别人是怎么样配置这个宏的,然后在smdk2440.h中定义即可,名字随意取
在这里插入图片描述
还有就是这个宏表示分区信息
在这里插入图片描述
smdk2440.h
在这里插入图片描述
在board.c的mainloop函数前执行使用默认的mtdpart命令
在这里插入图片描述
编译uboot,下载,在串口中输入mtdpart就会显示分区信息
在这里插入图片描述
这样一来就可以使用这些分区来烧写内核和文件系统了

//没有分区信息烧写内核的命令
tftp 30000000 uImage_4.3
nand erase 60000 200000
nand write 30000000 60000 200000

//使用分区之后的烧写
tftp 30000000 uImage_4.3
nand erase.part kernel
nand write 30000000 kernel

对比之下,好处就是再也不需要去记那些地址信息了,bootcmd也可以改为下面的样子
在这里插入图片描述
重启,倒计时结束之后就回去kernel分区启动内核,内核可以启动成功,但是没有文件系统,现在来烧写文件系统,在烧写yaffs2文件系统的时候发现还不支持这个类型的烧写,在cmd_nand中找到
在这里插入图片描述
看样子是这个宏没有配置,在smdk2440.h中进行配置,成功之后更新uboot
tftp 30000000 u-boot.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000
在这个过程中发生了一些错误,需要解决
1、Kernel panic - not syncing: No init found. Try passing init= option to kernel.
cmd_nand.c do_nand函数在烧写yaffs2文件系统的时候调用了函数nand_write_skip_bad,这个函数改为如下
在这里插入图片描述
2、烧写过程
如果是烧写jffs2类型的文件系统
tftp 30000000 fs_mini_mdev.jffs2
nand erase.part rootfs
nand write.jffs2 30000000 0x00260000 5b89a8
set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2 //设置启动参数

这样是完全没有问题的
如果是烧写yaffs2类型的文件系统
tftp 30000000 fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs2 30000000 260000 889bc0

由于当前的uboot还不支持nand write.yaffs2的命令,所以我使用nand write.yaffs的命令下载,这一点也忽略了好久,但是这样下载,烧写的文件系统时启动不了的,和上面的错误时一样的,这也烦恼了我好久,于是在网上看到一个答案,
nand_util.c:518行:
//if (!need_skip && !(flags & WITH_DROP_FFS)) {
改为:if (!need_skip && !(flags & WITH_DROP_FFS) && !(flags & WITH_YAFFS_OOB)) {

再次编译,下载,使用如下的命令烧写yaffs2的文件系统
nand write.yaffs 30000000 260000 889bc0
启动,终于成功进入内核,挂载文件系统
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值