#define CFG_DBAT1U CFG_IBAT1U
#define CFG_DBAT2L CFG_IBAT2L
#define CFG_DBAT2U CFG_IBAT2U
#define CFG_DBAT3L CFG_IBAT3L
#define CFG_DBAT3U CFG_IBAT3U
/*此宏只针对加载linux 的情况,所有linux 需要的参数都必须放在内存最开始的8M 空间内, 因为linux 核初始化过程中只映射这么大的空间*/
#define CFG_BOOTMAPSZ (8 << 20) /*Linux 最初的内存映射空间*/
/*flash 组织,我的电路板没有使用,没有研究这些参数*/
#define CFG_MAX_FLASH_BANKS 2
/* max number of memory banks */
#define CFG_MAX_FLASH_SECT 20
/* max number of sectors on one chip */
#define CFG_FLASH_ERASE_TOUT 120000
/* Timeout for Flash Erase (in ms)*/
#define CFG_FLASH_WRITE_TOUT 500
/* Timeout for Flash Write (in ms)*/
/*cache 配置*/
#define CFG_CACHELINE_SIZE 32
/* MPC8240cache line 大小*/
/*log base 2 of the above value,此宏定义MPC8240 没有使用*/
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CFG_CACHELINE_SHIFT 5
#endif
/*启动标志定义*/
#define BOOTFLAG_COLD 0x01
/*普通的硬件上电或复位启动*/
#define BOOTFLAG_WARM 0x02
/*软件的软重启动*/
/*控制内存操作字,实际上只针对fad 板,对于sandpoint 板无意义,参见\board\fads\fads.c*/
#define CONFIG_DRAM_50MHZ 1
#define CONFIG_SDRAM_50MHZ
/*控制内存操作字,实际上对于MPC8240 无意义,
参见\board\fads\fads.c/
/*此宏只对MPC8xx 核有意义,对于sandpoint 板无意义,参见\include\mpc8xx_irq.h*/
#undef NR_8259_INTS
#define NR_8259_INTS 1
/*硬盘转速,由于没有使用硬盘,此参数无意义*/
#define CONFIG_DISK_SPINUP_TIME 1000000
#endif /* __CONFIG_H
*/
4.4 u-boot 入口程序\cpu\mpc824x\start.S
start.S 是u-boot 的入口程序,程序从_start:开始运行,如果4.2 的内容已经运行成功, 那么就一步步地向下挪动点灯代码,确定程序正常运行即可,一般来说,如果碰到程序使用了宏定义的地方,需要注意一下宏定义的值,其中很多是CPU
内部寄存器的初始化值,这些寄存器值应当参考CPU 的用户手册和原VxWorks 的BSP 修改,其余的宏定义和代码一般不需要改动。
程序的几个特殊节点为:
cpu_init_f
board_init_f
relocate_code
in_ram
board_init_r
? cpu_init_f
源代码位置:\cpu\mpc824x\cpu_init.c
运行位置: (从flash 启动)内存/(从ROM 启动)ROM
描述: 初始化cpu 的底层寄存器,这也是u-boot 中第一个运行C 语言程序,虽然大量使用将汇编定义为宏的方法进行寄存器操作,且不能使用除了register
类型之外的局部变量,但是这里确实可以使用标准C , 一个最好的例子就是可以方便地使用 *(char*)0xffe00055
= 0x00;进行点灯。由于此函数中涉及到了内存地址映射,具体方法是先
设置内存不可操作,即MCCR1 的MEM_GO 位为0),然后依次初始化MCCR2~MCCR4,最后再设置MCCR1 的MEM_GO
位为1。在此期间,内存是不可操作的,而我们的u-boot映像是放在内存中的,这意味着程序跑到这里就运行不下去了。因此,直接在start.S
中将跳转的汇编语句(bl cpu_init_f)注释掉。不用担心这些寄存器初始化的问题,因为引导u-boot 的bootrom
已经先行做完了这些工作。
? board_init_f
源代码位置:\lib_ppc\board.c
运行位置: (从flash 启动)内存/(从ROM 启动)ROM
描述:初始化串口和内存,尽早初始串口可以使程序错误容易被定位。需要注意的是:全局变量在这里是只读的,堆栈空间也很小,不超过几个KB。在这个程序里可以调用带局部变量的函数了,因此可以使用下面的语句实现更加复杂的点灯。
#define LED_ADDR ((char*)(0xffe00055))
#define LED_OP_ON 0
#define LED_OP_OFF 1
#define LED_OP_FLASH 2
void opLed(char mode)
{
int ledi;
switch(mode)
{
case LED_OP_ON:
*(char*)LED_ADDR = 0x00;
break;
case LED_OP_OFF:
*(char*)LED_ADDR = 0xff;
break;
case LED_OP_FLASH:
*(char*)LED_ADDR = 0x00;
for(ledi=0;ledi<500000;ledi++);
*(char*)LED_ADDR = 0xff;
break;
default:
break;
}
}
程序中只需要调用opLed(LED_OP_XXX)即可。
在board_init_f 中使用如下语句完成初始化:
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
{
if ((*init_fnc_ptr) () != 0) {
hang ();
}
}
init_sequence 是一个函数入口组成的数组,其中就包括有串口初始化函数:init_baudrate ( \lib_ppc\board.c
), serial_init ( \drivers\serial.c ),console_init_f (common\console.c
)和 display_options(\lib_generic \display_options.c)。最后一个函数打印出:
U-Boot 1.1.4 (Mar 13 2006 - 16:49:46)
从此以后,就可以使用puts()函数打印信息到串口上了。
主要的相关宏定义有( 宏定义在user8240.h 中, 具体说明参见4.3 节):
CONFIG_CONS_INDEX 、CONFIG_BAUDRATE 、CFG_BAUDRATE_TABLE 、
CFG_NS16550、CFG_NS16550_SERIAL、CFG_NS16550_REG_SIZE、CFG_NS16550_CLK
和CFG_NS16550_COM1(1~4)。
值得一提的是,从这个数组里还可以看出,如果定义了CFG_DRAM_TEST,会调用testdram 函数,进行内存的测试。
board_init_f 接下来完成一些需要全局使用参数的参数,跳转到relocate_code。
? relocate_code
源代码位置:\cpu\mpc824x\start.S
运行位置: (从flash 启动)内存/(从ROM 启动)ROM
描述: 此段代码应该是把从TEXT_BASE 开始的内容拷贝到从某地址开始的内存,然后跳转到内存中相应的in_ram 位置继续执行。
? in_ram
源代码位置:\cpu\mpc824x\start.S
运行位置: 内存
描述: 第一个真正意义上运行在内存中的程序,如果在此点灯能够被看到,剩下需要修改的基本上就可以脱离汇编了,此段代码清BSS,最后跳转board_init_r。
? board_init_r
源代码位置:\lib_ppc\board.c
运行位置: 内存
描述: 第一个拥有正常C 环境的程序,可以大规模使用堆栈。程序使用宏定义控制是否初始化硬件。对我们来说,关键步骤有:
1
2
3
4
5
6
7
8
9
10
11 |