为了调试的方便,设定bootrom 如下启动,如果在启动过程中没有人为干扰,即在串口出现press any key to
stop autoboot 之后, 没有按下任何键, 则直接从flash 的
FLASH_DATA_UBOOT 读取程序,然后执行。否则,使用启动行参数从网络启动,获取VxWorks,用来烧录flash。由于跳转地址都是0x00010000,而第一条执行的机器码位置不同,因此原来从flash
读取VxWorks 的程序代码是将已经烧入flash 的VxWorks.bin 文件读取 到内存0x00010000 的位置,然后跳转0x00010000,而对于u-boot,则需要从u-boot.bin
文件的0x100 位置开始读取,存放到0x00010000 位置再跳转0x00010000。或者干脆为了保持烧写和读取程序的一致,两种文件的读写都是从头开始,存放到内存的0x00010000,只是u-boot.bin
的跳转地址是0x00010100。修改完位置为usrConfig()的结尾处,直接在bootConfig.c 文件的LOCAL
char autoboot
(int timeout)函数中声明变量:
#ifdef BOOT_FROM_FLASH
char tmpt[4];
int imageLen;
#endif
在的下列语句:
if (bytesRead == 0) /* nothing typed so auto-boot */
{
(void) ioctl (consoleFd, FIOSETOPTIONS, OPT_TERMINAL);
后添加:
#ifdef BOOT_FROM_FLASH
flashInit();
if(flashDataGet(FLASH_DATA_UBOOT,tmpt,4)!=0)
printf("error in getting U-BOOT length\n");
else
{
imageLen = tmpt[0]*0x01000000+tmpt[1]*0x00010000
+tmpt[2]*0x00000100+tmpt[3];
printf("\nloading U-BOOT for %d bytes from flash\n",
imageLen);
if(flashDataGet(FLASH_DATA_UBOOT,
(char*)(IMAGE_UBOOT_RAMADDR-4),
imageLen)!=STATUS_NORMAL)
printf("error in getting U-BOOT from flash\n");
else
{
printf("now running...\n");
go((FUNCPTR)(IMAGE_UBOOT_RAMADDR+0x100));
}
}
flashShutdown();
#endif
在config.h 中定义BOOT_FROM_FLASH,定义IMAGE_UBOOT_RAMADDR 为0x00010000,同时还需要flash
的驱动程序,不过这些在做VxWorks 程序在线固化的时候应该早就作好啦( 我的主页上有flash 程序驱动可以下载:
http://mail.ustc.edu.cn/~jycheng3/study/flashdriver.rar)。
修改完毕后制作bootrom。在命令行下输入:
torvars
make bootrom_uncmp.hex
把bootrom_uncmp.hex 烧写到EEPROM,烧写过程中load 选择hex 形式即可。也可以用如下命令:
torvars
make bootrom_uncmp
elftobin <bootrom_uncmp> bootrom_uncmp.bin
烧写bootrom_uncmp.bin,烧写过程中load 选择bin 形式。
制作完bootrom,接下来制作u-boot.bin,为了使起始地址与bootrom 保持一致,修改\board\user8240\下的config.mk
文件,用“#”注释掉将原来的TEXT_BASE,重新定义:
TEXT_BASE = 0x00010000
为了保证u-boot 的运行可以被看到,修改\cpu\mpc824x\目录下的start.S 中加入点灯的汇编指令。
#ifdef CONFIG_USER8240
lis r4,0xffe0
li r3,0x00
stb r3,0x0055(r4)
#endif
上面的代码直接加在 _start: 说明符后即可。需要注意的是,如果没有bootrom 的引导、上电直接从u-boot 启动,则上面的点灯代码无效,原因是地址映射和外围控制的寄存器都还没有正确初始化。由bootrom
读取flash 中的u-boot 到内存再启动,可以更早地标志u-boot运行状态,这也是此种方法调试的一大优势。
上面的MPC8240 汇编相当于C 语言的*(char*)0xffe00055 = 0x00;
可以在VxWorks 的用户程序中测试,该语句是否有效。编写用户程序:
void testLedOn()
{
__asm ("lis 4,0xffe0;li 3,0;stb 3,0x0055(4)");
}
通过target server 下载,然后直接在shell 下输入testLenOn,就可以检测点灯语句是否有效了。对于其他的电路板,最好能找到一个点灯或者电路板某处电平变化的方法,形成一个标志。把这样的操作的汇编代码添加到start.S
入口处。
修改完毕后,制作u-boot.bin,拷贝到Windows 下。启动电路板,在bootrom 启动输出press any key
to stop autoboot 时,按任意键停止自动加载,选择从网络加载刚才制作的vxWorks。加载运行后,用上面提到的Windows
程序将u-boot.bin 烧入FLASH_DATA_UBOOT 开始的flash 块。
重新启动电路板,别动键盘,就让bootrom 自己启动,串口输出:
Press any key to stop auto-boot...
5 4 3 2 1 0
loading U-BOOT for 142588 bytes from flash
now running...
Starting at 0x10100...
如果接下去你看到电路板上的灯亮了,或者其他标志有效了,那么恭喜你,u-boot 的第一步终于成功了。否则,查查看flash
的操作是否正确(让bootrom 打印从flash 读取到的内容,和u-boot.bin 文件比较),看看基地址是否正确,点灯程序是否正确,硬件有没有出毛病。需要注意的是,虽然u-boot
文件和vxWorks 文件都是hex 格式,但由于u-boot 的起始地址有0x100 的偏移,而vxWorks 没有,因此使用网络加载vxWorks
的方法加载u-boot 是
无法成功的,最简单的方法是烧写flash。
4.3 软硬结合的配置文件\include\configs\[boardname].h
急着要修改代码?不行。现在得仔细看看\include\configs\目录下的user8240.h,它使用宏定义控制板上硬件的初始化,从某种意义上来说,是电路板硬件特性的代表文件。其他电路板也类似,控制文件为\include\configs\[boardname].h。你应该已经浏览过user8240.h
了,下面给出了它的内容和注释,为了简略起见,省去了源代码中除了版权声明的原有注释。针对于电路板的修改都只是用注释的方法给出建议,而没有直接修改源代码。如果碰到不明白的宏定义,记得在u-boot
目录下搜索一遍。
/* (C) Copyright 2001-2005
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* See file CREDITS for list of people who contributed to this
* project.
* This program is free software; you can redistribute it and/or
modify it under the terms
* of the GNU General Public License as published by the Free Software
Foundation;
* either version 2 of the License, or (at your option) any later
version.
*/
#ifndef __CONFIG_H
#define __CONFIG_H /*控制本文件不会被重复引用*/
#define CONFIG_MPC824X 1 /*使用8240/8245 CPU*/
#define CONFIG_MPC8240 1 /*使用8240 CPU*/
#define CONFIG_USER8240 1 /*电路板标志,如果需要修改与sandpoint 板不同的地方,都建议用此宏定义控制*/
/*控制是否是从内存启动,事实上,当我们从flash 获取u-boot 时,确实是在从内存启动,但由于已经初始化了内存控制的寄存器,因此并不是纯粹意义上的从内存启动。为了后来修改成烧入ROM
的方便,仍然定义为不是从内存启动,需要修改的内容将在后面说明*/
#if 0
#define USE_DINK32 1 /*从内存启动,不修改MCCR1 的MEMGO 位*/
#else
#undef USE_DINK32 /*从非易失存储硬件启动,修改MCCR1 的MEMGO 位*/
#endif
/*sandpoint 使用NS16552 作为串口芯片,该芯片集成了两个串口控制,选择第一个作为控制台串口,通讯的波特率设为9600,在Windows
的超级中端中也必须设定为此值,才能正确显示串口的打印信息,建议设置为与VxWorks 的bootrom 相同的波特率*/
#define CONFIG_CONS_INDEX 1
#define CONFIG_BAUDRATE 9600
1
2
3
4
5
6
7
8
9
10
11 |