历史上的今天
返回首页

历史上的今天

今天是:2025年07月30日(星期三)

正在发生

2021年07月30日 | 移植uboot-设置默认环境变量,裁剪,并分区

2021-07-30 来源:eefocus

在上一章使uboot支持网卡传输文件后,但是每次启机时,环境变量都要变为默认值,需要重新设置ip,MAC地址才行,由于没有配置mtdparts命令,启动内核也不成功


所以本章主要学习:


1)修改环境变量默认值

2)裁剪uboot  

3)分区,设置mtdparts命令

1.修改之前,先来理解下uboot的环境参数


首先,uboot会去校验(CRC)存放环境变量的一段空间 ,若CRC有效则使用该空间里的环境变量,无效则用默认的环境变量.


而我们移植的uboot,由于一直没有使用save,所以没有读不出CRC校验,使用的默认环境变量,如下图所示:

2.来修改uboot的默认环境变量


(PS:uboot此时的内存分区还没修改,所以每次设置环境后,不能用save保存,怕破坏掉nand里面的内容)


2.1搜索using default environment,找到位于set_default_env()函数:

从上面代码可以看到, default_environment这个变量,这是个全局字符数组,从字面上就可知道,这个是默认环境变量数组,里面保存了各个环境值


2.2进入default_environment[]看看

这个数组比较长,所以只剪切一部分,其中MK_STR()的作用就是将数值转换为字符串


这些都是环境参数,比如"bootargs="(环境变量里最重要的一个),里面会保存文件系统位置,控制台console等等


我们以bootargs为例:


在default_environment[]数组里,若CONFIG_BOOTARGS宏有值,便会组成一串字符串"bootargs=... ..."


比如在以前的uboot里,可以看到:


bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0

//root:指定文件系统位置

//init:指定内核启动后执行的第一个应用程序

//console:指定使用哪个终端,比如串口0,使用ttySAC0


其它宏也是这样.比如我们熟悉的有:


"bootcmd=", 用来启动内核的命令

"bootdelay=",uboot启动的倒计时,默认值为5S,只有设置了bootcmd,该倒计时才有用

"baudrate=",波特率,默认为115200

"ethaddr=",网卡的MAC地址(也叫物理地址)

"ipaddr=",ip地址

"serverip=",使用tftp时的服务器地址

"netmask=",掩码, 默认值为255.255.255.0

"mtdparts=",mtd分区表

 

2.3所以接下来,便修改smdk2440.h里面与环境相关的宏


设置默认环境变量宏(位于include/configs/smdk2440.h):


#define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"   //bootargs

#define CONFIG_BOOTCOMMAND "nand read  0x30000000 0x60000 0x200000; bootm 0x30000000" //bootcmd

#define CONFIG_BOOTDELAY       10                      //uboot 倒计时      

#define CONFIG_NETMASK         255.255.255.0           //掩码

#define CONFIG_IPADDR          192.168.2.103           //本机IP

#define CONFIG_SERVERIP        192.168.2.101           //电脑IP

#define CONFIG_ETHADDR         08:00:3e:26:0a:5b       //MAC地址


其中bootcmd是随意写的,因为此时的内核位置还不确定放在哪(后面配置mtdparts命令后,会在4.6小节修改)


由于nand中要划分bootload空间、环境变量空间、内核空间、系统空间


而uboot就有400多k,所以我们需要裁剪uboot,裁剪后再来划分内存分区


3.裁剪uboot


uboot很多文件都是基于Makefile,里面通过判断宏来加载文件.而宏大部分都定义在include/configs/smdk2440.h


3.1进入smdk2440.h,把不需要的功能的宏去掉,比如usb,文件系统,rtc等


1)去掉usb支持


/************************************************************

// * USB support (currently only works with D-cache off)

// ************************************************************/


//#define CONFIG_USB_OHCI

//#define CONFIG_USB_KEYBOARD

//#define CONFIG_USB_STORAGE

//#define CONFIG_DOS_PARTITION


2)去掉rtc支持


/************************************************************

// * RTC

// ************************************************************/


//#define CONFIG_RTC_S3C24X0


3)去掉BOOTP选项


/*

// * BOOTP options

// */


//#define CONFIG_BOOTP_BOOTFILESIZE

//#define CONFIG_BOOTP_BOOTPATH

//#define CONFIG_BOOTP_GATEWAY

//#define CONFIG_BOOTP_HOSTNAME


4)去掉部分不需要的命令行配置


// #define CONFIG_CMD_DHCP     //动态主机配置协议命令行

// #define CONFIG_CMD_USB      //USB命令行


5)去掉文件系统


/*

// * File system

// */


//#define CONFIG_CMD_FAT

//#define CONFIG_CMD_EXT2

//#define CONFIG_CMD_UBI

//#define CONFIG_CMD_UBIFS

//#define CONFIG_CMD_MTDPARTS

//#define CONFIG_MTD_DEVICE

//#define CONFIG_MTD_PARTITIONS

//#define CONFIG_YAFFS2

//#define CONFIG_RBTR


3.2 编译


由于屏蔽的宏在其它文件也会用到,而make在之前用过,再次make只会编译修改过的文件.


所以输入:


make clean                  

make s3c2440config

make


make后,打印以下错误:


common/libcommon.o: In function `do_date':

/work/system/u-boot-2012.04.01/common/cmd_date.c:60: undefined reference to `rtc_reset'

/work/system/u-boot-2012.04.01/common/cmd_date.c:63: undefined reference to `rtc_get'

/work/system/u-boot-2012.04.01/common/cmd_date.c:72: undefined reference to `rtc_set'

/work/system/u-boot-2012.04.01/common/cmd_date.c:81: undefined reference to `rtc_get'

make: *** [u-boot] 错误 1


上面的cmd_date.c文件以及出错变量rtc_xxx,从字面上来看显然是与RTC有关,我们直接屏蔽该文件


通过Makefile,找到需要屏蔽宏CONFIG_CMD_DATE(宏定义位于include/configs/smdk2440.h):

屏蔽后,make成功,可以看到uboot只有200kb了:

接下来,便开始分区,使我们的环境变量能保存在uboot指定位置里


4.设置分区


以前,我们每次启动内核时,都会打印以下分区信息:


Creating 4 MTD partitions on "NAND 256MiB 3,3V 8-bit":

0x00000000-0x00040000 : "bootloader"            //存放uboot

0x00040000-0x00060000 : "params"                //存放环境变量

0x00060000-0x00260000 : "kernel"                //存放内核

0x00260000-0x10000000 : "root"                  //存放文件系统


所以,我们新的uboot,还是照着这个来分区


还记得之前,我们每次设置了环境变量,都不敢用save命令来保存.


4.1所以我们通过sava -help命令,看它位于哪个文件,找到save命令相关宏


如下图所示:

4.2然后在si里搜索saveenv


搜索如下图所示:

可以发现,在env_flash.c 和env_nand.c这两个文件都有saveenv()函数.


显然env_flash.c的作用是,通过save命令将环境变量保存在nor flash.


而env_nand.c,是将环境变量保存在nand flash里.


4.3接下来在common/Makefile搜索,看看这两个文件依赖哪两个宏


如下图所示:

4.4然后在smdk2440.h搜索这两个宏,看看板卡默认配置的是不是env_nand.c


如下图所示:

可以看到,smdk2440.h是将环境变量保存在nor flash,由于2440在nand启动下是无法支持nor,所以我们需要屏蔽这三处宏,重新设置宏


4.5设置save相关宏


在其它板卡里搜索CONFIG_ENV_IS_IN_NAND,看看别人是怎么通过宏配置save的,然后在env_nand.c文件里搜索宏,来看宏是怎么用的


最终宏修改为如下所示(位于include/configs/smdk2440.h):


//#define CONFIG_ENV_ADDR                    (CONFIG_SYS_FLASH_BASE + 0x070000)

//#define CONFIG_ENV_IS_IN_FLASH

//#define CONFIG_ENV_SIZE               0x10000


#define CONFIG_ENV_SIZE                 0x20000       //环境变量空间大小

#define CONFIG_ENV_IS_IN_NAND

#define CONFIG_ENV_OFFSET               0x40000          //位于0x40000~(0X40000+0x20000)

#define CONFIG_ENV_RANGE                CONFIG_ENV_SIZE  //环境变量的擦除范围,要>=SIZE


上面的CONFIG_ENV_RANGE宏,其实不定义,内核也会自动定义(位于env_nand.c):

然后重新编译新的uboot,就可以使用save命令保存环境变量了.


接着我们烧写内核: 


tftp 30000000 uImage

nand erase 60000 200000                         

nand write 30000000 60000 200000        //保存在内核分区里

bootm 30000000                         //启动内核


从这里,看出烧个内核还需要记录这些分区空间地址,非常麻烦


4.6 设置mtdparts命令(在旧版uboot里,是mtd命令)


其实,我们可以使用mtdparts命令,通过分区名字来代替这些地址,比如以前的uboot,直接输入:


nand erase kernel              //这个kernel名字就等于: 60000 200000 

nand write  30000000 kernel    //这个kernel名字就等于: 60000 200000


由于smdk2440板卡里没有配置mtdparts命令,所以步骤如下所示:


1)搜索mtdparts,发现位于common/cmd_mtdparts.c


2) 在common/Makefile搜索,找到cmd_mtdparts.c文件依赖CONFIG_CMD_MTDPARTS宏

3)在其它板卡里搜索CONFIG_CMD_MTDPARTS,看看别人是怎么通过宏配置nand的,别人写的配置如下所示:

"-":表示剩余空间都是文件系统。

(PS:当执行mtdparts default命令时,uboot就会检测是否有CONFIG_CMD_MTDPARTS宏,然后再根据上面的MTDPARTS_DEFAULT宏保存的mtd分区信息,来将nand和nor分区)


4)设置mtdparts相关宏


接下来,便复制上面的宏到smdk2440.h中,改为:


/*-----------------------------------------------------------------------

 * mtdparts

 */

#define CONFIG_CMD_MTDPARTS

#define CONFIG_MTD_DEVICE

#define MTDIDS_DEFAULT           "nand0=smdk2440-0"  

#define MTDPARTS_DEFAULT       "mtdparts=smdk2440-0:256k(u-boot),"       

                                          "128k(params),"                     

                                          "2m(kernel),"        

                                          "-(rootfs)"       


然后重新修改,之前设置的环境参数bootcmd(位于smdk2440.h):



#define CONFIG_BOOTCOMMAND "nand read  0x30000000 0x60000 0x200000; bootm 0x30000000" //bootcmd


改为:


#define CONFIG_BOOTCOMMAND "nand read  0x30000000 kernel; bootm 0x30000000"    //bootcmd


5)修改好后,我们还需要在board_init_r()函数里的for(;;)前面添加(位于arch/arm/lib/board.c):


  run_command("mtdparts default", 0);       //添加此处代码

 

       for (;;) {

              main_loop();

       }


这样uboot每次启动时,都会执行一次mtdparts default命令,使它根据默认参数来自动分区.


mtdparts命令就此设置好了


接下来,便重新烧写uboot,来测试


5.测试mtdparts分区


输入mtdparts,查看默认分区名称:

如上图所示,接下来我们便可以直接使用kernel名字来擦除kernel分区,并烧写内核了


步骤如下:


tftp 30000000 uImage

nand erase.part kernel      //等于nand erase 200000    60000

nand write 30000000 kernel  //从sdram拷贝到nand


推荐阅读

史海拾趣

Ampire Co Ltd公司的发展小趣事

Ampire Co., Ltd. 是一家总部位于中国深圳的汽车电子产品制造商,专注于汽车安全、娱乐和舒适性电子产品的研发、生产和销售。以下是关于 Ampire 公司发展的五个相关故事:

  1. 成立与初创阶段:Ampire 公司成立于 2002 年,起初主要从事汽车电子产品的贸易业务。公司的创始人致力于在汽车行业提供高品质的电子产品,以提升驾驶体验和车辆安全性。在公司初期,他们主要进口和销售一些汽车音响和影音产品。

  2. 技术创新与产品升级:随着市场需求的不断变化和技术的进步,Ampire 公司开始注重技术创新和产品升级。公司加大了对汽车安全和行车辅助系统的研发投入,推出了一系列高品质的后视摄像头、倒车雷达、行车记录仪等产品,以提高车辆的安全性和驾驶便利性。

  3. 品牌建设与市场拓展:Ampire 公司通过不断提升产品质量和服务水平,逐渐树立起了良好的品牌形象,并在国内外市场上获得了良好的口碑和知名度。公司积极参加国内外汽车电子展会和行业活动,拓展了国际市场,产品出口至欧美、东南亚等多个国家和地区。

  4. 生产基地建设与产能提升:为满足不断增长的市场需求,Ampire 公司逐步扩大了生产基地,并引进了先进的生产设备和技术。公司建立了完善的生产制造体系,实现了规模化生产和产能提升,保障了产品质量和交货期。

  5. 持续发展与未来规划:Ampire 公司持续致力于技术创新和产品升级,不断推出符合市场需求的新品。未来,公司计划进一步加大在汽车安全、智能驾驶和车载娱乐等领域的研发投入,积极探索人工智能、互联网车联网等新技术的应用,为客户提供更加智能、安全和便捷的汽车电子产品。

这些故事展示了 Ampire 公司从创立初期到如今在技术创新、产品升级、品牌建设、生产基地建设以及未来规划等方面取得的重要进展。

Golledge Electronics公司的发展小趣事

Golledge Electronics公司的发展故事

故事一:石英晶体振荡器的创新起点

Golledge Electronics公司的起源可以追溯到对石英晶体振荡器技术的深入研究和创新。公司最初成立于英国水晶产区的中心,依托当地丰富的水晶资源,Golledge迅速成为石英晶体振荡器领域的佼佼者。公司创始人敏锐地意识到石英晶体的压电特性在电子系统中的重要应用价值,于是投入大量资源进行研发。通过不断优化晶体制造工艺和温度补偿技术,Golledge成功推出了高精度、高稳定性的石英晶体振荡器,为无线电通信、卫星通信等领域提供了关键技术支持。这一创新不仅奠定了Golledge在电子行业的基础,也为其后续发展铺平了道路。

故事二:微机电系统(MEMS)技术的突破

随着电子产品的不断小型化和便携化,Golledge Electronics公司紧跟时代步伐,将研发重点转向微机电系统(MEMS)技术。MEMS谐振器以其紧凑的尺寸和稳健的性能,成为便携式设备和可穿戴设备中的理想选择。Golledge通过自主研发和合作创新,成功将MEMS技术应用于频率控制产品中,推出了多款高性能、低功耗的MEMS谐振器。这些产品不仅满足了市场对小型化、轻量化的需求,还进一步提升了电子系统的整体性能和可靠性。Golledge在MEMS技术领域的突破,为其在电子行业中的领先地位增添了新的动力。

故事三:新材料应用的探索

为了不断提升产品的性能和质量,Golledge Electronics公司始终致力于新材料的研发和应用。公司研发团队通过深入研究石英晶体的物理特性和化学性质,成功开发出了一系列具有独特性能的石英晶体材料。这些新材料不仅具有更高的稳定性和频率精度,还能够在极端环境下保持优异的性能表现。Golledge将这些新材料应用于频率控制产品中,显著提升了产品的竞争力和市场占有率。同时,公司还积极探索其他新型材料的应用潜力,为未来的技术创新储备了丰富的资源。

故事四:机器学习集成的创新实践

随着人工智能技术的快速发展,Golledge Electronics公司敏锐地捕捉到这一趋势,并积极探索机器学习在频率控制领域的应用。公司研发团队通过集成机器学习算法,使频率控制系统能够动态地适应和优化频率设置。这一创新实践不仅确保了频率控制系统的持续准确性,还为其赋予了自我学习和自我优化的能力。Golledge的这一创新成果,不仅提升了产品的智能化水平,也为电子行业的未来发展提供了新的思路和方向。

故事五:超微型SMD晶体的商用化

为了满足市场对更小、更轻、更高效的电子产品的需求,Golledge Electronics公司推出了超微型1610mm封装SMD晶体,并成功实现商用化。这款晶体以其极小的尺寸和优异的性能,迅速赢得了市场的青睐。Golledge通过不断优化生产工艺和质量控制体系,确保了超微型SMD晶体的稳定供应和高质量表现。这款产品的成功商用,不仅进一步巩固了Golledge在电子行业中的地位,也为其在小型化、便携化电子产品领域的发展开辟了新的市场空间。

ECLIPSE公司的发展小趣事

2001年,IBM公司决定推动一个开源项目,旨在打造一个全新的集成开发环境。这个项目名为Eclipse,旨在通过开放源代码的方式,吸引全球开发者共同参与。Eclipse的初始版本发布后,凭借其优秀的性能和友好的界面,迅速在开发者社区中引起了关注。

Analogic Corporation公司的发展小趣事

Eclipse的成功离不开其强大的社区支持。Eclipse社区拥有众多的开发者、测试者和用户,他们共同为Eclipse的发展贡献力量。通过举办开发者大会、在线论坛和邮件列表等方式,Eclipse社区为开发者们提供了一个交流学习的平台。在这个平台上,开发者们可以分享经验、解决问题,共同推动Eclipse的发展。

ATP [ATP Electronics]公司的发展小趣事

ATP深知,优质的产品需要优质的服务来支撑。因此,公司一直致力于提升客户服务水平,为客户提供最优质的产品、最具竞争力的价格和最优质的服务。ATP通过建立完善的售后服务体系,及时解决客户在使用过程中遇到的问题,赢得了客户的信任和好评。同时,公司还积极开展市场调研,了解客户需求,不断优化产品和服务,以满足市场的不断变化。

这五个故事展示了ATP Electronics在电子行业中的发展历程和取得的成就。通过技术创新、推出工业级产品、践行环保理念、实施全球化战略以及提升优质服务,ATP成功地在激烈的市场竞争中脱颖而出,成为了闪存卡市场的领军企业。

功得(CONQUER)公司的发展小趣事

在追求经济效益的同时,功得公司也积极履行社会责任。他们关注环保问题,采用环保材料和工艺生产产品;关注员工福利,为员工提供良好的工作环境和福利待遇;关注社会公益事业,积极参与各种慈善活动。这些举措使得功得公司在社会上树立了良好的形象,也为公司的长远发展提供了有力保障。

问答坊 | AI 解惑

帮忙广州哪里买单片机和学习板比较便宜?

帮忙广州哪里买单片机和学习板比较便宜?…

查看全部问答>

关于如何获得 camera 的资料问题.

本人想知道 nokia 内置camera的生产厂商,比如 型号为nokia 3220的内置camera型号是什么?生产厂商,以及如何获得这些成熟产品零部件的详细datasheet,除了拆装,还有什么其它方法, 还有一款是索爱的外置camera,MCA_25,我在网上找它的camera型号及资 ...…

查看全部问答>

AVR单片机+CPLD体系在测频电路中的应用

通过制成的实物验证CPLD 与单片机接口设计完全正确。单片机和 CPLD 具有很强的互补性:在逻辑运算、智能控制方面,单片机具有不可替代的优越性;而在高速稳定等方面,CPLD 无疑是首选。因此,在目前的电子设计中,充分利用单片机+CPLD 结构将起到 ...…

查看全部问答>

如果用单片机上电配置FPGA~~

如果用单片机上电配置FPGA~~1,我用Quartus II 8.1 (32-Bit)编译生成.POF文件,接下来怎样转换为可用于单片机配置的文件A,用什么工具转换? 2,转换后的文件A是不是直接烧进单片机就可以? 本人初学FPGA,关于单片机怎样配置FPGA文件,在网上找 ...…

查看全部问答>

evc 几个对话框的小问题

我想请问。当我点击F1 返回上一个窗口。或者是销毁现在的窗口。去显示别的窗口。这样的代码应该怎么写啊。         if(pMsg->message   ==   WM_KEYDOWN)        {   &n ...…

查看全部问答>

关于文件过滤驱动的两个问题请教高人

1.关于驱动分层与过滤驱动的关系。我一直搞不清驱动分层与过滤驱动的分别,我现在自己的理解是:对于过滤驱动来说,它处理完截获的IRP后直接调用IoCallDriver发送给下一层设备,而对于分层驱动来说某一层的驱动完成IRP后使用IoCompleteRequest向IO ...…

查看全部问答>

小弟想学嵌入式,大牛能不能推荐几本书啊?(模拟电子,数电方面)

小弟想学嵌入式,大牛能不能推荐几本书啊? 小弟想学嵌入式,大牛能不能推荐几本书啊? 主要是做ARM方向的,也可能搞SOC 用VERILOG 硬件描述语言 模电,数电基础不是很好,(不是学这个专业的),大牛能不能推荐几本比较好的书啊? 另外还要看什么相 ...…

查看全部问答>

MSP430学习小记~~~~关于在IAR环境下使用MSP的中断。

前段时间一直用CCS,但是机器太差(06 年的笔记本),启动一次CCS的调试需要近2分钟。。。。。:funk:   于是换IAR5.10,速度确实提升不少。。。。。     今天使用IAR新建的工程调试MSP430的IO中断程序。整个中断程序如下: ...…

查看全部问答>

我心中的ST,不是做广告

ST微控制器,真的很不错,不仅仅是因为他的产品性能,还有它的后续服务;至今为止,可以说没有任何一家芯片厂商能做到像ST这样将芯片推广得如此深入人心。 完善的程序库,让客户在很短的时间内就能做产品开发; 丰富的应用案例,让不同的客 ...…

查看全部问答>

山寨IPHONE4 TFT屏破解

这个是我的山寨IPHONE4拆下来的彩屏照片,不知道什么型号和管脚顺序,有谁知道。…

查看全部问答>