上节操作完成后,虽然uboot中有了我们自己的板卡,但并未进行移植,所以现在是还不能烧录的,本节将带领大家根据自己的板卡进行uboot移植。
2.4.1 图形界面下配置
命令行执行 make menuconfig,出现如下界面
方括号[ ]中的“*”代表编译链接时添加该模块,为空则不参加编译链接,这就是uboot的裁剪功能。
因为我们的启动介质是SPIFLASH,在SPL阶段我们应该将SPI设备和驱动添加进编译链接,将SPL / TPL=>[*]Support SPI flash drivers和SPL / TPL=> [*] Support SPI drivers添加进来。
注:虽然我们将SPI驱动添加进来了,但是SPIFlash型号多种多样,包括容量、扇区大小等等,市场上大多数SPIFlash型号uboot都支持,查看spi_flash_ids.c文件,里面有各种型号的SPIFlash的描述,如果我们使用的SPIFlash型号不在其中,我们需要手动添加我们的SPIFlash信息至表中即可。如果uboot支持我们的SPIFlash,则至> Device Drivers > SPI Flash Support下去选择Flash厂家。 |
我们需要在uboot控制台下能够使用命令访问操作SPIFlash,所以也要把这项功能添加进来,图形界面Command line interface > Device access commands,将[*]sf添加进来。
2.4.2 修改omapl138_639.h
目前omapl138_639.h文件的内容和TI omapl138_lcdk.h的内容是一样的,我们需要进行一些修改才适用于我们的板卡,omapl138_lcdk.h内容略长,这里仅挑重要的从前往后进行讲解。
2.4.2.1 启动介质
639A板卡的启动介质选择的是SPIFlash,而TI板卡选择的是NandFlash,因此需要进行如下修改。
#define CONFIG_DRIVER_TI_EMAC #undef CONFIG_SYS_USE_NOR #undef CONFIG_USE_NAND
#define CONFIG_USE_SPIFLASH |
2.4.2.2 系统时钟
TI开发板选用的是24M晶振,我们的板卡使用的是20M晶振,因此需要按照我们的需求修改系统时钟,24倍频。
#define CONFIG_SYS_OSCIN_FREQ 20000000
#define CONFIG_SYS_DA850_PLL0_PLLM 23
#define CONFIG_SYS_DA850_PLL1_PLLM 23
2.4.2.3 串口控制台
TI开发板选择Uart2作为串口控制台,我们的板卡只有Uart0是对外串口,另外以后我们需要在控制台下使用串口向DDR加载内核镜像,为了提高传输效率,我将串口波特率设为460800,(以后也可以在uboot命令行通过修改环境变量“baudrate”的方式切换串口波特率)。
/* * Serial Driver info */ #define CONFIG_SYS_NS16550_SERIAL #define CONFIG_SYS_NS16550_REG_SIZE -4 /* NS16550 register size */ #define CONFIG_SYS_NS16550_COM1 DAVINCI_UART0_BASE #define CONFIG_SYS_NS16550_CLK clk_get(DAVINCI_UART2_CLKID) #define CONFIG_CONS_INDEX 1 /* use UART0 for console */ #define CONFIG_BAUDRATE 115200 /* Default baud rate */ #define CONFIG_SYS_BAUDRATE_TABLE { 115200,230400,380400,460800 } |
另外,在系统电源配置处,我们需要将Uart0模块使能,TI并没有使能Uart0的电源模块。
#define CONFIG_SYS_DA850_SYSCFG_SUSPSRC ( \ DAVINCI_SYSCFG_SUSPSRC_TIMER0 | \ DAVINCI_SYSCFG_SUSPSRC_SPI1 | \ DAVINCI_SYSCFG_SUSPSRC_UART2 | \ DAVINCI_SYSCFG_SUSPSRC_UART0 | \ DAVINCI_SYSCFG_SUSPSRC_EMAC | \ DAVINCI_SYSCFG_SUSPSRC_I2C)
const struct lpsc_resource lpsc[] = { { DAVINCI_LPSC_AEMIF }, /* NAND, NOR */ { DAVINCI_LPSC_SPI1 }, /* Serial Flash */ { DAVINCI_LPSC_EMAC }, /* image download */ { DAVINCI_LPSC_UART0 }, /* console */ { DAVINCI_LPSC_GPIO }, #ifdef CONFIG_DAVINCI_MMC { DAVINCI_LPSC_MMC_SD }, #endif }; |
static const struct pinmux_config uart_pins[] = { { pinmux(3), 2, 6 }, { pinmux(3), 2, 7 }, { pinmux(3), 2, 4 }, { pinmux(3), 2, 5 } }; |
在omapl138_639.c文件中添加Uart0引脚使能结构体。
TI官方开发板的网卡使用的是MII接口,但MII引脚和uart0引脚复用,所以为了使用Uart0,我们需要将uboot中MII接口初始化函数屏蔽。
//if (davinci_configure_pin_mux(emac_pins, ARRAY_SIZE(emac_pins)) != 0)
2.4.2.3 uboot地址
我们需要指定uboot镜像在SPIFlash中的位置,这样SPL将会去改地址加载uboot镜像至DDR,并启动uboot,我们指定0x10000地址作为uboot镜像所在的起始地址,镜像不超过512K。
#define CONFIG_SPL_SPI_LOAD
#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x10000
#define CONFIG_SYS_SPI_U_BOOT_SIZE 0x80000
2.4.2.4 环境变量
环境变量让我们可以不用修改uboot的源代码,而是通过修改环境变量来影响uboot运行时的一些数据和特性。譬如说通过修改bootdelay环境变量就可以更改系统开机自动启动时倒数的秒数。
uboot代码当中有一个值,环境变量中也有一个值。uboot程序实际运行时规则是:如果环境变量为空则使用代码中的值;如果环境变量不为空则优先使用环境变量对应的值。
SPIFlash中其实就是给了个分区,专门用来存储而已。存储时其实是把DDR中的环境变量整体的写入SPIFlash卡中分区里。所以当我们saveenv时其实整个所有的环境变量都被保存了一遍,而不是只保存更改了的。
刚烧录的系统中环境变量分区是空白的,uboot第一次运行时加载的是uboot代码中自带的一份环境变量,叫默认环境变量。我们在saveenv时DDR中的环境变量会被更新到SPIFlash中的环境变量中,就可以被保存下来,下次开机会在环境变量relocate时会SD卡中的环境变量会被加载到DDR中去。
default_environment中的内容虽然被uboot源代码初始化为一定的值(这个值就是我们的默认环境变量),但是在uboot启动的第二阶段,env_relocate时代码会去判断SD卡中的env分区的crc是否通过。如果crc校验通过说明SPIFlash中有正确的环境变量存储,则relocate函数会从SD卡中读取环境变量来覆盖default_environment字符数组,从而每次开机可以保持上一次更改过的环境变量。
将uboot环境变量存储在SPIFlash地址0x00090000开始64K。
#define CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_SIZE (64*1024) #define CONFIG_ENV_OFFSET 0x00090000 #define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE |
2.4.3 烧录uboot至SPIFlash
以上步骤都操作完成,我们就可以将编译好的ubootspl和uboot镜像烧录至SPIFlash中了,万事开头难,第一次我们仍然需要使用CCS环境在线仿真的方式进行烧录,需要等待时间略长,打开CCS6.1将我们最熟悉的工程添加进来,该工程在以往的基础上进行了修改,主要是修改的烧录地址,如果你是第一次烧录,请务必使用我提供的工程进行烧录,对于使用该工程进行烧录大家应该很熟悉了,为了减少以后不必要的麻烦,我这里再不厌其烦的带领大家操作一遍。
进入仿真模式后,点击“运行”,console出现如下界面
输入“1”后回车,进入子界面
我们先烧录uboot-spl,在选择之前我们首先将uboot-spl和uboot镜像拷贝到路径D:\\639B_WorkPlace\\obj,输入“1”后回车。
Uboot-spl镜像烧录完成后,不要退出,一鼓作气,继续烧录uboot镜像,uboot镜像比较大,226Kbyte,需要等个两分钟才能烧录完成。
经过漫长的等待,uboot终于烧录完成了,那就赶快重新上电验证下我们的uboot是否已经移植成功了吧!接下来将是激动人心的时刻!
注1:在uboot调试阶段,为了让我们更好的了解uboot和及时发现和解决Bug,建议搭建把DEGUG宏打开,这样在我们使用和调试uboot时,uboot会将一些设备状态和出错信息打印到终端,在include/common.h头文件中打开DEBUG宏 |
嚯,uboot启动界面出现了,但并不代表我们的工作已经结束了,别忘了uboot的终极目的是为了启动内核,接下来我们需要根据自己项目的需求在uboot中添加我们想要的功能,比如在线升级等等。
注2:有些朋友可能会对我们烧录镜像的文件格式感到疑惑,ubootspl我们烧录的是ais格式的镜像,因为omapl138在启动时只认ais格式的程序,所以我们必须选择ais格式作为spl镜像。而uboot镜像作为spl加载启动的镜像,格式就可以随意些了,平时我们烧录的都是bin文件格式的镜像,但这里有些不同,spl为了启动uboot需要获取uboot的一些信息,比如函数入口,你可以去比较一下你编译出的img格式的镜像比bin文件格式的镜像多64Byte,这64Byte包含了spl加载uboot时需要解析的信息。 |