初学嵌入式Linux,感觉需要学习的东西太多了。把学习过程中的收获和问题记录在这里,算是一份经验吧。
2006-08-10 前面利用开发板带的现成的东西step by step让Linux
2.4.19在开发板上跑起来了,对于开发的流程也有了一定的认识。现在想对每一步进行详细深入的探讨,好好学习一下,把笔记记录下来,省得忘记了。有些
内容是从看过的书中摘要过来的,大部分是自己实践后的心得。我想记得详细点,也好为后面总结打好基础。
先谈一下对于嵌入式开发流程和嵌入式开发环境拓扑结构的认识。刚开始比较盲目,看得书也不多,现在才算是大体上有了些了解。从开发产品的角度简单的描述如下:一、嵌入式开发流程简介
假设我们现在进行一项嵌入式开产品的开发,比如说智能电力系统终端,那么我想首先应该对完整的开发流程有一个大致的了解,才不致于在以后的工作中被动。下面对嵌入式linux开发简单的介绍一下。
1、系统的需求分析
2、硬件平台的选择和设计
3、软件开发
(3-1)建立开发环境。
(3-2)引导装载程序。
(3-3)内核裁减与编译。
(3-4)建立文件系统。
(3-5)应用程序开发。 图1因为我想要做的是软件开发,所以对前两步就不作深入探索了。只想要对软件开发的每一步熟悉起来,让我定制的系统跑得稳定,开发的程序能很好的完成其功能。这是个很艰巨的任务,万里长征刚刚走了第一步:)二、嵌入式开发环境拓扑结构简介
嵌入式开发环境一般由:宿主机(Linux Server)、工作站、嵌入式目标系统(target board)和将它们连在一起的网络环境。
1、linux server:嵌入式linux内核编译、应用程序编译的公共平台,有单独的一台pc机充当,安装标准的linux操作系统,比如redhat,debian等等。
2、工作站:为普通局域网计算机,以支持小组项目开发。工作站一般安装windows,需要linux服务器时,可以从工作站远程登陆到linux server。
3、target board:这是需要开发的最终产品,可以根据需要与工作站连接(通常通过串口或者usb接口),或连至局域网。
4、工作站需要安装ftp客户端(cuteftp、flashfxp等)和telnet客户端程序(secureCRT等),linux服务器应该开通ftp和telnet服务,还有ssh。
综
述过程:开发人员在一台工作站进行操作,通过远程登陆的方式操作linux server,并且使用ftp在linux
server和工作站进行文件传输,同时target
board需要与网络连接,其串口与工作站的RS232接口连接。使用工作站上的超级终端作为嵌入式目标系统输入/输出端。
对于开发流程有了一定的了解后就有了目标,这样才能够不是太郁闷。我的开发环境:Windows XP SP2+VMWARE+RedHat 9.0首先规划一下,我先建立了一个用户armlinux,我的全部工作都是在这个用户根目录下完成。$pwd/home/armlinux$mkdir bootloader debug images software source kernel rootfiles sysapps tmp tools program$lsbootloader images program software sysapps tools
debug kernel rootfiles source tmp然后建立环境变量,直接在.bash_profile中改就可以了。
# .bash_profile # Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi # User specific environment and startup programs
export TARGET=arm-linux
export PRJROOT=/home/armlinux
export PREFIX=${PRJROOT}/tools
export TARGET_PREFIX=${PREFIX}/${TARGET}
export PATH=$PATH:$HOME/bin:$PREFIX/bin:/sbin:/usr/sbin:/usr/local/sbin unset USERNAME
这样在下一次进入此用户时,环境变量就生效了。如果想立刻生效,那么可以用下面的命令:$source .bash_profile。这种方法可以使这些环境变量在进入用户armlinux后就会成效,比较方便。 三、建立交叉编译环境这一步工作我已经很顺利的完成了。刚开始时,手动建立交叉编译工具链,很困难,出现了很多问题,幸亏网上有不少的
资料可以参考。关于手动建立交叉编译工具链的过程我已经做了总结,放到blog上了。现在可以获得已经编译好的工具链,这样比较方便些,毕竟几个小时的手
动建立过程太繁琐,太容易出错了。3.1 获取交叉编译工具链网站:http://www.arm.linux.org.uk在linux server上以ftp方式登陆:#ftp ftp.arm.linux.org.uk这是系统提示输入用户名和密码,不要随便输,那样可能会连接失败。该ftp站点是允许匿名访问的,所以你可以用下面的用户名:anonymous登陆,密码无,直接回车就可以了。进入后执行:ftp>cd pub/armlinux/toolchain/ftp>binftp>get cross-2.95.3.tar.bz2ftp>get cross-3.0.tar.bz2ftp>get cross-3.2.tar.bz2ftp>get READMEftp>byeLinux 2.4.xx及其以下的内核源码用2.95.3的交叉编译器来编译就可以了;而2.6.xx的内核源码一般要用到cross-3.x以上的版本来编译。所以我全都下载下来了,备用。若下載速度慢,可選擇在windows下用迅雷下載,速度很快。
要想用更新的版本,则可以到网站ftp://ftp.handhelds.org/projects/toolchain下载,这里可以下在到cross-3.3.2和cross-3.4.1,默认路径是/usr/local/arm/<版本号>。从手动编译就可以知道,根据环境变量PREFIX指定了安装目标文件夹,那么上面提供的编译好的工具链也必须安装到指定的文件夹才可以使用。可以在README中知道安装方法:
This works for both gcc-2.95.3 and gcc-3.0.How to install: cd /usr/local
mkdir arm
cd arm
tar Ixvf cross-<version>.tar.bz2Add /usr/local/arm/<version>/bin to your path to use the cross compiler.
在Linux下面要养成看README、INSTALL文件的习惯,虽然是英文,但是写得都比较具体,比较简洁,没有很困难的。明确了方法就比较简单了。#mkdir /usr/local/arm#cd /usr/local/arm#tar jxvf cross-2.95.3.tar.bz2然后添加路径:$cd$ls -a$vi .bash_profile
# .bash_profile# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi# User specific environment and startup programs
export TARGET=arm-linux
export PRJROOT=/home/armlinux
export PREFIX=${PRJROOT}/tools
export TARGET_PREFIX=${PREFIX}/${TARGET}
export PATH=$PATH:$HOME/bin:$PREFIX/bin:/usr/local/arm/2.95.3/bin:/sbin:/usr/sbin:/usr/local/sbinunset USERNAME
修改好後,終端執行命令:
$. .bash_profile //讓配置文件生效
看见红色的行就是修改好的。只需要把你的路径添加到后面就可以了。这样可以验证一下了。
验证:$cd$cd program$vi hello.c-------------------------------------------#include <stdio.h>int main()
{
int i;
for(i=1;i<9;i++)
printf("Hello World %d times!\n",i);
}--------------------------------------------保存后退出。$arm-linux-gcc hello.c -o hello-arm$file hello-armhello-arm: ELF 32-bit LSB executable, ARM, version 1
(ARM), for GNU/Linux 2.0.0, dynamically linked (uses shared libs), not
stripped这就说明生成的hello-arm是可以工作在ARM平台上的,也证明了你的交叉编译工具链是有效并且可用的。在下载的2.95.3的工具链中没有包含调试工具gdb和目标板的gdbserver。在这里一起搭建好。首先从ftp://ftp.gnu.org/gnu/gdb中获得gdb套件。解压缩关于路径就不多说了。$cd$cd debug$mkdir build-gdb build-gdbserver$cd$cd software$../source/gdb-5.2.1/configure --target=$TARGET --prefix=$PREFIX$make$make install这样就可以顺利的完成gdb-5.2.1的安装了。要想对目标板进行交叉编译,gdb显得太大了些,所以需要gdbserver。下面建立gdbserver。$cd$cd debug/build-gdbserver$chmod +x ../../source/gdb-5.2.1/gdb/gdbserver/configure$CC=arm-linux-gcc ../../source/gdb-5.2.1/gdb/gdbserver/configure --host=$TARGET --prefix=$TARGET_PREFIX$make
$make installn=`echo gdbserver | sed 's,x,x,'`; \
if [ x$n = x ]; then n=gdbserver; else true; fi; \
/usr/bin/install -c gdbserver /home/armlinux/tools/arm-linux/bin/$n; \
/usr/bin/install -c -m 644 ../../software/gdb-5.2.1/gdb/gdbserver/gdbserver.1 /home/armlinux/tools/arm-linux/man/man1/$n.1
/usr/bin/install: 无法创建一般文件‘/home/armlinux/tools/arm-linux/bin/gdbserver’: 没有那个文件或目录
/usr/bin/install: 无法创建一般文件‘/home/armlinux/tools/arm-linux/man/man1/gdbserver.1’: 没有那个文件或目录
make: *** [install-only] Error 1此处错误不难理解,主要是因为交叉编译工具放到/usr/local/arm里面了。前面的安装目录tools里面缺少几个文件夹,只需要建立就可以了。$cd $PRJROOT/tools$mkdir arm-linux$cd arm-linux$mkdir bin man$cd man $mkdir man1$cd $PRJROOT/debug/build-gdbserver$make install这样就没有问题了,当然也可以修改makefile,但是自己还没有学好shell语言,所以采取上述方法解决了。这样首先用strip处理一下,目的是gdbserver不需要附带上调试的信息,把它们都剥离去就是了。$arm-linux-strip $TARGET_PREFIX/bin/gdbserver/gdbserver$ls -l $TARGET_PREFIX/bin/总用量 24
-rwxr-xr-x 1 armlinux armlinux 23132 8月 10 11:33 gdbserver也就是说,gdbserver经过strip处理之后还剩下23KB多一点,已经挺小了,适合目标板了。附:在CU论坛上看到tree工具可以查看目录树,觉得不错。也想要安装一个。下面這個站點已經沒有tree-1.5.0.tgz。
有效的下載地址:http://linus.yhspatriot.net/cs/cs/assignments/q1/introToUnix.html
$cd$cd source$ftp mama.indstate.edu
Connected to mama.indstate.edu (139.102.70.201).
220 ProFTPD 1.3.0 Server (ProFTPD Default Installation) [139.102.70.201]
Name (mama.indstate.edu:armlinux): anonymous
331 Anonymous login ok, send your complete email address as your password.
Password:
230 Anonymous access granted, restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd linux/tree
250 CWD command successful
ftp> ls
227 Entering Passive Mode (139,102,70,201,149,53).
150 Opening ASCII mode data connection for file list
drwxr-xr-x 2 root root 4096 Jun 4 2001 binary
drwxr-xr-x 2 root root 4096 May 19 1999 slack
-rw-r--r-- 1 root root 406 Oct 11 1996 tree-1.1.lsm
-rw-r--r-- 1 root root 13135 Oct 11 1996 tree-1.1.tgz
-rw-r--r-- 1 root root 405 Jan 6 1997 tree-1.2.lsm
-rw-r--r-- 1 root root 16362 Jan 6 1997 tree-1.2.tgz
-rw-r--r-- 1 root root 436 Feb 21 2002 tree-1.3.lsm
-rw-r--r-- 1 root root 25060 Feb 21 2002 tree-1.3.tgz
-rw-r--r-- 1 root root 432 Feb 21 2002 tree-1.4b1.lsm
-rw-r--r-- 1 root root 27536 Feb 21 2002 tree-1.4b1.tgz
-rw-r--r-- 1 root root 27891 Mar 25 2002 tree-1.4b2.tgz
-rw-r--r-- 1 root root 432 Jun 18 2003 tree-1.4b3.lsm
-rw-r--r-- 1 root root 29366 Feb 6 2003 tree-1.4b3.tgz
-rw-r--r-- 1 root root 466 Aug 20 2004 tree-1.5.0.lsm
-rw-r--r-- 1 root root 26543 Aug 16 2004 tree-1.5.0.tgz
226 Transfer complete.
ftp> get tree-1.5.0.tgzftp> bye221 Goodbye.
在Windows下解壓tree-1.5.0.tgz,將解壓後的文件夾tree-1.5.0拷到/home/zhj1011/software下。
$cd /home/zhj1011/software/tree-1.5.0
$make$make install然后就可以了,安装路径查看makefile文件知道在/usr/local/bin,也可以用which查看。现在可以用tree命令来查看一下自己的目录结构了。示例:$cd$tree -L 1 //显示一级目录,当然也可以显示二级目录了。.
|-- bootloader
|-- debug
|-- images
|-- kernel
|-- program
|-- rootfiles
|-- software
|-- source
|-- sysapps
|-- tmp
`-- tools这样对自己的组织比较好。等用tree熟悉了,在补充它的用法。四、引导装载程序bootloader因为u-boot的功能比较强大,所以选择了u-boot。这几天想先研究研究它的代码,好好分析一下启动过程。原来做过一次,不过是利用原来开发板做好的,熟悉过程是可以,但是不明白原理仍然不行。这次要学习掌握原理部分。待续。。。。2006-08-14一、了解一下存储器的基本分类情况。
存储器的物理实质是一组或多组具备数据输入输出和数据存储功能的集成电路,用于充当设备缓存或保存固定的程序及数据。存储器按存储信息的功能可分为只读存储器ROM(Read Only Memory)和随机存储器RAM(Random Access Memory)。
图1 常见存储器分类
6 u-boot-1.1.1的移植自己先用u-boot-1.1.1,主要步骤如下:(1)下载u-boot-1.1.1http://sourceforge.net/projects/u-boot(2)解压用户:armlinux$mkdir bootloader$cd bootloader$tar jxvf ../source/u-boot-1.1.1.tar.bz2$cd u-boot-1.1.1(3)修改首先看一下结构$ tree -L 1 -d
.
|-- board 平台依赖,存放电路板相关的目录文件
|-- common 通用多功能函数的实现|-- cpu 平台依赖,存放cpu相关的目录文件|-- disk 通用。硬盘接口程序
|-- doc 文档
|-- drivers 通用的设备驱动程序,如以太网接口驱动
|-- dtt
|-- examples 应用例子
|-- fs 通用存放文件系统的程序
|-- include 头文件和开发板配置文件,所有开发板配置文件放在其configs里
|-- lib_arm 平台依赖,存放arm架构通用文件
|-- lib_generic 通用的库函数
|-- lib_i386 平台依赖,存放x86架构通用文件
|-- lib_m68k 平台依赖|-- lib_microblaze 平台依赖
|-- lib_mips 平台依赖|-- lib_nios 平台依赖
|-- lib_ppc平台依赖,存放ppc架构通用文件
|-- net 存放网络的程序
|-- post 存放上电自检程序
|-- rtc rtc的驱动程序
`-- tools 工具然后具体步骤为:(一)在board文件夹下面建立自己的开发板的文件夹。一般的,要选取与自己的开发板硬件设置最为接近的型号。
在u-boot-1.1.1中,已经支持at91rm9200,所以可以选取at91rm9200dk作为模板进行修改。设置你的开发板的名字,随意即
可,我的设置为:myboard。[armlinux@lqm u-boot-1.1.1]$ cd board[armlinux@lqm board]$ cp -R at91rm9200dk/ myboard/
[armlinux@lqm board]$ cd myboard
[armlinux@lqm myboard]$ ls
at91rm9200dk.c config.mk flash.c Makefile u-boot.lds(二)可以看到,这里共有5个文件。首先,要修改主文件的名字,即要把at91rm9200dk.c更改为
myboard.c。其次,要更改config.mk中TEXT_BASE的数值,与loader等一级bootloader的要一致。接下来,因为在
at91rm9200dk用的是AMD的flash,而我的开发板上用的是Intel的28F640J3,那么需要另外找Intel的flash.C,以
减少工作量。在这里,推荐用source
insight这个查看代码的工具。我是在win下面使用的,它可以很方便的读代码,并且查找调用函数等等的工作。在strong
ARM构架里有xm250,它的flash是Intel的,修改的东西并不是很多。需要注意的是,xm250的flash位宽是32,而我的位宽是16,
要根据这个进行相应的修改。最后,修改Makefile,主要是修改生成文件的名字。具体操作如下:[armlinux@lqm myboard]$ mv at91rm9200dk.c myboard.c
[armlinux@lqm myboard]$ cat config.mk
TEXT_BASE = 0x21f80000
[armlinux@lqm myboard]$ vi config.mk修改成:TEXT_BASE = 0x21f00000,然后保存退出。[armlinux@lqm myboard]$ vi Makefileinclude $(TOPDIR)/config.mkLIB = lib$(BOARD).aOBJS := myboard.o flash.o
SOBJS :=$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS) $(SOBJS)clean:
rm -f $(SOBJS) $(OBJS)[armlinux@lq
m myboard]$ rm flash.c
[armlinux@lqm myboard]$ cp ../xm250/flash.c ./
[armlinux@lqm myboard]$ ls
config.mk flash.c Makefile myboard.c u-boot.lds
[armlinux@lqm myboard]$ vi flash.c
34 #undef FLASH_PORT_WIDTH32 /*不定义位宽32*/
35 #define FLASH_PORT_WIDTH16 /*定义位宽16*/ 216 switch (value) {
217
218 case (FPW) INTEL_ID_28F128J3A:
219 info->flash_id += FLASH_28F128J3A;
220 info->sector_count = 128;
221 info->size = 0x01000000;
222 break; /* => 16 MB */
223
224 case (FPW) INTEL_ID_28F640J3A: /*就是这个芯片*/
225 info->flash_id += FLASH_28F640J3A;
226 info->sector_count = 64;
227 info->size = 0x00800000;
228 break; /* => 8 MB */ [armlinux@lqm myboard]$ cd ../..
[armlinux@lqm u-boot-1.1.1]$ vi Makefile#########################################################################
## AT91RM9200 Systems
#########################################################################at91rm9200dk_config : unconfig
@./mkconfig $(@:_config=) arm at91rm9200 at91rm9200dkmyboard_config : unconfig
@./mkconfig $(@:_config=) arm at91rm9200 myboard#########################################################################在这里,可以在命令模式下输入“/at91rm9200”快速查找
at91rm9200dk,仿照它的例子,写出自己板子的配置。注意的是,第二行开头要用TAB键,不是空格,否则报错。选项arm表示目标板架构,
at91rm9200表是片上系统,myboard是你自己的开发板名字。[armlinux@lqm u-boot-1.1.1]$ vi MAKEALL LIST_ARM9=" \
at91rm9200dk integratorcp integratorap \
omap1510inn omap1610h2 omap1610inn \
smdk2400 smdk2410 trab \
VCMA9 versatile myboard \
"(三)修改主要的配置文件。配置选项比较多,主要是配置cpu,波特率,flash和sdram的类型大小,环境变量的偏移量等等,容易出错。应该首先了解硬件情况,仔细对应芯片资料进行修改。[armlinux@lqm u-boot-1.1.1]$ cd include/configs
[armlinux@lqm configs]$ cp at91rm9200dk.h myboard.h
[armlinux@lqm configs]$ vi myboard.h
//行號和實際的myboard.h的行號有所偏差,認真修改好配置就可以了。
41 #define CONFIG_MYBOARD 1 目标板65 #define CONFIG_BOOTDELAY 5 u-boot延时等待时间110 #define CONFIG_NR_DRAM_BANKS 1 sdram banks,我的是一个
111 #define PHYS_SDRAM 0x20000000 sdram起始地址
112 #define PHYS_SDRAM_SIZE 0x2000000 sdram容量32MB121 #undef CONFIG_HAS_DATAFLASH 未用dataflash128 #define PHYS_FLASH_1 0x10000000
129 #define PHYS_FLASH_2 0x00000000 定义,flash.c用到,但实际并未起作用
130 #define PHYS_FLASH_SIZE 0x800000 flash容量8MB 131 #define CFG_FLASH_BASE PHYS_FLASH_1 flash起始地址别名
132 #define CFG_MAX_FLASH_BANKS 1 flash最大banks数
133 #define CFG_MAX_FLASH_SECT 64 扇区总数
134 #define PHYS_FLASH_SECT_SIZE (128*1024) 每个扇区128KB
135 #define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
136 #define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
137 #define CFG_FLASH_UNLOCK_TOUT (2*CFG_HZ)
138
139 #undef CFG_ENV_IS_IN_DATAFLASH
140
141 #ifdef CFG_ENV_IS_IN_DATAFLASH
142 #define CFG_ENV_OFFSET 0x20000
143 #define CFG_ENV_ADDR (CFG_DATAFLASH_LOGIC_ADDR_CS0 + CFG_ENV_OFFSET)
144 #define CFG_ENV_SIZE 0x2000 /* 0x8000 */
145 #else
146 #define CFG_ENV_IS_IN_FLASH 1
147 #define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x7e0000) /* 0x107E0000 */
148 #define CFG_ENV_SIZE 0x20000 环境变量占了一个扇区,共128KB149 #endif
150
151 #define CFG_SOFT_RESET 1 定义软复位,flash.c用到
152 #define CFG_LOAD_ADDR 0x21000000 /* default load address */160 #define CFG_PROMPT "U-boot> " 提示符名字,可任意改 [armlinux@lqm configs]$ cd ../..[armlinux@lqm u-boot-1.1.1]$ make myboard_config
Conf
iguring for myboard board...
[armlinux@lqm u-boot-1.1.1]$ make CROSS_COMPILE=arm-linux-
然后把生成的u-boot.bin保存,并且压缩一下得到u-boot.bin.gz。将这两个文件通过ftp传至windows上,通过SecureCRT来进行传输。
//u-boot.bin在目錄: u-boot-1.1.1下。
$gzip u-boot.bin //壓縮得到u-boot.bin.gz
这里注意,知道CROSS_COMPILE路径,前面设置环境变量时说到过。压缩命令为gzip <filename>利用交叉线将com1和开发板串口相连。首先设置为片内启动方式,上电。超级终端首先出现“CCCC”,这时利用modem协议传输loader.bin,成功后传输u-boot.bin。具体现象如下:--------------------------------------------------------------CCCCCCCCCCCC
正在开始 xmodem 传输。 按 Ctrl+C 取消。
正在传输 loader.bin...
100% 6 KB-I- AT91F_LowLevelInit(): Debug channel initialized 6 KB/s 00:00:01 0 错误loader 1.0 (Aug 8 2003 - 12:01:07)XMODEM: Download U-BOOT
CCCCCCCCCCCCC
正在开始 xmodem 传输。 按 Ctrl+C 取消。
正在传输 u-boot.bin...
100% 85 KB 6 KB/s 00:00:14 0 错误U-Boot downloaded successfullyU-Boot 1.1.1 (Aug 17 2006 - 14:07:56)U-Boot code: 21F00000 -> 21F156CC BSS: -> 21F198D0
RAM Configuration:
Bank #0: 20000000 32 MB
Flash: 8 MB
*** Warning - bad CRC, using default environmentIn: serial
Out: serial
Err: serial
U-boot> versionU-Boot 1.1.1 (Aug 17 2006 - 14:07:56)U-boot> printenv
bootdelay=5
baudrate=115200
stdin=serial
stdout=serial
stderr=serialEnvironment tes-------------------------------------------------------设定环境变量,当然这些也可以在include/configs/<your-board>.h里面定义。
U-boot> setenv ipaddr 192.168.1.100
U-boot> setenv serverip 192.168.1.106
U-boot> setenv ethaddr 36:B9:04:00:24:80注意:物理地址应该合法,在tools文件夹内有一个文件gen_eth_addr.c,利用其生成可执行文件则能够获得有效的mac地址。你可以先用gcc编译,生成可执行文件,然后执行,获得合法的mac地址。
U-boot> saveenv
Saving Environment to Flash...
Un-Protected 1 sectors
Erasing Flash...
Erasing sector done
Erased 1 sectors
Writing to Flash...\done
Protected 1 sectorsU-boot> tftpboot 20000000 boot.bin
TFTP from server 192.168.1.106; our IP address is 192.168.1.100
Filename 'boot.bin'.
Load address: 0x20000000
Loading: ###
done
Bytes transferred = 10628 (2984 hex)U-boot> protect off 1:0
Un-Protect Flash Sectors 0-0 in Bank # 1
U-boot> erase 1:0
Erase Flash Sectors 0-0 in Bank # 1
Erasing sector 0 ... done
U-boot> cp.b 20000000 10000000 2984
Copy to Flash...-doneU-boot> tftpboot 20000000 u-boot.bin.gz
TFTP from server 192.168.1.106; our IP address is 192.168.1.100
Filename 'u-boot.bin.gz'.
Load address: 0x20000000
Loading: #########
done
Bytes transferred = 43791 (ab0f hex)
U-boot> cp.b 20000000 10010000 ab0f
Copy to Flash...\done断电重启,从片外启动。 这时遇到了一个问题,就是从flash启动时,总是提示:*** Warning - bad CRC, using default environment,具体解决方法:
现象:配置好u-boot,在RAM里正常启动如下:--------------------------------U-Boot 1.1.2 (Aug 17 2006 - 14:07:56) U-Boot code: 21F00000 -> 21F156CC BSS: -> 21F198D0
RAM Configuration:
Bank #0: 20000000 32 MB
Flash: 8 MB
*** Warning - bad CRC, using default environmentIn: serial
Out: serial
Err: serial
U-boot>--------------------------------flash读写擦除均正常,当设置好环境变量,固化到flash之后,启动仍然如上,即总是提示“*** Warning - bad CRC, using default environment”。使用md查看环境变量所在63扇区,发现设置的环境变量仍然在。问题解决:通过分析u-boot的启动流程,调试代码,得知问题出在cpu/at91rm9200/start.S中。其中有一段代码:-------------------- ldr r0, =_start
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyex--------------------它的作用是把中断向量表从flash reload到RAM,以提高速度。但是它没有进行remap。故而使得u-boot启动之后无法寻找到环境变量所在的第63扇区。更改如下:--------------------if 0 ldr r0, =_start
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyexendif--------------------即把此段代码注释掉。【或者是在此段前面加上remap部分,不过如果加上remap,则需要把前面的设置svc部分的代码注释掉,否则在u-boot>reset时会进入异常状态。】此解决方案对u-boot-1.1.2也有效。U-Boot 1.1.1 (Aug 17 2006 - 16:50:31)U-Boot code: 21F00000 -> 21F157F4 BSS: -> 21F199F4
RAM Configuration:
Bank #0: 20000000 32 MB
Flash: 8 MB
In: serial
Out: serial
Err: serial
U-Boot>经验证,这是u-boot-1.1.1已经能够正常启动了。---------------------------同样的方法,u-boot-1.1.2也正常启动了。另外,u-boot-1.1.2有几个小的补丁,等明天再做
一下总结。同时看看如何制作补丁,如何打补丁。具体的调试过程没有写得很仔细,要想做好一项工作,只会写程序远远不够,更为重要的是会调试。我需要加强此
方面的工作。明天把JEDI probe调试环境的建立也总结一下。2006-08-18今天学习了一下Linux下面patch的制作和使用,做了总结,放到blog上面。u-boot-1.1.2有几个diff补丁文件,具体没有分析,先附在这里。我的使用倒是还没有发现这几个问题,也许没有测试,不管它,以后如果出现问题在来仔细考虑吧。开发板由王老师用,我先学习内核裁减吧。关于移植版本,不一定非得越高越好。关于内核版本标号问题,详细参考
《Building Embedded Linux
Systems》。现在还不开发产品,那么先多试用几个,总结总结经验。初步打算先移植一个2.4.x版本,然后移植一个2.6.x版本。-----------------------------Bug1:
RCS file: /home/cvs/u-boot/tools/env/fw_env.c,v
retrieving revision 1.2
diff -u -r1.2 fw_env.c
--- fw_env.c 21 Jul 2004 03:28:43 -0000 1.2
+++ fw_env.c 23 Jul 2004 05:00:25 -0000
@@ -612,8 +612,8 @@
if (!crc1_ok) {
fprintf (stderr,
"Warning: Bad CRC, using default environment\n");
- environment.data = default_environment;
- free (addr1);
+ memset(environment.data, 0, E
NV_SIZE);
+ memcpy(environment.data, default_environment, sizeof(default_environment));
}
} else {
flag1 = environment.flags;
Bug2:saveenv bad checksum
when saving environment after changing stdin,
stdout,... the checksum is not consistent.
Adding an env_crc_update() before saving environment
could solve this. i.e in common/cmd_nvedit.c in
function do_saveenv() :
int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc,char *argv[])
{
extern char * env_name_spec;
printf ("Saving Environment to %s...\n", env_name_spec);
env_crc_update();
----------------------------------------2006-08-22Linux内核移植
版本:Linux-2.4.27-vrs1
Target Board:ARM
U-boot:1.1.2
toolchain:cross-2.95.3
1、准备
kernel下载到网站
www.kernel.org,可以通过ftp方式:$ftp
ftp.kernel.org,采用匿名的方式输入anonymous即可进入下载。
patch准备:到官方网站
www.arm.linux.org.uk,这里提供ftp方式$ftp
ftp.arm.linux.org.uk2、打好补丁,执行make mrproper清理一下代码树。
3、修改根目录的Makefile文件,只需修改ARCH和CROSS_COMPILE即可。
ARCH :=arm
CROSS_COMPILE=arm-linux-
在这里,我已经将2.95.3放到PATH中,所以不需要写全路径。如果采用其他版本的toolchain,可以指明路径,如:CROSS_COMPILE=/usr/local/arm/3.3.2/bin/arm-linux-
4、$make at91rm9200dk_config
该
步的作用是把根目录下面的.config重命名为.config.old,然后把arch/arm/defconfig/里的at91rm9200dk开
发板的默认配置文件复制到根目录下,命名为.config。简单的说,就是要利用提供的开发板的配置文件,然后在此基础上进行修改。
下一步如果执
行make oldconfig,那么就完全按照.config来配置。而现在需要根据实际应用需要重新配置,所以不执行make
oldconfig。而要执行make menuconfig。这两个命令都是首先寻找默认的.config文件并且执行,但不同的是,make
oldconfig只出现.config没有的新配置选项供选择。而make
menuconfig则提供所有选项,图形界面默认的是.config的配置。
在这里,还是推荐在提供的开发板配置文件的基础之上进行修改,否则后面很容易出现意想不到的问题。我就是因为开始没有使用默认配置,后面的错误一个接一个,折腾了一个上午。
5、make menuconfig
在这里可以重新配置,根据你所需要的功能进行裁减。
6、make clean dep
建立依赖关系。
7、make
Image 或者 make zImage。这要看你后面使用什么方式的内核映象。如果是make
Image,则生成vmlinux,需要arm-linux-objcopy进行处理,生成uImage影响文件。如果是make
zImage,则生成zImage,vmlinux,system.map。
zImage和uImage对应的u-boot处理的方式也不相同,分别对应着go和bootm。
8、
[armlinux@lqm linux-2.4.27]$ cp arch/arm/boot/zImage /home/armlinux/images/zImage-2.4.27-vrs1
[armlinux@lqm linux-2.4.27]$ cp vmlinux $PRJROOT/images/vmlinux-2.4.27-vrs1
[armlinux@lqm linux-2.4.27]$ cp System.map $PRJROOT/images/System.map-2.4.27-vrs1
[armlinux@lqm linux-2.4.27]$ cp .config $PRJROOT/images/2.4.27-vrs1.config
9、生成uImage
[armlinux@lqm linux-2.4.27]$ arm-linux-objcopy -O binary -S vmlinux linux.bin
[armlinux@lqm linux-2.4.27]$ gzip -v9 linux.bin
linux.bin: 55.7% -- replaced with linux.bin.gz
[armlinux@lqm
linux-2.4.27]$ ../../bootloader/u-boot-1.1.2/tools/mkimage -n 'RAM
disk' -A arm -O linux -T kernel -C gzip -a 0x20008000 -e 0x20008000 -d
linux.bin.gz uImage
//纠正:利用mkimage制作uImage,其中-T后跟type,此时应该为kernel,不应该为ramdisk。如果是ramdisk,那么bootm肯定无法正常引导,会显示Wrong Image Type for bootm command。
Image Name: RAM disk
Created: Wed Aug 23 09:09:27 2006
Image Type: ARM Linux Kernel Image (gzip compressed)
Data Size: 617981 Bytes = 603.50 kB = 0.59 MB
Load Address: 0x20008000
Entry Point: 0x20008000
10、准备好uImage,先通过超级终端下载到ram里面,检测,然后烧写到flash里面。
可以发现已经成功。
文章评论(0条评论)
登录后参与讨论