移植U-BOOT之裁剪和修改默认参数(易用性)启动内核,以及对uboot进行分区

今天我们来裁剪U-BOOT,使其更加易用,修改默认参数,以及制作最终修改好得补丁文件方便以后的快速移植。

那么如果想看之前的关于网卡以及flash等的移植,请点击链接查看:点击链接查看

在裁剪修改之前呢,我们先来了解一下U-BOOT的环境参数(环境变量):
uboot在启动的时候首先会读取环境参数,然后判断环境参数是否有效,如果设置的环境参数是无效的,那么就使用默认的参数。

我们还要知道整个Linux系统在硬盘中(FLASH)中是如何分区的:
Linux系统的分区
我们可以看到,uboot放到第一个分区,环境参数放到第二个分区,内核放到第三个分区,文件系统放到第四个分区。

之前我们修改的U-BOOT启动后,一直有一个警告:
警告信息
显示说CRC的参数错误,使用默认的环境变量。那么我们就从这个问题引入吧。在uboot中搜索字符串:using default environment
从而找到了:
Env_common.c(common目录下)

const uchar default_environment[] = {
#ifdef  CONFIG_BOOTARGS"bootargs=" CONFIG_BOOTARGS         "\0"
#endif
#ifdef  CONFIG_BOOTCOMMAND"bootcmd="  CONFIG_BOOTCOMMAND      "\0"
#endif
.......
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)"bootdelay="    MK_STR(CONFIG_BOOTDELAY)    "\0"
#endif
......
#ifdef  CONFIG_ETHADDR"ethaddr="  MK_STR(CONFIG_ETHADDR)      "\0"
#endif
......
#ifdef  CONFIG_IPADDR"ipaddr="   MK_STR(CONFIG_IPADDR)       "\0"
#endif
}

bootargs是传给内核的启动参数,可以设置文件系统的相关分区等。我们在配置文件smdk2440.h中159行的地方定义一下:

#define CONFIG_BOOTARGS "console=ttySAC0 root=dev/mtdblock3" //代表内核从串口0启动,文件系统放到第3个分区

bootcmd是uboot用来启动内核的参数,我们也在配置文件中定义(bootargs定义的下面)定义一下(先随便定义一个值):

#define CONFIG_BOOTCOMMAND "nand read 30000000 0xbac 0x200000;bootm 30000000"
//因为现在还无得知内核的分区的具体地址,先随便设置一个值,用于演示,等我们把整个FLASH分区规划好了之后,再来设置

bootdelay是uboot启动后的那个倒数计时的参数,当uboot启动后,进入倒计时启动,我们按下任意键,进入uboot交互界面开始进行一些设置等操作。这里我们就去默认值。

ipaddr我们已经很熟悉了,是uboot单板的ip地址,这个我们可以修改一下看看,这个在配置文件smdk2440.h中已经由定义,我们找到将其修改为:

#define CONFIG_IPADDR       192.168.1.103

ethaddr表示网卡的MAC地址,再定义一下MAC地址:

#define CONFIG_ETHADDR      00:0c:29:4d:e4:f4  //lyy

好了,设置好我们常用的参数后,我们先来裁剪一下uboot,因为这个uboot实在是太大了。
我们在uboot命令行输入help,发现有各种命令,有些命令根本不需要,那么我们就需要把相关的宏定义给去掉。
这里我就不记录了,去掉的地方太分散了,大概是去掉了usb,文件系统的支持等。
然后重新编译uboot,发现有一些错误,说我的有一些定义没定义,但是,我已经把相关定义去掉了。重新:make distclean,然后make smdk2440_config,再make。没有错误了(至于为什么,我也不清楚,没必要细究。)。

然后我们现在来分区:
首先看一下之前是怎么分区的,启动内核看一下之前是怎么分区的:
0x00000000-0x00040000 : “bootloader” (0~256k)
0x00040000-0x00060000 : “params”
0x00060000-0x00260000 : “kernel”
0x00260000-0x10000000 : “root”
我们先来设置一下我们的参数的存放地址吧,因为之前我们设置好参数之后,每次都不敢save,就是怕破坏FLASH。

在配置文件中,找到如下环境变量的相关定义:

#define CONFIG_ENV_ADDR         (CONFIG_SYS_FLASH_BASE + 0x070000)
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE         0x10000
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE

那么我们重新定义这些宏,该怎么定义呢?
在uboot命令行使用help命令查看save相关的信息:
save信息
然后我们在uboot源码中搜索字符串:saveenv
找到了类似这样的语句:
搜索信息:Env_flash.c (common):int saveenv(void)
我们去common目录下看看Makefile,看看Env_flash.c的编译依赖哪个宏?找到了下面这句:
COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
说明编译Env_flash.c依赖的是CONFIG_ENV_IS_IN_NAND这个宏的定义。那么我们就定义这个宏CONFIG_ENV_IS_IN_NAND:
所以我们将上面环境变量的宏重新定义如下:

#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET       0x00040000
#define CONFIG_ENV_SIZE         0x20000
#define CONFIG_ENV_RANGE        CONFIG_ENV_SIZE

然后重新编译,没有错误。
用tftp下载,先设置好ip等(参考上一篇文章):
tftp 30000000 u-boot.bin
protect off all
erase 0 3ffff (因为uboot经过裁剪后,大小变了,所以擦除和拷贝的地址会发生变化)
cp.b 30000000 0 40000
然后重启:
裁剪后的uboot启动
由启动知,已经有了倒数的命令,以及我们设置的ip等,都直接就存在了。
但是还是有呢个关于CRC的警告信息,那是因为,那个CRC的变量没有写到FLSAH中,我们执行save命令,再重启:
这里写图片描述
此时,就没有那个警告信息了,说明参数已经成功被写进flash,说明上面修改的的参数保存的地址的区域,也设置成功了。
然后我们烧写内核:
tftp 30000000 uImage_4.3
nand erase 60000 200000
nand write 30000000 60000 200000
从这里,就可以感觉到,烧写个程序要这么麻烦。下面我们就来修改代码,让烧写程序变得简单:
在配置文件中定义宏:CONFIG_CMD_MTDPARTS(寻找方法类似于上面的找Makefile的方法)

#define CONFIG_CMD_MTDPARTS
#define MTDIDS_DEFAULT      "nand0=jz2440-0"    /* 表示哪一个设备 */
#define MTDPARTS_DEFAULT    "mtdparts=jz2440-0:256k(u-boot),"   \"128k(params),"     \"2m(kernel),"   \"-(rootfs)"     \

在board.c中657行添加:

run_command("mtdparts default",0);

重新编译,出现错误:
common/libcommon.o: In function get_mtd_info':
/work/system/u-boot-2012.04.01/common/cmd_mtdparts.c:306: undefined reference to
get_mtd_device_nm’
make: * [u-boot] Error 1
通过查找,发现Mtdcore.c函数(在drivers/mtd目录下)定义了get_mtd_device_nm这个函数,应该是没有被编译进内核,所以才显示错误,去Makefile中查看,发现,还需要定义这个宏:CONFIG_MTD_DEVICE,那么我们在配置文件中再定义这个宏:

#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define MTDIDS_DEFAULT      "nand0=jz2440-0"    /* 表示哪一个设备 */
#define MTDPARTS_DEFAULT    "mtdparts=jz2440-0:256k(u-boot),"   \"128k(params),"     \"2m(kernel),"   \"-(rootfs)"     \

再重新编译,没有错误。烧写uboot,重启,在uboot命令行输入:mtdparts,显示如下:
这里写图片描述

再来烧写内核时,就可以这样烧写内核了:
tftp 30000000 uImage_4.3
nand erase.part kernel
nand write 30000000 kernel
然后我们再回过头把配置文件中的这句话:

#define CONFIG_BOOTCOMMAND "nand read 30000000 0xbac 0x200000;bootm 30000000"

修改为:

#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel 0x200000;bootm 30000000"

重新编译,烧写uboot,烧写内核。重启,发现可以直接启动内核了,因为我们已经把读内核的地址修改好了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移植U-BOOT之支持烧写YAFFS文件系统以及制作U-BOOT补丁

今天,我们来移植U-BOOT让其支持YAFFS文件系统映像的烧写,以及最后的终极目标,制作Uboot补丁,因为我们信心苦苦移植好了Uboot,如果换一个地方的或者换一台电脑之类的,我们也不想再浪费时间从头开始移植&…

【数据结构学习之完全从零实现所有数据结构的代码编写之一】泛型编程简介

学习交流加 个人qq: 1126137994个人微信: liu1126137994学习交流资源分享qq群: 962535112 今天开始系统性学习数据结构内容,之前也看过大话数据结构这本书,对大多数概念以及数据结构都有一定的了解,但是就是…

zookeeper 安装和使用

1.Windows安装和使用zookeeper 之前整理过一篇文章《zookeeper 分布式锁服务》,本文介绍的 Zookeeper 是以 3.4.5 这个稳定版本为基础,最新的版本可以通过官网 http://hadoop.apache.org/zookeeper/来获取,Zookeeper 的安装非常简单&#xf…

【移植Linux 3.4.2内核第一步】之简单修改

前一阵子已经将U-boot移植好了,从今天开始,我们开始移植linux内核。移植的内核为3.4.2,移植的开发板为:jz2440开发板。 想看之前移植U-boot的记录,可以查看我的博客专栏,点击链接:点击查看U-bo…

前端学习(77):css中常见margin塌陷问题之解决办法

塌陷问题 当两个盒子在垂直方向上设置margin值时&#xff0c;会出现一个有趣的塌陷现象。 ①垂直并列 首先设置两个DIV,并为其制定宽高 1 1 /*HTML部分*/2 <body>3 <div class"box1">box1</div>4 <div class"box2">box2…

HBase2.0 vs HBase1.x 延时比较

hbase2.0已经正式发布&#xff0c;对比之前1.x版本&#xff0c;2.0在读写链路上做了完善的优化&#xff0c;offheap、netty rpc等&#xff0c;这里做个小测试实验对比1.x和2.0在读写上的延时情况。本测试基于特定测试环境与软件版本得到的结果&#xff0c;仅供参考。 测试介绍 …

【数据结构学习之完全从零实现所有数据结构的代码编写之二】智能指针

今天我们依然暂时不讲解数据结构里面的内容&#xff0c;我们来复习一下昨天学的模板技术用于数据结构编程的思想&#xff0c;给出一个模板技术的实例&#xff1a;智能指针的应用。喜欢看我分享的加我q:1126137994 加我共同学习交流各种技术。 为什么会引入智能指针呢&#xff…

职责链模式(Chain of Responsibility)

重要概念 1. 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处理它为止。 2.请求是沿着链条传递到有一个处理点对象负责处理这个请求为止。请求者无需…

mootools

$();// 选择ID为”body_wrap“的元素$(body_wrap);.getElement();// 选择ID为”body_wrap“的元素下面的第一个链接$(body_wrap).getElement(a); or #xxx or .xxx.getElements();// 选择ID为”body_wrap“的元素下面的所有链接$(body_wrap).getElements(a); $(body_wrap).getE…

图形化界面客户端连接phoenix操作hbase

下载客户端软件 DBeaver https://dbeaver.io/download/ 选择对应系统的版本&#xff0c;我这里选择解压版windows64位 创建连接 注意&#xff1a;URL模板就不要一般是默认 选择合适的版本&#xff08;跟你服务器的版本一致&#xff09;&#xff0c;下载jar包 点击测试或完成即…

【C++深度剖析教程12】数组操作符的重载

之前写的C学习记录忘记打编号了&#xff0c;从今天开始&#xff0c;所有内容&#xff0c;记录编号&#xff0c;方便以后的查阅复习。今天学习的是C中&#xff0c;数组操作符的重载。 上一篇博文写的是介绍C中的字符串类&#xff0c;我们知道&#xff0c;C标准库中通过string类…

前端学习(80):按类型划分标签(inline)

解决font-size中间有间隙 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compat…

HBase shell 命令介绍

HBase shell是HBase的一套命令行工具&#xff0c;类似传统数据中的sql概念&#xff0c;可以使用shell命令来查询HBase中数据的详细情况。安装完HBase之后&#xff0c;如果配置了HBase的环境变量&#xff0c;只要在shell中执行hbase shell就可以进入命令行界面&#xff0c;HBase…

【C++深度剖析教程13】函数对象的分析

今天来学习函数对象。什么是函数对象呢&#xff1f;下面我们以一个例子来引出函数对象的概念。 假设我们需要编写一个函数&#xff0c;实现下面这些功能&#xff1a; -函数可以获得斐波那契数列每一项的值 -每调用一次返回一个值 -函数可根据需要重复用使用 实现上面的几个…

IE图标消失 HTML文件图标变为未知图标的解决方法

有时候保存在硬盘里的HTM和HTML文件图标会突然变为未知的图标&#xff0c;而且它们往往还是与IE关联&#xff0c;也没有发现病毒。原因我怎么也弄不明白&#xff0c;但可以通过对注册表做些修改来恢复&#xff0c;详细步骤如下: 1.首先打开注册表编辑器&#xff0c;定位到HKEY_…

(SQuirreL SQL Client 客户端 )使用Apache Phoenix 实现 SQL 操作HBase

Apache Phoenix 相信大家并不陌生&#xff0c;它是HBase的SQL驱动&#xff0c;Phoenix 使得Hbase 支持通过JDBC的方式进行访问&#xff0c;并将你的SQL查询转换成Hbase的扫描和相应的动作。 兼容性&#xff1a; Phoenix 2.x - HBase 0.94.x Phoenix 3.x - HBase 0.94.x Phoen…

【C++深度剖析教程14】经典问题解析三之关于赋值的疑问

今天我们来总结一下&#xff0c;之前所学C中所遇到的一些经典的问题。 第一个疑问是&#xff1a; -什么时候需要重载赋值操作符 -编译器是否提供默认的赋值操作&#xff1f; 解答&#xff1a; *编译器为每个类默认重载了赋值操作符 *默认的赋值操作符仅完成了浅拷贝 *当…

微服务架构和SOA的区别

1. 2. 4 微服 务 架构 与 SOA 的 区别 1. 3. 1 微 服务 的 拆分 对于 一般 的 公司 而言&#xff0c; 实践 微 服务 有 非常 大的 技术 挑战&#xff0c; 所以 并不是 所有 的 公司 都 适合 将 单体 架构 拆分 成 微服 务 架构。 一般来说&#xff0c; 微服 务 架构 比较 适合 …

【C++深度剖析教程15】经典问题解析之关于string的疑问

今天来看一下在面试笔试中经常会出错的地方。 我们先来看一个代码&#xff1a; #include <iostream> #include <string>using namespace std;int main() {string s "12345";const char* p s.c_str();cout << p << endl; s.append(&qu…