基于OMAP-L138电路板的U-boot移植

最近参加了一个项目,主板采用的是TI的OMAP-L138,为了引导linux内核,准备采用u-boot作为bootloader。在搜集资料的过程中发现关于移植u-boot到基于OMAP-L138电路板的资料非常少,而且TI的OMAP-L138采用三级boot,比其他单arm9核的SOC要复杂的多,因此纠结了很长时间。好不容易参照hawkboard的配置把u-boot-2011.03移植到我们的板子(gcboard)上,在此记录下我的一点经验,希望能对后来者有所帮助。


step 1.移植准备
u-boot-2011.03 已经包含了对hawkboard开发板的完整支持,这是一款基于OMAP-L138的开发板,它的外设主要有:
1)128MB DDR2 SDRAM
2)128MB NAND Flash
3)一个标准RS232串口
4)一个10M/100M高速网卡
而我们的项目所用的开发板与hawkboard主要的区别在于没有nand flash,多了一块SPI flash(采用STMicro公司的M25P128,)
移植u-boot主要是为了在开发初期调试内核,文件系统,后期一般他只需要做适当的初始化,再引导内核就可以了,所以移植需要关注的基本就是这些。
为了熟悉程序结构,首先使用hawkboard的默认配置对uboot进行编译:
make hawkboard_config
make
编译完成后可以看到在主目录下生成了uboot.bin文件,为了方便分析,使用如下命令将其反汇编:
arm-linux-objdump -D -m arm u-boot > u-boot.asm
利用u-boot.asm 和 system.map,u-boot.lds这三个文件,再配合源代码,我们可以很容易的分析程序流程:
首先看u-boot.lds文件,它指定了程序链接顺序,在最初几行我们可以看到:init_sequence

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
arch/arm/cpu/arm926ejs/start.o (.text)
*(.text)
}
...
}

可知程序是从arch/arm/cpu/arm926ejs/start.s开始的(这是老生常谈了,百度一下,几乎任何一篇介绍uboot的文章都会介绍这一点),打开这个文件我们可以看到程序的54行:

.globl _start
_start:
b reset

首先跳到reset 标号处执行,在第108行:

reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0

/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif

这里是否会执行 bl cpu_init_crit这一句指令呢?需要到配置文件中去找答案,打开include/configs/hawkboard.h文件我们可以看到,由于定义了宏CONFIG_SKIP_LOWLEVEL_INIT,这一句被跳过,这是由OMAP-L138 的启动方式决定的。接下来看第179行:

call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r0,=0x00000000
bl board_init_f

首先设置好栈,然后调用了一个c函数(使用r0来传递参数),找到这个函数有一个比较麻烦的方法,首先在u-boot.asm中找到board_init_f标号,它在第1100行,对应的地址为c1180e9c,在uboot主目录下输入如下命令:
addr2line -e u-boot c1180e9c
显示该函数是在u-boot-2011.03/arch/arm/lib/board.c:283行(当然在linux下我们还可以使用命令: grep "board_init_f" ./ -R,在u-boot源码目录下查找所有包含"board_init_f"的文件,只是要找出这个函数在哪个文件还得再费点功夫)
打开board.c,这个是所有arm结构的班子共用的板级初始化文件,可以看到该函数主要做了如下工作:
1.调用init_sequence数组中包含的所有初始化函数,这些函数包括
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,
另外有一些初始化函数由宏定义开关来决定是否执行
2.对gd_t这个结构进行填充(非常重要,定义在arch/arm/include/asm/global_data.h中)。这个结构记录了系统的内存大小,波特率等信息。
最后调用relocate_code函数进行代码重定位,这是一个汇编函数,在start.s第195行定义:
elocate_code:
mov r4, r0 /* save addr_sp */
mov r5, r1 /* save addr of gd */
mov r6, r2 /* save addr of destination */

/* Set up the stack */
stack_setup:
mov sp, r4

adr r0, _start
cmp r0, r6
beq clear_bss /* skip relocation */
mov r1, r6 /* r1 <- scratch for copy loop */
ldr r3, _bss_start_ofs
add r2, r0, r3 /* r2 <- source end address */

copy_loop:
ldmia r0!, {r9-r10} /* copy from source address [r0] */
stmia r1!, {r9-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
blo copy_loop

函数执行之前先检查自己是否已经在内存中,由于TI的OMAP-L138采用三重启动,U-boot在启动时已经被UBL装载到内存中,所以这一步跳过,直接跳转到clear_bss,清数据段,然后跳转到board.c中的board_init_r函数中,开始了第二阶段的初始化,最后进入U-boot的主循环。


step 2.根据上述流程,对u-boot作如下移植:
将/include/configs/hawkboard.h复制为gcboard.h,打开gcboard.h,作如下修改:
1)注释掉#define CONFIG_SYS_USE_NAND,这样所有跟nand flash 有关的代码都不会被编译了。
2)添加如下宏定义:
#define CONFIG_SPI_FLASH 1 //添加SPI Flash 支持
#ifdef CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_STMICRO 1 //添加STMicro 的SPI FLASH 驱动
#define CONFIG_SYS_NO_FLASH 1 //务必添加这个宏,否则会引入CFI Flash的驱动编译
#define CONFIG_DEFAULT_SPI_BUS 1 //定义SPI FLASH所在的总线,这里指定SPI1
#define CONFIG_DAVINCI_SPI 1 //架构相关的SPI驱动
#define CONFIG_SYS_SPI_BASE 0x01f0e000 //指定SPI1 寄存器的基地址
#define CONFIG_SYS_SPI_CLK 50000000 //最大工作频率50Mhz,由器件手册得到
#define CONFIG_MAX_SPI_SECT 64 //从这里开始的三个宏是我自己定义的,为了方便记忆,他们不是必要的
#define CONFIG_MAX_SPI_BANKS 1 //
#define CONFIG_MAX_SPI_CAPACITY 0x1000000 //
#define CONFIG_SPI_SECT_SIZE 0x40000 //M25P128每个sector是256KB

#define CONFIG_ENV_IS_IN_SPI_FLASH 1 //环境变量保存在SPI FLASH 中
#define CONFIG_ENV_SPI_MODE SPI_MODE_0 //其实不用指定,默认值也可以
#define CONFIG_ENV_SPI_BUS 1 //
#define CONFIG_ENV_SPI_CS 0 //必须是CS0
#define CONFIG_ENV_SPI_MAX_HZ 50000000
#define CONFIG_ENV_SIZE 0x40000
#define CONFIG_ENV_SECT_SIZE 0x40000
#define CONFIG_ENV_OFFSET (CONFIG_MAX_SPI_CAPACITY-CONFIG_SPI_SECT_SIZE) //保存在最后一块,以免误操作把U-boot给擦掉了


#define CONFIG_CMD_SPI 1 //
#define CONFIG_SPIBOOTLDR 1 //
#define CONFIG_CMD_SF 1 //在U-boot中增加SF(SPI FLASH命令),否则不能对SPI FLASH进行操作

3)驱动的修改。在u-boot-2011.03中,davinci 架构的SPI FLASH 驱动中有一个问题就是,在检测SPI FLASH 时只检测SPI0的CS0,由此导致的问题是:若你的SPI FLASH挂在SPI1上,而你想要在U-boot 中使用SF probe 检测SPI FLASH 就会提示"can't setup slave"的问题,因此找到/drivers/spi/davinci_spi.c中的setup_slave函数,将其中的:
if (!spi_cs_is_valid(bus, cs))
return NULL;
这一段注释掉。实际上spi_cs_is_valid函数只有一句:
return bus == 0 && cs == 0
可见这样检测的话我们的SPI FLASH 是不可能被检测出来的。

4)添加自定义配置gcboard.h。u-boot-2011.03使用新的生成配置文件方法,为了在执行make gcboard_config时能够自动读取我们的配置文件,需要编辑u-boot主目录下的boards.cfg文件,在其中搜索hawkboard,可以看到第84行:
hawkboard arm arm926ejs da8xxevm davinci davinci
hawkboard_nand arm arm926ejs da8xxevm davinci davinci hawkboard:NAND_U_BOOT
hawkboard_uart arm arm926ejs da8xxevm davinci davinci hawkboard:UART_U_BOOT
仿照这种格式我们添加如下行:
gcboard arm arm926ejs da8xxevm davinci davinci
这样make的时候会自动读取我们的配置

5)重新编译u-boot
make clean
make distclean
make gcboard_config
make

这样就生成了针对gcboard的u-boot,当然,下一步还需要将u-boot.bin使用TI的工具转换为AIS格式映像,下载到已经装有UBL的SPI FLASH才能引导板子启动

最近参加了一个项目,主板采用的是TI的OMAP-L138,为了引导linux内核,准备采用u-boot作为bootloader。在搜集资料的过程中发现关于移植u-boot到基于OMAP-L138电路板的资料非常少,而且TI的OMAP-L138采用三级boot,比其他单arm9核的SOC要复杂的多,因此纠结了很长时间。好不容易参照hawkboard的配置把u-boot-2011.03移植到我们的板子(gcboard)上,在此记录下我的一点经验,希望能对后来者有所帮助。


step 1.移植准备
u-boot-2011.03 已经包含了对hawkboard开发板的完整支持,这是一款基于OMAP-L138的开发板,它的外设主要有:
1)128MB DDR2 SDRAM
2)128MB NAND Flash
3)一个标准RS232串口
4)一个10M/100M高速网卡
而我们的项目所用的开发板与hawkboard主要的区别在于没有nand flash,多了一块SPI flash(采用STMicro公司的M25P128,)
移植u-boot主要是为了在开发初期调试内核,文件系统,后期一般他只需要做适当的初始化,再引导内核就可以了,所以移植需要关注的基本就是这些。
为了熟悉程序结构,首先使用hawkboard的默认配置对uboot进行编译:
make hawkboard_config
make
编译完成后可以看到在主目录下生成了uboot.bin文件,为了方便分析,使用如下命令将其反汇编:
arm-linux-objdump -D -m arm u-boot > u-boot.asm
利用u-boot.asm 和 system.map,u-boot.lds这三个文件,再配合源代码,我们可以很容易的分析程序流程:
首先看u-boot.lds文件,它指定了程序链接顺序,在最初几行我们可以看到:init_sequence

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
arch/arm/cpu/arm926ejs/start.o (.text)
*(.text)
}
...
}

可知程序是从arch/arm/cpu/arm926ejs/start.s开始的(这是老生常谈了,百度一下,几乎任何一篇介绍uboot的文章都会介绍这一点),打开这个文件我们可以看到程序的54行:

.globl _start
_start:
b reset

首先跳到reset 标号处执行,在第108行:

reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0

/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif

这里是否会执行 bl cpu_init_crit这一句指令呢?需要到配置文件中去找答案,打开include/configs/hawkboard.h文件我们可以看到,由于定义了宏CONFIG_SKIP_LOWLEVEL_INIT,这一句被跳过,这是由OMAP-L138 的启动方式决定的。接下来看第179行:

call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r0,=0x00000000
bl board_init_f

首先设置好栈,然后调用了一个c函数(使用r0来传递参数),找到这个函数有一个比较麻烦的方法,首先在u-boot.asm中找到board_init_f标号,它在第1100行,对应的地址为c1180e9c,在uboot主目录下输入如下命令:
addr2line -e u-boot c1180e9c
显示该函数是在u-boot-2011.03/arch/arm/lib/board.c:283行(当然在linux下我们还可以使用命令: grep "board_init_f" ./ -R,在u-boot源码目录下查找所有包含"board_init_f"的文件,只是要找出这个函数在哪个文件还得再费点功夫)
打开board.c,这个是所有arm结构的班子共用的板级初始化文件,可以看到该函数主要做了如下工作:
1.调用init_sequence数组中包含的所有初始化函数,这些函数包括
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,
另外有一些初始化函数由宏定义开关来决定是否执行
2.对gd_t这个结构进行填充(非常重要,定义在arch/arm/include/asm/global_data.h中)。这个结构记录了系统的内存大小,波特率等信息。
最后调用relocate_code函数进行代码重定位,这是一个汇编函数,在start.s第195行定义:
elocate_code:
mov r4, r0 /* save addr_sp */
mov r5, r1 /* save addr of gd */
mov r6, r2 /* save addr of destination */

/* Set up the stack */
stack_setup:
mov sp, r4

adr r0, _start
cmp r0, r6
beq clear_bss /* skip relocation */
mov r1, r6 /* r1 <- scratch for copy loop */
ldr r3, _bss_start_ofs
add r2, r0, r3 /* r2 <- source end address */

copy_loop:
ldmia r0!, {r9-r10} /* copy from source address [r0] */
stmia r1!, {r9-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
blo copy_loop

函数执行之前先检查自己是否已经在内存中,由于TI的OMAP-L138采用三重启动,U-boot在启动时已经被UBL装载到内存中,所以这一步跳过,直接跳转到clear_bss,清数据段,然后跳转到board.c中的board_init_r函数中,开始了第二阶段的初始化,最后进入U-boot的主循环。


step 2.根据上述流程,对u-boot作如下移植:
将/include/configs/hawkboard.h复制为gcboard.h,打开gcboard.h,作如下修改:
1)注释掉#define CONFIG_SYS_USE_NAND,这样所有跟nand flash 有关的代码都不会被编译了。
2)添加如下宏定义:
#define CONFIG_SPI_FLASH 1 //添加SPI Flash 支持
#ifdef CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_STMICRO 1 //添加STMicro 的SPI FLASH 驱动
#define CONFIG_SYS_NO_FLASH 1 //务必添加这个宏,否则会引入CFI Flash的驱动编译
#define CONFIG_DEFAULT_SPI_BUS 1 //定义SPI FLASH所在的总线,这里指定SPI1
#define CONFIG_DAVINCI_SPI 1 //架构相关的SPI驱动
#define CONFIG_SYS_SPI_BASE 0x01f0e000 //指定SPI1 寄存器的基地址
#define CONFIG_SYS_SPI_CLK 50000000 //最大工作频率50Mhz,由器件手册得到
#define CONFIG_MAX_SPI_SECT 64 //从这里开始的三个宏是我自己定义的,为了方便记忆,他们不是必要的
#define CONFIG_MAX_SPI_BANKS 1 //
#define CONFIG_MAX_SPI_CAPACITY 0x1000000 //
#define CONFIG_SPI_SECT_SIZE 0x40000 //M25P128每个sector是256KB

#define CONFIG_ENV_IS_IN_SPI_FLASH 1 //环境变量保存在SPI FLASH 中
#define CONFIG_ENV_SPI_MODE SPI_MODE_0 //其实不用指定,默认值也可以
#define CONFIG_ENV_SPI_BUS 1 //
#define CONFIG_ENV_SPI_CS 0 //必须是CS0
#define CONFIG_ENV_SPI_MAX_HZ 50000000
#define CONFIG_ENV_SIZE 0x40000
#define CONFIG_ENV_SECT_SIZE 0x40000
#define CONFIG_ENV_OFFSET (CONFIG_MAX_SPI_CAPACITY-CONFIG_SPI_SECT_SIZE) //保存在最后一块,以免误操作把U-boot给擦掉了


#define CONFIG_CMD_SPI 1 //
#define CONFIG_SPIBOOTLDR 1 //
#define CONFIG_CMD_SF 1 //在U-boot中增加SF(SPI FLASH命令),否则不能对SPI FLASH进行操作

3)驱动的修改。在u-boot-2011.03中,davinci 架构的SPI FLASH 驱动中有一个问题就是,在检测SPI FLASH 时只检测SPI0的CS0,由此导致的问题是:若你的SPI FLASH挂在SPI1上,而你想要在U-boot 中使用SF probe 检测SPI FLASH 就会提示"can't setup slave"的问题,因此找到/drivers/spi/davinci_spi.c中的setup_slave函数,将其中的:
if (!spi_cs_is_valid(bus, cs))
return NULL;
这一段注释掉。实际上spi_cs_is_valid函数只有一句:
return bus == 0 && cs == 0
可见这样检测的话我们的SPI FLASH 是不可能被检测出来的。

4)添加自定义配置gcboard.h。u-boot-2011.03使用新的生成配置文件方法,为了在执行make gcboard_config时能够自动读取我们的配置文件,需要编辑u-boot主目录下的boards.cfg文件,在其中搜索hawkboard,可以看到第84行:
hawkboard arm arm926ejs da8xxevm davinci davinci
hawkboard_nand arm arm926ejs da8xxevm davinci davinci hawkboard:NAND_U_BOOT
hawkboard_uart arm arm926ejs da8xxevm davinci davinci hawkboard:UART_U_BOOT
仿照这种格式我们添加如下行:
gcboard arm arm926ejs da8xxevm davinci davinci
这样make的时候会自动读取我们的配置

5)重新编译u-boot
make clean
make distclean
make gcboard_config
make

这样就生成了针对gcboard的u-boot,当然,下一步还需要将u-boot.bin使用TI的工具转换为AIS格式映像,下载到已经装有UBL的SPI FLASH才能引导板子启动

最近参加了一个项目,主板采用的是TI的OMAP-L138,为了引导linux内核,准备采用u-boot作为bootloader。在搜集资料的过程中发现关于移植u-boot到基于OMAP-L138电路板的资料非常少,而且TI的OMAP-L138采用三级boot,比其他单arm9核的SOC要复杂的多,因此纠结了很长时间。好不容易参照hawkboard的配置把u-boot-2011.03移植到我们的板子(gcboard)上,在此记录下我的一点经验,希望能对后来者有所帮助。


step 1.移植准备
u-boot-2011.03 已经包含了对hawkboard开发板的完整支持,这是一款基于OMAP-L138的开发板,它的外设主要有:
1)128MB DDR2 SDRAM
2)128MB NAND Flash
3)一个标准RS232串口
4)一个10M/100M高速网卡
而我们的项目所用的开发板与hawkboard主要的区别在于没有nand flash,多了一块SPI flash(采用STMicro公司的M25P128,)
移植u-boot主要是为了在开发初期调试内核,文件系统,后期一般他只需要做适当的初始化,再引导内核就可以了,所以移植需要关注的基本就是这些。
为了熟悉程序结构,首先使用hawkboard的默认配置对uboot进行编译:
make hawkboard_config
make
编译完成后可以看到在主目录下生成了uboot.bin文件,为了方便分析,使用如下命令将其反汇编:
arm-linux-objdump -D -m arm u-boot > u-boot.asm
利用u-boot.asm 和 system.map,u-boot.lds这三个文件,再配合源代码,我们可以很容易的分析程序流程:
首先看u-boot.lds文件,它指定了程序链接顺序,在最初几行我们可以看到:init_sequence

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
arch/arm/cpu/arm926ejs/start.o (.text)
*(.text)
}
...
}

可知程序是从arch/arm/cpu/arm926ejs/start.s开始的(这是老生常谈了,百度一下,几乎任何一篇介绍uboot的文章都会介绍这一点),打开这个文件我们可以看到程序的54行:

.globl _start
_start:
b reset

首先跳到reset 标号处执行,在第108行:

reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0

/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif

这里是否会执行 bl cpu_init_crit这一句指令呢?需要到配置文件中去找答案,打开include/configs/hawkboard.h文件我们可以看到,由于定义了宏CONFIG_SKIP_LOWLEVEL_INIT,这一句被跳过,这是由OMAP-L138 的启动方式决定的。接下来看第179行:

call_board_init_f:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r0,=0x00000000
bl board_init_f

首先设置好栈,然后调用了一个c函数(使用r0来传递参数),找到这个函数有一个比较麻烦的方法,首先在u-boot.asm中找到board_init_f标号,它在第1100行,对应的地址为c1180e9c,在uboot主目录下输入如下命令:
addr2line -e u-boot c1180e9c
显示该函数是在u-boot-2011.03/arch/arm/lib/board.c:283行(当然在linux下我们还可以使用命令: grep "board_init_f" ./ -R,在u-boot源码目录下查找所有包含"board_init_f"的文件,只是要找出这个函数在哪个文件还得再费点功夫)
打开board.c,这个是所有arm结构的班子共用的板级初始化文件,可以看到该函数主要做了如下工作:
1.调用init_sequence数组中包含的所有初始化函数,这些函数包括
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,
另外有一些初始化函数由宏定义开关来决定是否执行
2.对gd_t这个结构进行填充(非常重要,定义在arch/arm/include/asm/global_data.h中)。这个结构记录了系统的内存大小,波特率等信息。
最后调用relocate_code函数进行代码重定位,这是一个汇编函数,在start.s第195行定义:
elocate_code:
mov r4, r0 /* save addr_sp */
mov r5, r1 /* save addr of gd */
mov r6, r2 /* save addr of destination */

/* Set up the stack */
stack_setup:
mov sp, r4

adr r0, _start
cmp r0, r6
beq clear_bss /* skip relocation */
mov r1, r6 /* r1 <- scratch for copy loop */
ldr r3, _bss_start_ofs
add r2, r0, r3 /* r2 <- source end address */

copy_loop:
ldmia r0!, {r9-r10} /* copy from source address [r0] */
stmia r1!, {r9-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
blo copy_loop

函数执行之前先检查自己是否已经在内存中,由于TI的OMAP-L138采用三重启动,U-boot在启动时已经被UBL装载到内存中,所以这一步跳过,直接跳转到clear_bss,清数据段,然后跳转到board.c中的board_init_r函数中,开始了第二阶段的初始化,最后进入U-boot的主循环。


step 2.根据上述流程,对u-boot作如下移植:
将/include/configs/hawkboard.h复制为gcboard.h,打开gcboard.h,作如下修改:
1)注释掉#define CONFIG_SYS_USE_NAND,这样所有跟nand flash 有关的代码都不会被编译了。
2)添加如下宏定义:
#define CONFIG_SPI_FLASH 1 //添加SPI Flash 支持
#ifdef CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_STMICRO 1 //添加STMicro 的SPI FLASH 驱动
#define CONFIG_SYS_NO_FLASH 1 //务必添加这个宏,否则会引入CFI Flash的驱动编译
#define CONFIG_DEFAULT_SPI_BUS 1 //定义SPI FLASH所在的总线,这里指定SPI1
#define CONFIG_DAVINCI_SPI 1 //架构相关的SPI驱动
#define CONFIG_SYS_SPI_BASE 0x01f0e000 //指定SPI1 寄存器的基地址
#define CONFIG_SYS_SPI_CLK 50000000 //最大工作频率50Mhz,由器件手册得到
#define CONFIG_MAX_SPI_SECT 64 //从这里开始的三个宏是我自己定义的,为了方便记忆,他们不是必要的
#define CONFIG_MAX_SPI_BANKS 1 //
#define CONFIG_MAX_SPI_CAPACITY 0x1000000 //
#define CONFIG_SPI_SECT_SIZE 0x40000 //M25P128每个sector是256KB

#define CONFIG_ENV_IS_IN_SPI_FLASH 1 //环境变量保存在SPI FLASH 中
#define CONFIG_ENV_SPI_MODE SPI_MODE_0 //其实不用指定,默认值也可以
#define CONFIG_ENV_SPI_BUS 1 //
#define CONFIG_ENV_SPI_CS 0 //必须是CS0
#define CONFIG_ENV_SPI_MAX_HZ 50000000
#define CONFIG_ENV_SIZE 0x40000
#define CONFIG_ENV_SECT_SIZE 0x40000
#define CONFIG_ENV_OFFSET (CONFIG_MAX_SPI_CAPACITY-CONFIG_SPI_SECT_SIZE) //保存在最后一块,以免误操作把U-boot给擦掉了


#define CONFIG_CMD_SPI 1 //
#define CONFIG_SPIBOOTLDR 1 //
#define CONFIG_CMD_SF 1 //在U-boot中增加SF(SPI FLASH命令),否则不能对SPI FLASH进行操作

3)驱动的修改。在u-boot-2011.03中,davinci 架构的SPI FLASH 驱动中有一个问题就是,在检测SPI FLASH 时只检测SPI0的CS0,由此导致的问题是:若你的SPI FLASH挂在SPI1上,而你想要在U-boot 中使用SF probe 检测SPI FLASH 就会提示"can't setup slave"的问题,因此找到/drivers/spi/davinci_spi.c中的setup_slave函数,将其中的:
if (!spi_cs_is_valid(bus, cs))
return NULL;
这一段注释掉。实际上spi_cs_is_valid函数只有一句:
return bus == 0 && cs == 0
可见这样检测的话我们的SPI FLASH 是不可能被检测出来的。

4)添加自定义配置gcboard.h。u-boot-2011.03使用新的生成配置文件方法,为了在执行make gcboard_config时能够自动读取我们的配置文件,需要编辑u-boot主目录下的boards.cfg文件,在其中搜索hawkboard,可以看到第84行:
hawkboard arm arm926ejs da8xxevm davinci davinci
hawkboard_nand arm arm926ejs da8xxevm davinci davinci hawkboard:NAND_U_BOOT
hawkboard_uart arm arm926ejs da8xxevm davinci davinci hawkboard:UART_U_BOOT
仿照这种格式我们添加如下行:
gcboard arm arm926ejs da8xxevm davinci davinci
这样make的时候会自动读取我们的配置

5)重新编译u-boot
make clean
make distclean
make gcboard_config
make

这样就生成了针对gcboard的u-boot,当然,下一步还需要将u-boot.bin使用TI的工具转换为AIS格式映像,下载到已经装有UBL的SPI FLASH才能引导板子启动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值