初学嵌入式Linux
假设我们现在进行一项嵌入式开产品的开发,比如说智能电力系统终端,那么我想首先应该对完整的开发流程有一个大致的了解,才不致于在以后的工作中被动。下面对嵌入式linux开发简单的介绍一下。
1、系统的需求分析
2、硬件平台的选择和设计
3、软件开发
(3-1)建立开发环境。
(3-2)引导装载程序。
(3-3)内核裁减与编译。
(3-4)建立文件系统。
(3-5)应用程序开发。
嵌入式开发环境一般由:宿主机(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接口连接。使用工作站上的超级终端作为嵌入式目标系统输入/输出端。
对于开发流程有了一定的了解后就有了目标,这样才能够不是太郁闷。
debug kernel rootfiles source tmp
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
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
要想用更新的版本,则可以到网站ftp://ftp.handhelds.org/projects/toolchain下载,这里可以下在到cross-3.3.2和cross-3.4.1,默认路径是/usr/local/arm/<版本号>。
mkdir arm
cd arm
tar Ixvf cross-.tar.bz2
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
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/sbin
$. .bash_profile //讓配置文件生效
看见红色的行就是修改好的。只需要把你的路径添加到后面就可以了。
{
int i;
for(i=1;i<9;i++)
printf("Hello World %d times!\n",i);
}
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
-rwxr-xr-x 1 armlinux armlinux 23132 8月 10 11:33 gdbserver
有效的下載地址:http://linus.yhspatriot.net/cs/cs/assignments/q1/introToUnix.html
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.tgz
在Windows下解壓tree-1.5.0.tgz,將解壓後的文件夾tree-1.5.0拷到/home/zhj1011/software下。
$cd /home/zhj1011/software/tree-1.5.0
|-- bootloader
|-- debug
|-- images
|-- kernel
|-- program
|-- rootfiles
|-- software
|-- source
|-- sysapps
|-- tmp
`-- tools
一、了解一下存储器的基本分类情况。
存储器的物理实质是一组或多组具备数据输入输出和数据存储功能的集成电路,用于充当设备缓存或保存固定的程序及数据。存储器按存储信息的功能可分为只读存储器ROM(Read Only Memory)和随机存储器RAM(Random Access Memory)。
图1 常见存储器分类
1、 ROM
ROM 中的信息一次写入后只能被读出,而不能被操作者修改或删除,一般由芯片制造商进行掩膜写入信息,价格便宜,适合于大量的应用。一般用于存放固定的程序,如监控程序、汇编程序等,以及存放各种表格。EPROM(Erasable Programmable ROM)和一般的ROM不同点在于它可以用特殊的装置擦除和重写它的内容,一般用于软件的开发过程。
特别介绍:闪存(Flash Memory)
闪速存储器(Flash Memory)又称PEROM(Programmable and Erasable Read Only Memory),是Intel 公司在80 年代末90 年代初推出的,由于它的众多优点而深受用户的青睐。Flash Memory 的两个主要特点是可以按整体/扇区擦除和按字节编程。它是完全非易失的,可以在线写入,并且可以按页连续字节写入,读出速度高。Flash 芯片划分成很多扇区,把一位从0 重置为1 不能通过对该位单独操作来实现,而必须擦除整个扇区。Flash芯片的寿命就用擦除周期来衡量。通常的寿命为每个扇区可擦除100,000 次。为了避免任意一个扇区在其他扇区之前达到这个极限,大多数Flash 芯片用户会尽量保证擦除次数在各扇区之间均匀分布,这一过程称为“磨损均衡”(wear leveling)
2、 RAM
RAM 就是我们平常所说的内存,主要用来存放各种现场的输入、输出数据,中间计算结果,以及与外部存储器交换信息和作堆栈用。它的存储单元根据具体需要可以读出,也可以写入或改写。RAM 只能用于暂时存放程序和数据,一旦关闭电源或发生断电,其中的数据就会丢失。现在的RAM 多为MOS 型半导体电路,它分为静态和动态两种。静态RAM 是靠双稳态触发器来记忆信息的;动态RAM 是靠MOS 电路中的栅极电容来记忆信息的。由于电容上的电荷会泄漏,需要定时给与补充,所以动态RAM 需要设置刷新电路。但动态RAM 比静态RAM 集成度高、功耗低,从而成本也低,适于作大容量存储器。所以主内存通常采用动态RAM,而高速缓冲存储器(Cache)则使用静态RAM。动态RAM 按制造工艺的不同,又可分为动态随机存储器(Dynamic RAM)、扩展数据输出随机存储器(Extended Data Out RAM)和同步动态随机存储器(Synchromized DynamicRAM)。DRAM 需要恒电流以保存信息,一旦断电,信息即丢失。它的刷新频率每秒钟可达几百次,但由于DRAM 使用同一电路来存取数据,所以DRAM 的存取时间有一定的时间间隔,这导致了它的存取速度并不是很快。另外,在DRAM 中,由于存储地址空间是按页排列的,所以当访问某一页面时,切换到另一页面会占用CPU 额外的时钟周期。EDO-RAM同DRAM 相似,但在把数据发送给CPU 的同时可以去访问下一个页面,故而速度要比普通DRAM 快15~30%。SDRAM同DRAM 有很大区别,它使用同一个CPU 时钟周期即可完成数据的访问和刷新,即以同一个周期、相同的速度、同步的工作,因而可以同系统总线以同频率工作,可大大提高数据传输率,其速度要比DRAM 和EDO-RAM 快很多(比EDO-RAM提高近50%)。
二、AT91RM9200开发板的存储器情况
第一级地址译码由存储控制器执行,即由具有附加功能的高级系统总线(ASB) 执行。译码将4G的地址空间分为16 个256M字节的区域。区域1 ~ 8对应EBI,和外部片选NC0 ~NCS7相联系。区域0为内部存储器地址,第二级译码提供1M字节内部存储空间。区域15为外设地址,且提供对高级外设总线(APB) 的访问。其它区域未使用,使用它们进行访问时将向发出访问请求的主机发出异常中断。注意,地址的转换都是按照字节为单位的。
1、内部存储器映射
内部ROM:AT91RM9200集成了一个128-K字节的内部ROM。任何时候,ROM均被映射到地址0x10 0000。若复位时BMS(引导模式选择引脚) 为高,则在复位后到重新映射命令执行前,可访问地址0x0。ROM容量为128KB,即对应0x20000。所以范围为0x100000-0x120000。
内部RAM:AT91RM9200集成了高速,16-K 字节的内部SRAM。复位后到重新映射命令执行前,只可访问SRAM 中0x20 0000的地址空间。重新映射后, SRAM 在地址0x0 同样有效。SRAM容量为16KB,即对应0x4000,所以范围为0x200000-0x204000。
USB 主机端口:AT91RM9200集成了一个USB主机端口开放主机控制器接口(OHCI)。ASB可直接访问该接口寄存器,且同标准内部存储器一样映射到地址0x30 0000。
图2 内部存储器映射
2、外部存储器映射
图3 外部存储器映射
嵌入式存储设备通常主要是RAM 和作为永久存储媒质的Flash。
现在所用的AT91RM9200开发板所用的SDRAM是HY57V281620HCT-H,其容量为4banks×2Mbits×16,即128Mbits=16Mbytes。SDRAM共有两片HY57V281620HCT-H,所以SDRAM容量为32MB。
现在所用的Flash芯片为Intel的28F640J3,容量为8MB,地址映射从0x10000000到0x10800000。现在将Flash分为64个扇区,每个扇区为128KB=0x20000,每个扇区分为两个擦除块,为64KB=0x10000。
-------------------------------------------------------------------
Chip Select 0――Flash(0x1000 0000-0x1FFF FFFF)
0x1000 0000(第0扇区)
boot.bin Flash
0x1001 0000(第0扇区)
u-boot.bin.gz Flash
0x1002 0000(第1扇区)
uImage Flash
.
.
.
0x1012 0000(第9扇区)
ramdisk Flash
.
.
.
0x107E 0000(第63扇区)
u-boot环境变量 Flash
-------------------------------------------------------------------
Chip Select 1――SDRAM(0x2000 0000-0x2200 0000)
0x2000 0000
SDRAM
.
.
0x2100 0000
uImage SDRAM
0x2110 0000
ramdisk SDRAM
.
.
-------------------------------------------------------------------
1. PLL SETUP //PLL:鎖相環,倍頻的作用。
设置PLLB产生48M时钟频率提供给USB DEVICE。同时DEBUG USART也被初始化为48M的时钟频率。
2. 相应模式下的堆栈设置
3. 检测主时钟源(Main oscillator)
4. 中断控制器(AIC)的设置
5. C 变量的初始化
6. 跳到主函数
完成以上步骤后,我们可以认为BOOT过程结束,接下来的就是LOADER的过程,或者也可以认为是装载二级BOOTLOER。AT91RM9200按照DATAFLASH、EEPROM、连接在外部总线上的8位并行FLASH的顺序依次来找合法的BOOT程序。所谓合法的指的是在这些存储设备的开始地址处连续的存放的32个字节,也就是8条指令必须是跳转指令或者装载PC的指令,其实这样规定就是把这8条指令当作是异常向量表来处理。必须注意的是第6 条指令要包含将要装载的映像的大小。关于如何计算和写这条指令可以参考用户手册。一旦合法的映像找到之后,则BOOT程序会把找到的映像搬到SRAM中去,所以映像的大小是非常有限的,不能超过16K的大小。当BOOT程序完成了把合法的映像搬到SRAM的任务以后,接下来就进行存储器的REMAP,经过REMAP之后,SRAM从映设前的0X200000地址处被映设到了0X0地址并且程序从0X0处开始执行。而ROM这时只能在0X100000这个地址处看到了。至此9200就算完成了一种形式的启动过程。如果BOOT程序在以上所列的几种存储设备中找到合法的映像,则自动初始化DEBUG USART口和USB DEVICE口以准备从外部载入映像。对DEBUG口的初始化包括设置参数115200 8 N 1以及运行XMODEM协议。对USB DEVICE进行初始化以及运行DFU协议。现在用户可以从外部(假定为PC平台)载入你的映像了。在PC平台下,以WIN2000为例,你可以用超级终端来完成这个功能,但是还是要注意你的映像的大小不能超过13K。一旦正确从外部装载了映像,接下来的过程就是和前面一样重映设然后执行映像了。我们上面讲了BMS(引导模式选择引脚)为高电平,AT91RM9200选择从片内的ROM启动的一个过程。如果BMS(引导模式选择引脚)为低电平,则AT91RM9200会从片外的FLASH启动,这时片外的FLASH的起始地址就是0X0了,接下来的过程和片内启动的过程是一样的,只不过这时就需要自己写启动代码了,至于怎么写,大致的内容和ROM的BOOT差不多,不同的硬件设计可能有不一样的地方,但基本的都是一样的。由于片外FLASH可以设计的大,所以这里编写的 BOOTLOADER可以一步到位,也就是说不用像片内启动可能需要BOOT好几级了,目前AT91RM9200上使用较多的bootloer是u-boot,这是一个开放源代码的软件,用户可以自由下载并根据自己的应用配置。
以上三个文件时at91rm9200启动所需要的三个bin,他们的实现代码并不难。
如果是你是采用at91rm9200的评估版,应该能得到其源码。
loader.bin 执行流程,这个文件主要在片内启动从串口下载代码时会用到
loader/entry.S init cpu
b main ---> crt0.S
--> copydata --> clearbss --> b boot
main.c --> boot -->
/*Get internel rom service address*/
/* Init of ROM services structure */
pAT91 = AT91C_ROM_BOOT_ADDRESS;
/* Xmodem Initialization */
--> pAT91->OpenSBuffer
--> pAT91->OpenSvcXmodem
/* System Timer initialization */
---> AT91F_AIC_ConfigureIt
/* Enable ST interrupt */
AT91F_AIC_EnableIt
AT91F_DBGU_Printk("XMODEM: Download U-BOOT ");
Jump.S
// Jump to Uboot BaseAddr exec
Jump((unsigned int)AT91C_UBOOT_BASE_ADDRESS)
boot.bin执行流程 该文件会在从片内启动时被下载到板子上,以后还会被烧写到片外Flash中,以便在片外启动时
用它来引导并解压u-boot.bin.gz,并跳转到u-boot来执行。
boot/entry.S
b main --> crt0.S --> copydata --> clearbss --> b boot
AT91F_DBGU_Printk(" ");
AT91F_DBGU_Printk("************************************** ");
AT91F_DBGU_Printk("** Welcome to at91rm9200 ** ");
AT91F_DBGU_Printk("************************************** ");
boot/misc.s /* unzip uboot.bin.gz */
----> decompress_image(SRC,DST,LEN) --> gunzip
//jump to ubootBaseAddr exec 这里跳转到解压u-boot.bin.gz的地址处直接开始执行u-boot
asm("mov pc,%0" : : "r" (DST));
u-boot.bin执行流程
u-boot/cpu/at91rm9200/start.S
start --->reset
---> copyex ---> cpu_init_crit
---> /* set up the stack */ --> start_armboot
u-boot/lib_arm/board.c
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
dram_init, /* configure available RAM banks */
display_dram_config,
checkboard,
NULL,
};
---> start_armboot ---> call init_sequence
---> flash_init --> display_flash_config
---> nand_init ---> AT91F_DataflashInit
---> dataflash_print_info --> env_relocate
---> drv_vfd_init --> devices_init --> jumptable_init
---> console_init_r --> misc_init_r --> enable_interrupts
---> cs8900_get_enetaddr --> board_post_init -->
u-boot/common/main.c
for (;;)
{ /* shell parser */
main_loop () --> u_boot_hush_start --> readline
--> abortboot
-->printf("Hit any key to stop autoboot: %2d ", bootdelay);
}
以上是at91rm9200启动并进入u-boot的执行流分析。后面u-boot还会将uImage解压到特定的位置并开始执行内核代码。
.
|-- board 平台依赖,存放电路板相关的目录文件
|-- common 通用多功能函数的实现
|-- doc 文档
|-- drivers 通用的设备驱动程序,如以太网接口驱动
|-- dtt
|-- examples 应用例子
|-- fs 通用存放文件系统的程序
|-- include 头文件和开发板配置文件,所有开发板配置文件放在其configs里
|-- lib_arm 平台依赖,存放arm架构通用文件
|-- lib_generic 通用的库函数
|-- lib_i386 平台依赖,存放x86架构通用文件
|-- lib_m68k 平台依赖
|-- lib_mips 平台依赖
|-- lib_ppc平台依赖,存放ppc架构通用文件
|-- net 存放网络的程序
|-- post 存放上电自检程序
|-- rtc rtc的驱动程序
`-- tools 工具
[armlinux@lqm board]$ cd myboard
[armlinux@lqm myboard]$ ls
at91rm9200dk.c config.mk flash.c Makefile u-boot.lds
[armlinux@lqm myboard]$ cat config.mk
TEXT_BASE = 0x21f80000
[armlinux@lqm myboard]$ vi config.mk
SOBJS :=
$(AR) crv $@ $(OBJS) $(SOBJS)
rm -f $(SOBJS) $(OBJS)
[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
35 #define FLASH_PORT_WIDTH16 /*定义位宽16*/
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 u-boot-1.1.1]$ vi Makefile
## AT91RM9200 Systems
#########################################################################
@./mkconfig $(@:_config=) arm at91rm9200 at91rm9200dk
@./mkconfig $(@:_config=) arm at91rm9200 myboard
at91rm9200dk integratorcp integratorap \
omap1510inn omap1610h2 omap1610inn \
smdk2400 smdk2410 trab \
VCMA9 versatile myboard \
"
[armlinux@lqm configs]$ cp at91rm9200dk.h myboard.h
[armlinux@lqm configs]$ vi myboard.h
//行號和實際的myboard.h的行號有所偏差,認真修改好配置就可以了。
111 #define PHYS_SDRAM 0x20000000 sdram起始地址
112 #define PHYS_SDRAM_SIZE 0x2000000 sdram容量32MB
129 #define PHYS_FLASH_2 0x00000000 定义,flash.c用到,但实际并未起作用
130 #define PHYS_FLASH_SIZE 0x800000 flash容量8MB
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 环境变量占了一个扇区,共128KB
150
151 #define CFG_SOFT_RESET 1 定义软复位,flash.c用到
152 #define CFG_LOAD_ADDR 0x21000000 /* default load address */
Configuring for myboard board...
[armlinux@lqm u-boot-1.1.1]$ make CROSS_COMPILE=arm-linux-
//u-boot.bin在目錄: u-boot-1.1.1下。
$gzip u-boot.bin //壓縮得到u-boot.bin.gz
正在开始 xmodem 传输。 按 Ctrl+C 取消。
正在传输 loader.bin...
100% 6 KB
CCCCCCCCCCCCC
正在开始 xmodem 传输。 按 Ctrl+C 取消。
正在传输 u-boot.bin...
100% 85 KB 6 KB/s 00:00:14 0 错误
RAM Configuration:
Bank #0: 20000000 32 MB
Flash: 8 MB
*** Warning - bad CRC, using default environment
Out: serial
Err: serial
U-boot> version
bootdelay=5
baudrate=115200
stdin=serial
stdout=serial
stderr=serial
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
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 sectors
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)
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...-done
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
RAM Configuration:
Bank #0: 20000000 32 MB
Flash: 8 MB
*** Warning - bad CRC, using default environment
Out: serial
Err: serial
U-boot>
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyex
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyex
RAM Configuration:
Bank #0: 20000000 32 MB
Flash: 8 MB
In: serial
Out: serial
Err: serial
U-Boot>
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, ENV_SIZE);
+ memcpy(environment.data, default_environment, sizeof(default_environment));
}
} else {
flag1 = environment.flags;
Bug2:
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() :
{
extern char * env_name_spec;
版本:Linux-2.4.27-vrs1
Target Board:ARM
U-boot:1.1.2
toolchain:cross-2.95.3
kernel下载到网站www.kernel.org,可以通过ftp方式:$ftp ftp.kernel.org,采用匿名的方式输入anonymous即可进入下载。
patch准备:到官方网站www.arm.linux.org.uk,这里提供ftp方式$ftp ftp.arm.linux.org.uk
2、打好补丁,执行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。
[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
[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
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
初学嵌入式Linux的更多相关文章
- 嵌入式Linux学习方法——给那些彷徨者(下)
上一章解决了嵌入式Linux的“学什么”问题,这一章则具体来说一下“怎么学”. 只要做好以下3点: 1.学习顺序.学习任何东西都应该由浅入深,不能一口吃下一个大胖子,得循序渐进.很多刚开始想学习Lin ...
- 嵌入式 Linux下永久生效环境变量bashrc
嵌入式 Linux下永久生效环境变量bashrc 1) .bashrc文件 在linux系统普通用户目录(cd /home/xxx)或root用户目录(cd /root)下,用指令ls -al可以看到 ...
- 制作自己的嵌入式Linux电脑_转
制作自己的嵌入式Linux电脑 http://os.51cto.com/art/201409/450334.htm 原文链接:http://blog.jobbole.com/75414/ 包含器件选择 ...
- 用Windows+VirtualBox搭建嵌入式Linux开发环境
Windows+VirtualBox的嵌入式Linux开发环境的搭建 最近一直在学习Linux的设备驱动编写,一直是在物理机上安装的Ubuntu进行的,但是在Ubuntu12.04的系统中,已经不能用 ...
- 嵌入式Linux的调试技术
本节我们研究嵌入式Linux的调试技术,对于复杂的Linux驱动及HAL等程序库,需要使用各种方法对其进行调试.刚开始讲了打印内核调试信息:printk,这个函数的用法与printf函数类似,只不过p ...
- 嵌入式linux应用程序移植方法总结
嵌入式linux应用程序移植方法总结 前段时间一直在做openCapwap的移植和调试工作,现在工作已接近尾声,编写本文档对前段工作进行一个总结,分享下openCapwap移植过程中的经验和感悟.江浩 ...
- 驱动开发学习笔记. 0.06 嵌入式linux视频开发之预备知识
驱动开发读书笔记. 0.06 嵌入式linux视频开发之预备知识 由于毕业设计选择了嵌入式linux视频开发相关的项目,于是找了相关的资料,下面是一下预备知识 UVC : UVC,全称为:USB v ...
- 嵌入式linux开发环境构建
2.1硬件环境构建 2.1.1主机与目标板结合的交叉开发模式 在主机上编辑.编译软件,然后再目标办上运行.验证程序. 对于S3C2440.S3C2410开发板,进行嵌入式Linux开发时一般可以分为以 ...
- 嵌入式Linux驱动开发日记
嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...
随机推荐
- Lua 学习 chapter30 编写c函数的技巧 - Jow的博客
目录 数组操作 字符串操作 在c函数中保存状态 生活总需要一点仪式感,然后慢慢的像那个趋向完美的自己靠近. 数组操作 Lua中的数组就是以特殊的方式使用边.像lua_setttable and lua ...
- 吴裕雄--天生自然HTML学习笔记:HTML 图像
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- piranha(注意iptables和selinux的问题)
piranha是红帽官方提供的一套工具,安装和配置都非常简单,可以快速部署. piranha方案原理结构描述: piranha方案是基于lvs基础上设计的一套负载均衡高可用解决方案 LVS运行在一对有 ...
- <USACO07JAN>解决问题Problem Solvingの思路
日常为dp贡献脑细胞 #include<iostream> #include<cmath> #include<cstdio> #include<cstdlib ...
- Kafka常用命令及配置文件
创建topic,指定备份分区数 bin/kafka-topics.sh --create --zookeeper zk:2181 --replication-factor 2 --partitions ...
- 漫谈国内外Android生态:华为发布的 HMS 服务,对 Mate30 系列无法搭载 Google GMS 的补偿有多大(原创)
如果既用过iPhone,也用过国际版Android,还用过国内的安卓,(并且这三种都用了半年以上),就能体会到GMS多重要.可以说,iOS的体验大幅度领先于国内的安卓,一多半的原因是国内安卓没有GMS ...
- 简单的员工管理系统(Mysql+jdbc+Servlet+JSP)
员工管理系统 因为学业要求,需要完成一个过关检测,但是因为检测之前没有做好准备,且想到之前用mysql+jdbc+Struts2+bootstrap做成了一个ATM系统(主要有对数据的增删改查操作), ...
- 设计模式-09装饰模式(Decorator Pattern)
1.模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制:使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是 ...
- sql -- 获取商品分类的最新销售情况
表设计: 需求: 1.先找出各个分类中销售的最新日期 select prod_class,max(sales_date) as sn from prod_sales group by prod_cla ...
- Jstorm执行task报错windows CONFIG SET protected-mode no
windows CONFIG SET protected-mode no报错说redis受保护模式,redis使用的是Redis-x64-3.2.100,参考博文说是redis3.2之后加入的特性, ...