历史上的今天
返回首页

历史上的今天

今天是:2025年04月07日(星期一)

正在发生

2021年04月07日 | 详细讲解 移植Uboot到ARMer9开发系统上

2021-04-07 来源:eefocus

首先了解ARMer9开发系统硬件设计上和三星原装SMDK2410之间的区别。让uboot在ARMer9开发系统上跑起来,目前只需要关注如下的硬件区别,解决了下面这个问题,uboot就可以在ARMer9开发系统上正常地从串口输出,进入提示符。很多命令都可以使用,当然有些命令需要做修改。


SMDK2410 : nor flash 是AMD的1M的;


ARMer9: 是Intel E28F128J3A, 两片并联,一共32M Bytes.



下载一个uboot-1.1.1.tar.bz2.;



tar jxvf uboot-1.1.1.tar.bz2;


在uboot 目录board/smdk2410 下的flash.c需要修改。这个是Flash的驱动,如何写,需要参考E28F128J3A的Datasheet. 这里我们提供一个我们修改好的flash.c文件,您只需要将这个文件覆盖掉board/smdk2410 下的文件即可。


(注意:你要安装了交叉编译器才行哦)


修改uboot目录下的Makefile,将


ifeq ($(ARCH),arm)


CROSS_COMPILE = arm-linux-


endif



修改成



ifeq ($(ARCH),arm)


CROSS_COMPILE = /opt/host/armv4l/bin/armv4l-unknown-linux-


endif



修改processor.h中:


union debug_insn


{


u32 arm;


u16 thumb;


}


修改成:


union debug_insn


{


u32 arm_mode;


u16 thumb_mode;


}



然后配置板子


make smdk2410_config



然后


make



在uboot目录生成uboot.bin;



通过sjf2410w程序将uboot.bin下载到nor flash中, 地址为0的地方;



串口接在UART0上,uboot的启动信息将输出。



你将发现很多命令都可以使用了。uboot果然强大。



关于网络部分,因为ARMer9开发系统使用也是CS8900A,所以代码部分几乎不用做改动,只需要在 include/configs/smdk2410.h中看看,有没有定义CONFIG_ETHADDR,CONFIG_IPADDR, CONFIG_SERVERIP这些宏没有,如果没有,请定义好。





#define CONFIG_ETHADDR 00:00:e0:ff:cd:15



#define CONFIG_IPADDR 192.168.0.5



#define CONFIG_SERVERIP 192.168.0.100



就这样修改一下,网络部分功能就通了,哈哈。



可以使用tftpboot命令从tftp服务器下载程序到系统内存中。



#tftpboot 0x33000000 zImage



#bootm 0x33000000




利用uboot引导可执行映象的通用方法





uboot源代码的tools/目录下有mkimage工具,这个工具可以用来制作不压缩或者压缩的多种可启动映象文件。



mkimage在制作映象文件的时候,是在原来的可执行映象文件的前面加上一个0x40字节的头,记录参数所指定的信息,这样uboot才能识别这个映象是针对哪个CPU体系结构的,哪个OS的,哪种类型,加载内存中的哪个位置, 入口点在内存的那个位置以及映象名是什么



root@Glym:/tftpboot# ./mkimage


Usage: ./mkimage -l image


-l ==> list image header information


./mkimage -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image


-A ==> set architecture to 'arch'


-O ==> set operating system to 'os'


-T ==> set image type to 'type'


-C ==> set compression type 'comp'


-a ==> set load address to 'addr' (hex)


-e ==> set entry point to 'ep' (hex)


-n ==> set image name to 'name'


-d ==> use image data from 'datafile'


-x ==> set XIP (execute in place)


参数说明:



-A 指定CPU的体系结构:



取值 表示的体系结构


alpha Alpha


arm A RM


x86 Intel x86


ia64 IA64


mips MIPS


mips64 MIPS 64 Bit


ppc PowerPC


s390 IBM S390


sh SuperH


sparc SPARC


sparc64 SPARC 64 Bit


m68k MC68000



-O 指定操作系统类型,可以取以下值:


openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos



-T 指定映象类型,可以取以下值:


standalone、kernel、ramdisk、multi、firmware、script、filesystem



-C 指定映象压缩方式,可以取以下值:


none 不压缩


gzip 用gzip的压缩方式


bzip2 用bzip2的压缩方式



-a 指定映象在内存中的加载地址,映象下载到内存中时,要按照用mkimage制作映象时,这个参数所指定的地址值来下载



-e 指定映象运行的入口点地址,这个地址就是-a参数指定的值加上0x40(因为前面有个mkimage添加的0x40个字节的头)



-n 指定映象名



-d 指定制作映象的源文件



常用U-BOOT命令介绍


1. ?或者help,得到所有命令列表;


2. help: help usb, 列出USB功能的使用说明


3. ping:注:通常只能运行uboot的系统PING别的机器


4. setenv: 设置环境变量


setenv serverip 10.36.20.49,设置TFTP Server的IP地址;


setenv ipaddr 10.36.20.200,设置IP地址;


setenv bootcmd ‘tftp 32000000 vmlinux; kgo 32000000’,设置启动命令(实际上就是一个脚本);


5. saveenv:在设置好环境变量以后, 保存环境变量值到flash中间;


6. tftpboot:tftpboot 0x800000 vmlinux, 将TFTP Server(IP = 环境变量中设置的serverip)中/tftpdroot目录 下的vmlinux通过TFTP协议下载到物理内存0x800000开始的地方。


7. kgo:启动没有压缩的linux内核,kgo 0x800000


8. bootm:启动通过UBOOT TOOLS—— mkimage制作的压缩LINUX内核, bootm 3200000;


9 flinfo:列出flash的信息


10. protect: 对FLASH进行写保护或取消写保护, protect on 1:0-3(就是对第一块FLASH的0-3扇区进行保护),protect off 1:0-3取消写保护


11. erase: 删除FLASH的扇区, erase 1:0-2(就是对每一块FLASH的0-2扇区进行删除)


12. cp: 将内存中数据烧写到Flash, cp 0x800000 0xc0000 0x40000(把内存中0x800000开始的0x40000字节复制到0xc0000处);


13. mw: 对RAM中的内容进行写操作, mw 32000000 ff 10000(把内存0x32000000开始的0x10000字节设为0xFF);


14. md: 显示RAM中的内容, md 0x800000;


15. loadb: 准备用 KERMIT协议接收来自kermit或超级终端传送的文件。


16. nfs: nfs 32000000 192.168.0.2:aa.txt , 把192.168.0.2(LINUX 的NFS文件系统)中的NFS文件系统中的aa.txt 读入内存0x32000000处。


17. fatls:列出DOS FAT文件系统, 如:fatls usb 0列出第一块U盘中的文件


18. fatload: 读入FAT中的一个文件,如:fatload usb 0:0 32000000 aa.txt


19. usb相关的命令:


usb start: 起动usb 功能


usb info: 列出设备


usb scan: 扫描usb storage(u 盘)设备



Uboot对SMDK2410板的NAND Flash初始化部分没有写,





即lib_arm/board.c中的start_armboot函数中有这么一句:


#if (CONFIG_COMMANDS & CFG_CMD_NAND)


puts ("NAND:");


nand_init(); /* go init the NAND */


#endif


但是在board/smdk2410目录下任何源文件中都没有定义nand_init这个函数。


所以需要我们补充这个函数以及这个函数涉及的底层操作。



我们可以仿照VCMA9板的nand_init函数,VCMA9板是一款用S3C2410做CPU的DEMO Board,因此这部分操作和SMDK2410 Demo Board很相似。大部分代码可以照搬。



首先将board/mpl/vcma9/vcma9.c中下面代码拷贝到board/smdk2410/ smdk2410.c中来。


/*


* NAND flash initialization.


*/


#if (CONFIG_COMMANDS & CFG_CMD_NAND)


extern ulong


nand_probe(ulong physadr);




static inline void NF_Reset(void)


{


int i;



NF_SetCE(NFCE_LOW);


NF_Cmd(0xFF); /* reset command */


for(i = 0; i < 10; i++); /* tWB = 100ns. */


NF_WaitRB(); /* wait 200~500us; */


NF_SetCE(NFCE_HIGH);


}




static inline void NF_Init(void)


{


#if 0 /* a little bit too optimistic */


#define TACLS 0


#define TWRPH0 3


#define TWRPH1 0


#else


#define TACLS 0


#define TWRPH0 4


#define TWRPH1 2


#endif



NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));


/*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */


/* 1 1 1 1, 1 xxx, r xxx, r xxx */


/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */



NF_Reset();


}



void


nand_init(void)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



NF_Init();


#ifdef DEBUG


printf("NAND flash probing at 0x%.8lXn", (ulong)nand);


#endif


printf ("%4lu MBn", nand_probe((ulong)nand) >> 20);


}


#endif



再将board/mpl/vcma9/vcma9.h中下面代码拷贝到board/smdk2410/ smdk2410.c中来。


#if (CONFIG_COMMANDS & CFG_CMD_NAND)


typedef enum {


NFCE_LOW,


NFCE_HIGH


} NFCE_STATE;





static inline void NF_Conf(u16 conf)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



nand->NFCONF = conf;


}



static inline void NF_Cmd(u8 cmd)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



nand->NFCMD = cmd;


}



static inline void NF_CmdW(u8 cmd)


{


NF_Cmd(cmd);


udelay(1);


}



static inline void NF_Addr(u8 addr)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



nand->NFADDR = addr;


}



static inline void NF_SetCE(NFCE_STATE s)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



switch (s) {


case NFCE_LOW:


nand->NFCONF &= ~(1<<11);


break;



case NFCE_HIGH:


nand->NFCONF |= (1<<11);


break;


}


}



static inline void NF_WaitRB(void)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



while (!(nand->NFSTAT & (1<<0)));


}



static inline void NF_Write(u8 data)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



nand->NFDATA = data;


}



static inline u8 NF_Read(void)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



return(nand->NFDATA);


}



static inline void NF_Init_ECC(void)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



nand->NFCONF |= (1<<12);


}



static inline u32 NF_Read_ECC(void)


{


S3C2410_NAND * const nand = S3C2410_GetBase_NAND();



return(nand->NFECC);


}



#endif



再将include/configs/vcma.9中下面代码拷贝到include/configs/smdk2410.h中来。



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


* NAND flash settings


*/


#if (CONFIG_COMMANDS & CFG_CMD_NAND)



#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */


#define SECTORSIZE 512



#define ADDR_COLUMN 1


#define ADDR_PAGE 2


#define ADDR_COLUMN_PAGE 3



#define NAND_ChipID_UNKNOWN 0x00


#define NAND_MAX_FLOORS 1


#define NAND_MAX_CHIPS 1



#define NAND_WAIT_READY(nand) NF_WaitRB()



#define NAND_DISABLE_CE(nand) NF_SetCE(NFCE_HIGH)


#define NAND_ENABLE_CE(nand) NF_SetCE(NFCE_LOW)




#define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d)


#define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)


#define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d)


#define WRITE_NAND(d, adr) NF_Write(d)


#define READ_NAND(adr) NF_Read()


/* the following functions are NOP's because S3C24X0 handles this in hardware */


#define NAND_CTL_CLRALE(nandptr)


#define NAND_CTL_SETALE(nandptr)


#define NAND_CTL_CLRCLE(nandptr)


#define NAND_CTL_SETCLE(nandptr)



#define CONFIG_MTD_NAND_VERIFY_WRITE 1


#define CONFIG_MTD_NAND_ECC_JFFS2 1



#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */



在include/configs/smdk2410.h中下面命令定义部分将CFG_CMD_NAND开关放开。



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


* Command definition


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


#define CONFIG_COMMANDS


(CONFIG_CMD_DFL |


CFG_CMD_CACHE |


/*CFG_CMD_NAND |*/


/*CFG_CMD_EEPROM |*/


/*CFG_CMD_I2C |*/


/*CFG_CMD_USB |*/


CFG_CMD_REGINFO |


CFG_CMD_DATE |


CFG_CMD_ELF)



U-BOOT源代码目录结构介绍





board:和一些已有开发板有关的文件,比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。


common:与体系结构无关的文件,实现各种命令的C文件。


cpu: CPU相关文件,其中的子目录都是以U-BOOT所支持的CPU为名,比如有子目录arm926ejs、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c和interrupt.c,start.S。其中cpu.c初始化CPU、设置指令Cache和数据Cache等; interrupt.c设置系统的各种中断和异常,比如快速中断、开关中断、时钟中断、软件中断、预取中止和未定义指令等;start.S是U-BOOT 启动时执行的第一个文件,它主要是设置系统堆栈和工作方式,为进入C程序奠定基础。


disk:disk驱动的分区处理代码。


doc:uboot移植的技术支持文档。


drivers:通用设备驱动程序,比如各种网卡、支持CFI的Flash、串口和USB总线等。


fs:支持文件系统的文件,U-BOOT现在支持cramfs、fat、fdos、jffs2和registerfs。


include:头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。


net:与网络有关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。


lib_arm:与ARM体系结构相关的代码。


lib_generic:与体系结构无关的通用例程的代码。


tools:创建S-Record格式文件 和U-BOOT images的工具的源代码。



U-BOOT的特点



U-BOOT支持SCC/FEC以太网、OOTP/TFTP引导、IP和MAC的预置功能, 这方面可能和其它BootLoader(如BLOB、RedBoot、vivi等)类似。但U-BOOT还具有一些特有的功能。



◆ 在线读写Flash、DOC、IDE、IIC、EEROM、RTC,其它的BootLoader根本不支持IDE和DOC的在线读写。


◆ 支持串行口kermit和S-record下载代码,U-BOOT本身的工具可以把ELF32格式的可执行文件转换成为 S-record格式,直接从串口下载并执行。


◆ 识别二进制、ELF32、uImage格式的Image,对Linux引导有特别的支持。U-BOOT对Linux 内核进一步封装为uImage。封装如下:


#{CROSS_COMPILE}-objcopy -O binary -R.note -R.comment -S vmlinux linux.bin


#gzip -9 linux.bin


#tools/mkimage -A arm -O linux -T kernel -C gzip -a 0xc0008000 –e 0xc0008000 -n “Linux-2.4.20” -d linux.bin.gz /tftpboot/uImage


即在Linux内核镜像vmLinux前添加了一个0x40个字节的特殊头,这个头在include/image.h中定义,包括目标操作系统的种类(比如 Linux,VxWorks等)、目标CPU的体系机构(比如ARM、PowerPC等)、映像文件压缩类型(比如gzip、bzip2等)、加载地址、入口地址、映像名称和映像的生成时间。当系统引导时,U-BOOT会对这个文件头进行CRC校验,如果正确,才会跳到内核执行。如下所示:


ARMer9# bootm 0xc1000000


## Checking Image at 0xc100000 ...


Image Name: Linux-2.4.20


Created: 2004-07-02 22:10:11 UTC


Image Type: ARM Linux Kernel Image (gzip compressed)


Data Size: 550196 Bytes = 537 kB = 0.55MB


Load Address: 0xc0008000


Entry Point: 0xc0008000


Verifying Checksum ... OK


Uncompressing Kernel Image ……… OK


◆ 单任务软件运行环境。U-BOOT可以动态加载和运行独立的应用程序,这些独立的应用程序可以利用U-BOOT控制台的I/O函数、内存申请和中断服务等。这些应用程序还可以在没有操作系统的情况下运行,是测试硬件系统很好的工具。


◆ 监控(minitor)命令集:读写I/O,内存,寄存器、内存、外设测试功能等。

推荐阅读

史海拾趣

Barnbrook Systems Limited公司的发展小趣事

随着技术的不断进步,Barnbrook意识到单一的电路板产品已经无法满足市场的多元化需求。于是,公司开始拓展产品线,逐步推出了包括服务器、存储设备以及网络设备在内的一系列电子产品。同时,Barnbrook也积极开拓国内外市场,通过参加国际电子展会、建立销售网络等方式,不断提升品牌知名度和市场份额。

灿科盟(Ckmtw)公司的发展小趣事

随着公司业务的不断扩展,灿科盟在2010年决定将生产基地从龙华搬迁至公明鑫博盛科技园,以满足日益增长的生产需求。同时,公司也在龙华设立了外贸业务分部,进一步拓展海外市场。这些举措不仅提升了公司的产能和竞争力,也为公司未来的发展奠定了坚实基础。

Green Solution Technology Co Ltd公司的发展小趣事

面对国内外市场变化及成本增长的压力,灿科盟在2012年决定在江西省九江市设立新的生产基地。这一基地主要负责产品的生产组装,有效降低了生产成本,提高了交货速度。同时,公司也加强了与当地供应商的合作,确保原材料的稳定供应。

FTCAP Fischer & Tausche Capacitor Group公司的发展小趣事

为了提升产品质量,增强客户信任,灿科盟在2008年成功通过了ISO9001:2000版质量管理体系认证。这一认证标志着公司在质量管理方面达到了国际标准,也为公司赢得了更多客户的青睐。此后,公司继续加强质量管理体系建设,不断提升产品质量和服务水平。

COTO TECHNOLOGY公司的发展小趣事

进入上世纪六十年代,COTO TECHNOLOGY迎来了一个重大的转折点。公司开始探索线圈绕组以外的领域,通过引入簧片继电器,成功扩展了产品线。这一创新举措不仅丰富了公司的产品种类,更重要的是,它为公司打开了新的市场领域。到了七十年代,COTO更是凭借开发出的首款获得专利的低热电动势簧片继电器,一跃成为业界领先的干簧继电器制造商。

飞翼科技(FEIYI)公司的发展小趣事

进入上世纪六十年代,COTO TECHNOLOGY迎来了一个重大的转折点。公司开始探索线圈绕组以外的领域,通过引入簧片继电器,成功扩展了产品线。这一创新举措不仅丰富了公司的产品种类,更重要的是,它为公司打开了新的市场领域。到了七十年代,COTO更是凭借开发出的首款获得专利的低热电动势簧片继电器,一跃成为业界领先的干簧继电器制造商。

问答坊 | AI 解惑

车载数码系统

车载GPS导航系统:        对于GPS系统,有一部分人也许已经不是很陌生了,虽然它一开始是为军事目的而建立的,但很快在民用方面得到了极大的发展。      车载GPS导航仪可以24小时不间断地接收卫星发 ...…

查看全部问答>

【藏书阁】半导体器件——OHM 大学理工系列

目录 第1章半导体器件的发展 1·1电子器件发展历程中的“潮流与波浪” 1·2从体单晶时代向多层化薄膜器件时代的发展 练习题 第2章半导体的电学性质 2·1半导体的导电率 2·2晶体中电子的有效质量 2·3电子状态密度 2·4载流子密度与温度 ...…

查看全部问答>

vhdl--万年历

我用循环总是在编译阶段卡住!也不报错! 能不能不用循环,给个算发吧! 要使用循环能编出来也行! 只求算法不求具体过程!谢谢!…

查看全部问答>

WINCE5.0+EVC变量值被修改?内存问题?

程序中用部分“全局变量”,调试过程中发现被修改了,大家碰到过吗?环境是WINCE5.0NET +EVC。比如定义一个BOOL BLOOP=TRUE; 运行一段时间后,发现BLOOP变成FALSE了,导致程序出问题。…

查看全部问答>

会硬件开发和单片机的来,有项目要开发

寻GPS导航原理图和PCB图 http://www.365huo.com/bbs/read.php?tid=38105 [南京]基于LINUX上的小应用程序开发 http://www.365huo.com/bbs/read.php?tid=38106 熟悉开发研华pcm-4862工控板的人(急) http://www.365huo.com/bbs/read.php?tid=38 ...…

查看全部问答>

具有充放电保护的家用高亮度LED应急灯

1.        设计思路和产品功能: 应急照明灯主要由蓄电池、控制电路电路板、外壳、灯头或安装光源的灯体组成。电路的设计和LED驱动器将成为影响灯具性能的重要因素。要使灯具光源保持较高的亮度,必须选择合适的光源种类及功 ...…

查看全部问答>

邵贝贝的uCOS-II的中文教程

现在我把邵贝贝的这本资料传上来,希望对大家有用!很好的关于uCOS-II的资料,不看后悔呦,~亲…

查看全部问答>

超声波测水位

各位高手,这是我写的用超声波水位的程序,这是我根据别人的程序修改的。现在是没啥反应。没啥显示的。我用的是两位的数码管。麻烦指点一下! /***************************************************************************** * 晶   ...…

查看全部问答>

上传一个ST-LINK更新固件软件

从网上找地,本来我的ST-LINK很旧了,新版MDK说我固件老,我从网上找下了这个,老好了,我现在可以在MDK4.6下用ST-LINK了,不敢独享放到这里造福网友及需要的人 用法是把ST-LINK 插入U口,然后打开软件,点更新就完了,都是全自动地…

查看全部问答>

一台计算机能不能同时调试两块LaunchPad?

一台计算机能不能同时调试两块LaunchPad? 不知道端口怎样识别的?开发环境中能不能设置?…

查看全部问答>