S3C24X0系列的芯片属于arm920t架构体系,不过就现在分析看来。arm920t架构体系发生了一些变化。分析的结果是,该版本的S3C24X0分支有严重缺陷。不推荐进行固件组建。
此次分析的问题出现的地方主要集中在arch/arm/cpu/arm920t/start.S和arch/arm/lib/board.c中。由于早期初始化代码无法通过,所以没有对后面的文件进行进一步的分析。
arch/arm/cpu/arm920t/start.S
问题代码片段:
01 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
02 bl cpu_init_crit
03 #endif
04
05 /* Set stackpointer in internal RAM to call board_init_f */
06 call_board_init_f:
07 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
08 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
09 ldr r0,=0x00000000
10 bl board_init_f
call_board_init_f这个部分代码原来是在第二部分初始化代码中的,此次被移植到了第一部分初始化代码。board_init_f函数在arch/arm/lib/board.c中,其代码如下所示。
arch/arm/lib/board.c
问题代码片段:
01 void board_init_f (ulong bootflag)
02 {
03 bd_t *bd;
04 init_fnc_t **init_fnc_ptr;
05 gd_t *id;
06 ulong addr, addr_sp;
07
08 /* Pointer is writable since we allocated a register for it */
09 gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
10 /* compiler optimization barrier needed for GCC >= 3.4 */
11 __asm__ __volatile__("": : :"memory");
12
13 memset ((void*)gd, 0, sizeof (gd_t));
14
15 gd->mon_len = _bss_end_ofs;
16
17 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
18 if ((*init_fnc_ptr)() != 0) {
19 hang ();
20 }
21 }
在执行(*init_fnc_ptr)()函数的过程中,程序出现跑飞的情况。init_fnc_ptr是一个指向一个指针函数数组的,其构造如下所示。
arch/arm/lib/board.c
问题代码片段:
01 init_fnc_t *init_sequence[] = {
02 #if defined(CONFIG_ARCH_CPU_INIT)
03 arch_cpu_init, /* basic arch cpu dependent setup */
04 #endif
05 #if defined(CONFIG_BOARD_EARLY_INIT_F)
06 board_early_init_f,
07 #endif
08 timer_init, /* initialize timer */
09 #ifdef CONFIG_FSL_ESDHC
10 get_clocks,
11 #endif
12 env_init, /* initialize environment */
13 init_baudrate, /* initialze baudrate settings */
14 serial_init, /* serial communications setup */
15 console_init_f, /* stage 1 init of console */
16 display_banner, /* say that we are here */
17 #if defined(CONFIG_DISPLAY_CPUINFO)
18 print_cpuinfo, /* display cpu info (and speed) */
19 #endif
20 #if defined(CONFIG_DISPLAY_BOARDINFO)
21 checkboard, /* display board info */
22 #endif
23 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
24 init_func_i2c,
25 #endif
26 dram_init, /* configure available RAM banks */
27 #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
28 arm_pci_init,
29 #endif
30 NULL,
31 };
本来在以前的版本中,UBOOT会在执行cpu_init_crit函数过后会执行将代码从存储器移动到内存的功能(以前的版本只有将代码从nor flash移动到内存中的功能)。然后就跳转到内存中去运行。而第二阶段初始化代码的执行顺序本来应该是:CPU频率初始化→GPIO管脚功能初始化→时钟初始化→波特率初始化→串口初始化→控制台初始化……在控制台初始化过后应该就可以输出一些基本信息了。但是现在将这第二阶段的初始化代码的一部分移动到第一阶段的初始化后,原有的顺序打乱,导致了很多奇怪的问题。
1. init_sequence数组不能够正常运行的,但是直接运行里面的函数是可以执行的。说明一个问题,函数指针没有正确指向执行的函数地址导致跳转失败。
2.在init_sequence数组中,本来应该是排在首位的board_init函数被移除。这样导致CPU频率和GPIO管脚没有得到初始化,其结果导致了后面的程序是无法正常运行的(比如说串口初始化)。
3. board_init_f函数中对环境变量gd结构体中的bd指针没有初始化(导致dram_init函数运行失败)。
综上所述,此次版本UBOOT的S3C24X0分支有很大的结构缺陷。UBOOT2010-6版本是已知的能够正确组建S3C24X0分支固件的最新版本,由于不清楚UBOOT今后的框架思路。所以只好等待后续版本解决这个问题。
看来UBOOT的又开始折腾了,作者主要是发展POWER PC架构的CPU,不知道好久才能照顾到S3C24X0分支啊。