U-Boot移植总结

时间:2021-06-28 04:26:55

U-Boot移植步骤总结:
                                   1、查看U-Boot目录结构(一般要修改的内容在cpu、board、                                         common、lib_xx、include等目录下)
                                   2、对照自己的开发板的CPU型号、生产厂商、具体型号以及                                           开发板的原理图,修改相应的配置文件,如串口、网卡、                                           存储器等。


U-Boot移植总结

U-Boot移植总结

U-Boot移植总结U-Boot移植总结

U-Boot的作用:
                        1、初始化硬件
                        2、为内核作准备

移植U-Boot:
        一、相关开发板配置
        二、相关驱动

一、硬件(CPU采用的具体类型芯片)
        1、CPU架构(arm,MIPS)
        2、生产厂商(三星、TI、Atmel)
        3、arm7、arm9、cortex-a8、a9
二、硬件布局(原理图、布线图)
        1、存储器(内存、Flash)
        2、显示设备
        3、串口使用
        4、USB
        5、网卡



SQ210平台系统移植之uboot移植
背景介绍:
Uboot是当前嵌入式应用中使用最广的bootloader之一,尤其是嵌入式linux平台一般均会选用uboot作为bootloader工具,因此学习uboot的移植具有实际工作意义。
Uboot为开源项目,源码网站为: ftp://ftp.denx.de/pub/u-boot/。移植时可以从官方网站选取一个版本下载,然后以此为基础进行移植工作。但因为官网uboot中支持的开发板型号毕竟有限,因此移植的难度通常较高。
简单些的方法就是选择芯片厂商以官网uboot为基础再次移植过的uboot源码,以此为基础来进行移植难度就降低了很多了。譬如我们的开发板SQ210使用了三星公司的SoC S5PV210,而三星公司针对该SoC推出的开发SDK为SMDKV210(实际上市面上所有的210开发板都是参考三星官方的SMDKV210修改而来,因此均大同小异。),并且为该开发平板提供了uboot、kernel等的移植。我们的移植便是以此三星公司提供的移植后的uboot源码(android_uboot_smdkv210.tar.bz2)为基础的。
第一部分:环境准备
1.1、VMWare与ubuntu安装,推荐VMWare使用8.0.2版,ubuntu使用10.04
1.2、交叉编译工具安装,推荐使用arm-2009q3。
第二部分:uboot基本功能移植
2.1、编译体验
2.1.1、编译目录建立、源码复制与解压
解压源码 # tar –jxvf android_uboot_smdkv210.tar.bz2
重命名 # mv u-boot-samsung-dev/ sq210_uboot
2.1.2、配置编译
首先确认Makefile中CROSS_COMPILE两个变量的值
ifeq ($(ARCH),arm)
#CROSS_COMPILE = arm-linux-
#CROSS_COMPILE = /usr/local/arm/4.4.1-eabi-cortex-a8/usr/bin/arm-linux-
#CROSS_COMPILE = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-
CROSS_COMPILE = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
Endif

若之前按照文档中目录安装了交叉工具链,则此处不需修改,或修改为CROSS_COMPILE = arm-linux-,因为我们已经在安装的工具链中创建了符号链接,并且导出了环境变量。
然后配置: make smdkv210single_config
最后编译: make
编译完成后在源码树根目录下生成u-boot.bin,这就是我们移植的目标了。通过usb下载运行,结果发现串口没有任何信息输出···说明这个uboot是不可以直接使用的。
2.2、初步移植
(1)、开发配置文件: # vi include/configs/smdkv210single.h
修改第145行中关于串口的定义(SERIAL3改为SERIAL1)
00145:#define CONFIG_SERIAL1 1 /* we use UART1 on SMDKC110 */
(2)、修改底层初始化函数 # vi board/samsung/smdkc110/lowlevel_init.S
注释掉第118行关于PMIC(电源管理IC)的初始化函数。
00118: // bl PMIC_InitIp
(3)、重新配置、编译
# make distclean
# make smdkv210single_config
# make
通过usb下载sq210_usb.bin到0xd0020010中
通过usb下载u-boot.bin到0x23e0_0000开发板中
,可以看到如下的启动信息:
U-Boot移植总结
Uboot终于工作起来了,但是还是有很多问题。譬如:
1、将该uboot固化烧写到NandFlash后,从Nand启动发现不能正常启动。
2、启动信息中显示DRAM为1GB,但是SQ210上实际为512MB。
3、启动信息中显示Flash为8M,但是SQ210上实际根本没有NorFlash。
问题分析:造成以上问题的原因主要是uboot配置中DRAM的配置信息和初始化代码和SQ210开发板不相符。查阅原理图可知,SQ210共有512MB DRAM,均接在BANK1上;而SMDKV210开发板中DRAM共有1GB(BANK1和BANK2各512MB),因此需要根据这些不同来调整配置文件和DRAM初始化代码才能解决问题。
2.3、DRAM配置和初始化移植
首先修改配置文件中DRAM控制器的配置参数。这里因为三星移植的配置文件(smdkv210single.h)中定义了各种时钟配置,而DRAM控制器的配置又与时钟配置有关联,因此更改DRAM控制器配置时要先确认好所使用的时钟,找准位置以免更改出错。
# vi include/configs/smdkv210single.h

#elif defined(CONFIG_CLK_800_200_166_133) || \
defined(CONFIG_CLK_1000_200_166_133) || \
defined(CONFIG_CLK_800_100_166_133) || \
defined(CONFIG_CLK_400_200_166_133) || \
defined(CONFIG_CLK_400_100_166_133)

#if defined(CONFIG_MCP_SINGLE)
#define DMC0_MEMCONTROL 0x00202400 // 添加该行
#define DMC0_MEMCONFIG_0 0x20E01323 // MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_1 0x40F01323 // MemConfig1
#define DMC0_TIMINGA_REF 0x00000618 // TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
#define DMC0_TIMING_ROW 0x28233287 // TimingRow for @200MHz
#define DMC0_TIMING_DATA 0x23240304 // TimingData CL=3
#define DMC0_TIMING_PWR 0x09C80232 // TimingPower

#define DMC1_MEMCONTROL 0x00202400 // MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
#define DMC1_MEMCONFIG_0 0x40C01323 // MemConfig0 512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC1_MEMCONFIG_1 0x00E01323 // MemConfig1
#define DMC1_TIMINGA_REF 0x00000618 // TimingAref 7.8us*133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4
#define DMC1_TIMING_ROW 0x28233289 // TimingRow for @200MHz
#define DMC1_TIMING_DATA 0x23240304 // TimingData CL=3
#define DMC1_TIMING_PWR 0x08280232 // TimingPower
----------------我-----是-----分-----割-----线-------------------------
#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
#define SDRAM_BANK_SIZE 0x20000000 /* 512 MB */
#define PHYS_SDRAM_1 MEMORY_BASE_ADDRESS /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE
//#define PHYS_SDRAM_2 (MEMORY_BASE_ADDRESS + SDRAM_BANK_SIZE) /* SDRAM Bank #2 */
//#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE

只更改配置文件还不够,DRAM初始化部分代码也要做相应修改。代码在 cpu/s5pc11x/s5pc110/cpu_init.S中的 mem_ctrl_asm_init 函数中。
# vi cpu/s5pc11x/s5pc110/cpu_init.S
将122行:
ldr r1, =0x00212400
修改为:
ldr r1, = DMC0_MEMCONTROL即可。

# make distclean && make smdkv210single_config && make,usb下载运行,即可看到如下启动信息。可见,DRAM已经识别正确了。
U-Boot移植总结
注:提示信息最后的NAND ECC 错误信息是因为板子上NandFlash内部烧录过其他内容,可以通过在烧录uboot前擦除整个NandFlash解决(# nand erase 0x0 0x20000000)。
2.4、DM9000网卡移植
网卡驱动的移植对uboot来说至关重要,内核和根文件系统等均需要通过uboot的tftp服务来download到板子上。
首先,uboot中已经实现了DM9000的网卡驱动(实际上是从linux内核源码中借用而来,即uboot源码目录的drivers/net/dm9000.c),驱动本身是不需要移植修改的。我们只需修改以下两点硬件相关部分即可:
(1)、配置文件中DM9000的硬件信息
(2)、板级初始化中关于硬件的初始化代码
首先修改配置文件,# vi include/configs/smdkv210single.h
#define DM9000_16BIT_DATA //128行

#define CONFIG_DRIVER_DM9000 1

#ifdef CONFIG_DRIVER_DM9000
#define CONFIG_DM9000_BASE ( 0x88000000) // srom bank 1
#define DM9000_IO (CONFIG_DM9000_BASE)
#if defined(DM9000_16BIT_DATA)
#define DM9000_DATA (CONFIG_DM9000_BASE+ 8) // cmd pin linked Xm0ADDR2
#else
#define DM9000_DATA (CONFIG_DM9000_BASE+1)
#endif
#endif

然后修改硬件初始化文件,# vi board/samsung/smdkc110/smdkc110.c
static void dm9000_pre_init(void)
{
unsigned int tmp;

#if defined(DM9000_16BIT_DATA)
SROM_BW_REG &= ~ (0xf << 4);
SROM_BW_REG |= (1<<4);

#else
SROM_BW_REG &= ~(0xf << 20);
SROM_BW_REG |= (0<<19) | (0<<18) | (0<<16);
#endif
SROM_BC1_REG = ((0<<28)|(1<<24)|(5<<16)|(1<<12)|(4<<8)|(6<<4)|(0<<0));

tmp = MP01CON_REG;
tmp &=~ (0xf<<4);
tmp |= (2<<4);
MP01CON_REG = tmp;
}
先# make distclean && make smdkv210single_config && make,usb下载运行后。使用printenv查看环境变量设置,setenv设置ipaddr与serverip,设置原则为serverip等于主机ip地址,而ipaddr设置为与serverip在同一网段。譬如我的tftp服务器在主机ubuntu中搭建,主机ubuntu的ip地址为192.168.1.141,则
# set ipaddr 192.168.1.10
# set serverip 192.168.1.141
然后使用ping命令测试是否可以ping通主机
# ping 192.168.1.141
U-Boot移植总结
正常情况下会打印以上内容,表示此时已ping通主机。在主机已经搭建tftp服务器的情况下,此时便可以通过tftp服务器从主机ubuntu中下载文件到板子上了。以下命令用于从主机下载烧录u-boot.bin到板子上Nand中。(注意在tftp下载前先要复制最新的u-boot.bin 文件到主机ubuntu中tftp服务器的共享文件夹中)
# tftp 0x20000000 u-boot.bin
# nand erase 0x0 0x60000
# nand write 0x20000000 0x0 0x60000

2.5、杂项
以上几部分移植完成后,我们的uboot已经可以下载烧录文件了(实际上也已经可以用来启动内核了)。主要功能已经完成,但还有一些地址可以修改以让uboot更好的工作。
2.5.1、修改默认IP信息
在配置文件中修改了内置默认的IP信息后,第一次烧录后不用再setenv设置IP信息就可以直接ping通主机,进行tftp下载等,很方便。
vim include/autoconf.mk
#define CONFIG_ETHADDR 00:40:5c:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.20
#define CONFIG_SERVERIP 192.168.1.141
#define CONFIG_GATEWAYIP 192.168.1.1
2.5.2、修改提示信息
提示信息中最明显的莫过于uboot命令行前的提示符。之前默认为SMDKV210 #,可以修改以使其匹配我们的开发板。
vim include/configs/smdkv210single.h
#define CFG_PROMPT " SQ210 # "
#define CONFIG_IDENT_STRING " for SQ210"

# vi board/Samsung/smdkc110/smdkc110.c
int checkboard(void)
{
#ifdef CONFIG_MCP_SINGLE
#if defined(CONFIG_VOGUES)
printf("\nBoard: VOGUESV210\n");
#else
printf("\nBoard: SQ210\n");
#endif //CONFIG_VOGUES
#else
printf("\nBoard: SMDKC110\n");
#endif
return (0);
}
当然了,修改了配置文件后,还是需要先make distclean再配置再编译的。
# make distclean && make smdkv210single_config && make


附录(下载、烧写U-Boot步骤,s5pv210为例):

          1. 使用USB线通过DNW下载sq210_usb.bin到0xd0020010(初始化板子,使板子有一个下载环境)

          2. 使用USB线通过DNW下载u-boot.bin到0x23e00000(下载到内存(RAM))

          3. 烧录uboot(烧写到flash)
                                 nand erase 0x0 0x60000
                                 tftp 0x20008000 u-boot.bin
                                 nand write 0x20008000 0x0 0x60000