printf("now running...\n");
addr_vx = (ulong)(IMAGE_VXWORKS_RAMADDR);
argc_vx = 0;
argv_vx = NULL;
rc_vx = ((ulong(*)(int,char*[]))addr_vx)(argc_vx,argv_vx);
}
}
}
#else
# ifdef CONFIG_AUTOBOOT_KEYED
int prev = disable_ctrlc(1); /* disable Control C checking */
# endif
# ifndef CFG_HUSH_PARSER
run_command (s, 0);
# else
parse_string_outer(s, FLAG_PARSE_SEMICOLON |
FLAG_EXIT_FROM_LOOP);
# endif
# ifdef CONFIG_AUTOBOOT_KEYED
disable_ctrlc(prev); /* restore Control C checking */
# endif
#endif
在user8240.h 中定义:
/*默认忽略启动行,从flash 启动vxWorks */
#define BOOT_FROM_FLASH
/*必须与 CONFIG_EXTRA_ENV_SETTINGS 和vxWorks 的RAM_LOW_ADRS 一致*/
#define IMAGE_VXWORKS_RAMADDR 0x00100000
把VxWork 使用的flash.c 和flash.h 拷贝到\common 目录下,在main.c 中加上对其的引用:
#if (defined CONFIG_USER8240 && defined BOOT_FROM_FLASH)
#include "flash.h"
#include "flash.c"
#endif
编译运行(如果是在我主页上下载的flash 驱动,可以把中间有关信号灯semaphore 的所有操作都去掉,因为这里还是单任务环境,不存在多个程序同时请求使用flash
的情况。还需要注意ppc_xxx-gcc 下需要在不带参数的函数后加上void,而VxWorks 加不加都行),在flashInit()函数中调用的
flashIDCheck ()函数报错,发现读取的flashID 不对,察看源程序:
char flashIDCheck(void)
{
FLASH_VALUE id1,id2;
/*设置为read identify 模式*/
*FLASH2CPU_ADDR(0) = FLASH_CC_READ_IDENTIFY;
/*读芯片代号*/
id1 = *FLASH2CPU_ADDR(0);
id2 = *FLASH2CPU_ADDR(1);
/*根据芯片是否是28F320B3 做出返回值*/
if( (id1==FLASH_28F320C3_ID) &&
((id2==FLASH_28F320C3_IDENT_T)||(id2==FLASH_28F320C3_IDENT_B))
)
return(0);
else
{
return(-1);
}
}
在VxWorks 下此程序运行无误,证明不是硬件的问题,修改程序让其打印出id1 和id2,发现id1 与FLASH_CC_READ_IDENTIFY
相等,id2 正确。怀疑是否是volatile 的问题。察看了VxWorks 的编译选项:
ccppc -g -mstrict-align -ansi -nostdinc -DRW_MULTI_THREAD -D_REENTRANT
-fvolatile -fno-builtin -fno-for-scope -I. -IC:\Tornado\target\h
-DCPU=PPC603 -c
F:\vxWorks_usrapp\tmpt\flash.c
包含了-fvolatile 选项。尝试在linux 下也用 –fvolatile 选项,编译报错:
cc1: error: unrecognized command line option "-fvolatile"
不得不修改源代码如下:
char flashIDCheck(void)
{
volatile FLASH_VALUE id1,id2;
volatile UINT addr;
*FLASH2CPU_ADDR(0) = FLASH_CC_READ_IDENTIFY;
addr = 0;
id1 = *FLASH2CPU_ADDR(addr);
addr = 1;
id2 = *FLASH2CPU_ADDR(addr);
if( (id1==FLASH_28F320C3_ID) &&
((id2==FLASH_28F320C3_IDENT_T)||(id2==FLASH_28F320C3_IDENT_B))
)
return(0);
else
{
printf("id1=0x%08x, should be 0x%08x\n",id1,FLASH_28F320C3_ID);
printf("id2=0x%08x, should be 0x%08x or 0x%08x\n",
id2,FLASH_28F320C3_IDENT_T,FLASH_28F320C3_IDENT_B);
return(-1);
}
}
其它flash 操作函数也类似加入volatile 限定,重新编译,烧入flash 运行,可以正常启动。
5.2 修改u-boot 脱离bootrom
最后,我们把u-boot 烧入EEPROM,启动流程将变为:从EEPROM 运行u-boot,从flash获取vxWorks,再运行,最终摆脱掉bootrom。
还记得4.4 里的cpu_init_f 么?这个CPU 底层寄存器初始化函数,在我们前面的运行中一直被忽略了。它的配置没有任何技巧可言,乖乖地去看CPU
手册吧。对于8240 来说,用户手册还在附录C 中提供了一段初始化代码,寄存器配置可以参考这段代码。
还有一种办法,就是“窃取”bootrom 中的寄存器配置值。在\cpu\mpc824x\cpu_init.c 中,有一个函数cpu_init_r
(),此函数被\lib_ppc\board.c 调用,如果在user8240.h 中定义了INCLUDE_MPC107_REPORT,则此函数会打印出内部寄存器的值。对于首先用bootrom
启动,u-boot 的cpu_init_f 没有被调用的情况下,此处打印的就是bootrom 对于内部寄存器的配置,除了MCCR1
需要考虑MEM_GO 位之外,其他的都可以直接使用。
修改完cpu_init_f 后,把start.S 中注释掉的bl cpu_init_f 恢复, 然后修改 \board\user8240\config.mk
文件:
TEXT_BASE = 0xfff00000
因为现在要从EEPROM 启动,默认的CPU 跳转地址为0xfff00100 了。
编译生成u-boot.bin,烧入EEPROM,运行,使用默认从flash 启动的方式,结果串口打印出一堆乱码。
原因是在bootrom 到vxWorks 的启动过程中,bootrom 默认会把的启动行参数放在内存地址BOOT_LINE_ADRS
所在的地方,而vxWorks 被加载后会到内存中获取启动行参数,从中分离出网口IP 等初始化参数。而u-boot 并没有bootrom
的启动参数,导致vxWorks 运行到此处出错。
解决办法是,把bootrom 参数也保存到flash 中,可以利用烧写vxWorks.bin 和u-boot.bin同样的方法烧写启动参数,并在vxWorks
中从flash 读取启动参数,在存到内存地址BOOT_LINE_ADRS 的地方。
我在脱离的bootrom 之后还遇到了一个问题,就是网口启动不起来了。原因是网口芯片的PCI 设备号没有设置正确,因此PCI
寄存器没有正确初始化。对于有bootrom 的情况,bootrom 已经自动初始化好了PCI,所以u-boot 中即使没有配置正确PCI,网口也可以工作。
如果分别尝试从网口(启动后按下任意键,再输入run tftpboot)和flash 启动(默认什么也不做)都成功后,为了保证VxWorks
文件的统一,把BSP 中config.h 和makefile 的RAM_LOW_ADRS 改回默认的0x00010000 ,
修改u-boot 的user8240.h 中宏定义CONFIG_EXTRA_ENV_SETTINGS 和IMAGE_VXWORKS_RAMADDR
与其一致,重新编译烧写u-boot 到EEPROM,vxWorks 到flash 即可。
1
2
3
4
5
6
7
8
9
10
11 |