Chinaunix首页 | 论坛 | 博客
  • 博客访问: 629127
  • 博文数量: 112
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 1406
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-25 18:46
文章分类
文章存档

2011年(1)

2010年(5)

2009年(25)

2008年(81)

我的朋友

分类: LINUX

2008-04-26 11:38:11

 

1.    我的开发板配置如下:

 AT91rm9200, 180MHz; 32MB SDRAM, NCS1/SDCS片选; 64KB EEPROM, AT24C512; 2MB Flash, 我选用了AM29lv320, NCS0/BFCS片选; nandflash 64M,SAMSUNGK9F1208U0B 10/100M 网络接口,DM9161E; USB 主接口from AT91rm9200; USB 设备接口from AT91rm9200; DBGU 串行调试接口from AT91rm9200;

 2.首先我们要搞清楚,真正的理解和成功的移植uboot得先弄明白at91rm9200的启动流程和uboot的启动方法: at91rm9200有片内引导和片外引导 2 种启动方式,由一根跳线控制。上电MCU检测BMS的电平,如果是高则选择片内ROM启动, 如果是低则从外部flash启动。 1 片外引导 执行烧在flash上的引导程序。 2 片内引导 at91rm9200内部本身有128k的片内rom,其固化了一个bootloaderuploader,片内引导时启动uploaderuploader开启xmodem协议,等待用户上传程序,上传的程序将载入片内SRAM,重映射,然后pc跳转到片内SRAM执行上传的用户程序。注:片内SRAM只有16k,除去3-4k片内启动程序的占用的部分数据空间,因此下载的程序大小限制在12k内。

 官方at91rm9200DK u-boot Flash Programming Solutions文档提供的解决方案如下。开发板flash上没有引导程序,于是只能用片内引导方式,载入一个12k以内的小程序到内部SRAM运行,而这个小程序初始化SDRAM后,再把u-boot下载到SDRAM运行(u-boot大于12k)pc跳到SDRAMu-boot位置运行u-bootu-boot启动后再用u-boot自己的flash烧写命令把自己烧到flash去,以后就可以片外flash启动了。

官方文档中并不是直接烧u-boot.bin,而是烧入了boot.binu-boot.gz2个文件。 Loader.bin boot.bin我暂时用的是板子提供的修改好的,这里重点先研究研究uboot的启动和移植。不过我还是了解了一下它们的启动流程,以便更好的去移植uboot loader.bin, boot.bin, u-boot.bin代码执行流分析. 以上三个文件时at91rm9200启动所需要的三个bin,他们的实现代码并不难。如果是你是采用at91rm9200的评估版,应该能得到其源码。

loader.bin 执行流程,这个文件主要在片内启动从串口下载代码时会用到 loader/entry.S 初始化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 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解压到特定的位置并开始启动内核代码。

 

 

3.1 修改Loader.bin的源码

 

1). 修改 include/main.h

#define AT91C_UBOOT_BASE_ADDRESS 0x21f00000 此开发板SDRAM32M 地址空间为 0x20000000—0x22000000 uboot被解压缩后要被拷贝到RAM的高端地址,防治 与其他地址冲突

2). 修改init.c中对SDRAM的初始化 AT91C_BASE_SDRC->SDRC_MR=0x02 根据具体的SDRAM芯片修改: MR[4]=1 (表示16) MR[4]=0 (表示32)

 

3.2 修改Boot.bin的源码

 

1). main.c中添加两个外部函数的定义

 Extern int deampress_image(void *src,void *dst,unsigned int len); 解压缩函数,用来解压缩UBOOT Extern void Jump() 跳转函数

2). main.c中修改宏定义

 #define SRC 0x10010000 ubootflash中的基地址

 #define DST 0x21f00000 解压缩UBOOT后载入到SDRAM中的地址    #define LEN 0x20000 uboot的大小(最大大小)

3) 修改main.c中打印语句 AT91F_DBGU_Pringk()

 AT91F_DBGU_Pringk() ……… AT91F_DBGU_Pringk()

 

 

4.实战

    从网上下载官方uboot1.1.1 交叉编译器用的是2.95.3.我没有创建自己的目录,直接用原有的。方便点。呵呵。由于我的开发板支持nandflash.所以我首先让我的板子的nand驱动起来。

修改的地方在board/at91rm9200dk/atrm9200dk.c,对nand_init进行修改。主要是:

*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;

改为 *AT91C_PIOC_ASR = AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE; //AT91C_PC0_BFCK

  *AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;

改为 *AT91C_PIOC_PDR = AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE; 增加两句

 *AT91C_PIOC_PER|= AT91C_PC0_BFCK;

 *AT91C_PIOC_OER = AT91C_PC0_BFCK;

 注:AT91C_PC0_BFCK Brust Flash控制器的时钟信号线 AT91C_PC1_BFRDY_SMOE Brust Flash 控制器的读信号。 AT91C_PC3_BFBAA_SMWE Brust Flash 控制器的脉冲前沿地址。 AT91C_PIOC_ASR 是外设A寄存器。

AT91C_PIOC_PDR GPIO 禁用寄存器。

AT91C_PIOC_PER GPIO 使能寄存器。

AT91C_PIOC_OER GPIO 使能输出寄存器。

上述修改的目的是,使能BFCK信号线的GPIO输出。

 在

/*Configure PC2 as input (signal READY of theSmartMedia)*/增加

*AT91C_PMC_PCER|=(unsigned int)(1<<4); 此句。:开启外设时钟。

然后把调试信息打开-#ifdef DEBUG给注释掉。看看你的nandflashbase对不对。

 

然后就是修改/include/cmd_confdefs.h

修改 #define CFG_CMD_NONSTD ()这个宏定义是决定uboot支持的功能,

如果需要支持就从括号中删除此行。例如源码支持 CFG_CMD_LOADB CFG_CMD_MEMORY 等。我们这里的修改是删除 “CFG_CMD_NAND | \ ” 这行,uboot支持nandflash然后你的nandflash的侦测ID等等,之类的东西都在cmd_nand.c里进行了,首先就是nand_probe,里面有两个重要的子函数。可以看看。然后把调试信息打开。看看是不是你想要的信息,比如: mfr=ec id=76 Flash chip found: Manufacturer ID: 0xEC, Chip ID: 0x76 (Samsung K9F1208UOA) 1 flash chips found. Total nand_chip size: 64 MB 看到这你应该高兴了。呵呵。下面就是对norflash的修改了。

 

阅读(2057) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~