总结uboot从源码移植的过程,是从飞凌6410的板子中修改而来。
1、查看U-Boot目录结构(一般要修改的内容在cpu、board、 common、lib_xx、include等目录下)2、对照自己的开发板的CPU型号、生产厂商、具体型号以及开发板的原理图,修改相应的配置文件,如串口、网卡、 存储器等。
第一阶段:
1、打开u-boot主目录下的makefile,找到smdk2410_config,在其下,仿照它的格式加入如下语句
forlinx_linux_config :unconfig
@$(MKCONFIG) $(@:_config=) arm s5pc11x smdkc110 samsung s5pc110 linux
@echo "TEXT_BASE = 0xcc800000" > $(obj)board/samsung/smdkc110/config.mk
@$(MKCONFIG) $(@:_config=) arm s5pc11x smdkc110 samsung s5pc110 linux
@echo "TEXT_BASE = 0xcc800000" > $(obj)board/samsung/smdkc110/config.mk
各项的意思如下:
arm: CPU的架构(ARCH)
s5pc11x : CPU的类型(CPU),其对应于cpu/s5pc11x 子目录。
smdkc110 : 开发板的型号(BOARD),对应于board/samsung /smdkc110 目录。
samsung : 开发者/或经销商(vender)。
s5pc110 : 片上系统(SOC)。
arm: CPU的架构(ARCH)
s5pc11x : CPU的类型(CPU),其对应于cpu/s5pc11x 子目录。
smdkc110 : 开发板的型号(BOARD),对应于board/samsung /smdkc110 目录。
samsung : 开发者/或经销商(vender)。
s5pc110 : 片上系统(SOC)。
此步是为了加入自已的开发板,非必须也可以在现有的开发板基础上修改。
2、在Makefile修改CROSS_COMPILE为自已的arm gcc编译器,我使用的是系统默认的arm-linux-gcc,故不必再修改相应的CROSS_COMPILE项。’
CROSS_COMPILE = /home/4.4.1/bin/arm-linux-
3 、在/board子目录中建立自己的开发板smdkc110 目录由于我在上一步板子的开发者/或经销商(vender)中填了samsung ,所以开发板smdkc110 目录一定要建在/board子目录中的samsung目录下 ,否则编译会出错。 即board/samsung/smdkc110/
然后,将飞凌源码的/samsung/smdk6410/目录下的文件考入smdkc110目录下。
并将其中的smdk6410.c改名为smdkc110.c
还要记得修改自己的开发板board/samsung/smdkc110/目录下的Makefile文件,不然编译时会出错:
并将其中的smdk6410.c改名为smdkc110.c
还要记得修改自己的开发板board/samsung/smdkc110/目录下的Makefile文件,不然编译时会出错:
OBJS:= smdkc110.o flash.o
4 在include/configs/中建立配置头文件smdkv210single.h
将飞凌include/configs/smdk6410.h的相应头文件复制一份在相同目录下。并改名为smdkv210single.h
将飞凌include/configs/smdk6410.h的相应头文件复制一份在相同目录下。并改名为smdkv210single.h
定义自己的打印调试串口,S5PV使用串口2
#if 0
#define CONFIG_SERIAL3 1 /* we use UART2 on SMDKC110 */
#else
#define CONFIG_SERIAL2 1 /* we use UART1 on SMDKC110 */
#endif
#define CONFIG_SERIAL3 1 /* we use UART2 on SMDKC110 */
#else
#define CONFIG_SERIAL2 1 /* we use UART1 on SMDKC110 */
#endif
定义u-boot传给内核启动参数的定义,以及u-boot中对以太网卡的参数设置。
#define CONFIG_BOOTARGS "console=ttySAC1,115200 root=/dev/mtdblock2 init=/linuxrc androidboot.console=ttySAC1"
#define CONFIG_ETHADDR 00:22:12:34:56:90
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.32.107
#define CONFIG_SERVERIP 192.168.32.43
#define CONFIG_GATEWAYIP 192.168.32.1
#define CONFIG_ETHADDR 00:22:12:34:56:90
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.32.107
#define CONFIG_SERVERIP 192.168.32.43
#define CONFIG_GATEWAYIP 192.168.32.1
nand flash的分区定义,如果linux内核对nand flash的分区有改动时,这里也想相应的改动。设定了u-boot读取内核的地址,这个要和镜像烧写的地址一致,不然是无法启动内核文件的。
#ifdef CONFIG_LINUX_FORLINX
#define CONFIG_BOOTCOMMAND "nand read C0008000 100000 500000; bootm C0008000"
#elif defined(CONFIG_ANDROID_FORLINX)
#define CONFIG_BOOTCOMMAND "nand read C0008000 600000 500000; bootm C0008000"
#endif
//#define CONFIG_BOOTCOMMAND "tftp c0008000 zImage;bootm c0008000"
#elif defined(CFG_FASTBOOT_SDMMCBSP)
#define CONFIG_BOOTCOMMAND "movi read kernel C0008000; movi read rootfs 30800000 180000; bootm C0008000 30800000"
#endif
#define CONFIG_BOOTCOMMAND "nand read C0008000 100000 500000; bootm C0008000"
#elif defined(CONFIG_ANDROID_FORLINX)
#define CONFIG_BOOTCOMMAND "nand read C0008000 600000 500000; bootm C0008000"
#endif
//#define CONFIG_BOOTCOMMAND "tftp c0008000 zImage;bootm c0008000"
#elif defined(CFG_FASTBOOT_SDMMCBSP)
#define CONFIG_BOOTCOMMAND "movi read kernel C0008000; movi read rootfs 30800000 180000; bootm C0008000 30800000"
#endif
5 回到u-boot主目录,makeforlinx_linux_config,再make,编译生成u-boot.bin成功。
第1阶段完成。
第2阶段
/cpu/s5pc11x/start.s (加入时钟相关的寄存器定义,加入时钟初始化代码)
board/samsung/smdkc110/lowlevel_init.s(加入210内存控制寄存器的定义)
修改board/samsung/smdkc110/smdkc110.c 中GPIO,PLL的设置
board/samsung/smdkc110/lowlevel_init.s(加入210内存控制寄存器的定义)
修改board/samsung/smdkc110/smdkc110.c 中GPIO,PLL的设置
writel(0x0, GPF0PUD); //GPF0PUD set pull-up,down disable
writel(0x22222222, GPF1CON); //set GPF1CON[7:0] as VD[11:4]
writel(0x0, GPF1PUD); //GPF1PUD set pull-up,down disable
writel(0x22222222, GPF2CON); //set GPF2CON[7:0] as VD[19:12]
writel(0x0, GPF2PUD); //GPF2PUD set pull-up,down disable
writel(0x00002222, GPF3CON); //set GPF3CON[3:0] as VD[23:20]
writel(0x0, GPF3PUD); //GPF3PUD set pull-up,down disable
//--------- S5PC110 EVT0 needs MAX drive strength---------//
writel(0xffffffff, GPF0DRV); //set GPF0DRV drive strength max by WJ.KIM(09.07.17)
writel(0xffffffff, GPF1DRV); //set GPF1DRV drive strength max by WJ.KIM(09.07.17)
writel(0xffffffff, GPF2DRV); //set GPF2DRV drive strength max by WJ.KIM(09.07.17)
writel(0x3ff, GPF3DRV); //set GPF3DRV drive strength max by WJ.KIM(09.07.17)
board_lcd_init();
int board_init(void);
int dram_init(void);
void nand_init(void);
在include/configs/smdkv210single.h中设置时钟
在include/configs/smdkv210single.h中设置时钟
#define CONFIG_SYS_CLK_FREQ 24000000 /* the SMDK6400 has 24MHz input clock */
环境变量
#define CONFIG_S5PC110 1 /* in a SAMSUNG S3C6410 SoC */
#define CONFIG_S5PC11X 1 /* in a SAMSUNG S3C64XX Family */
#define CONFIG_SMDKC110 1
#define CONFIG_S5PC11X 1 /* in a SAMSUNG S3C64XX Family */
#define CONFIG_SMDKC110 1
include/configs/smdkv210single.h定义波特率
#define CONFIG_BAUDRATE 115200
mem地址
#define CFG_MEMTEST_START MEMORY_BASE_ADDRESS /* memtest works on */
//#define CFG_MEMTEST_END MEMORY_BASE_ADDRESS + 0x3E00000
#define CFG_MEMTEST_END MEMORY_BASE_ADDRESS + 0xC800000
//#define CFG_MEMTEST_END MEMORY_BASE_ADDRESS + 0x3E00000
#define CFG_MEMTEST_END MEMORY_BASE_ADDRESS + 0xC800000
DRAM配置和初始化移植,DRAM控制器的配置又与时钟配置有关联,因此更改DRAM控制器配置时要先确认好所使用的时钟。
//#define DMC0_MEMCONTROL 0x00212400 //MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
#define DMC0_MEMCONTROL 0x00202400 // MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
//#define DMC0_MEMCONFIG_0 0x20E01323 // MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_0 0x20F01313
//#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_ROW 0x28255287
//#define DMC0_TIMING_DATA 0x23240304 // TimingData CL=4
//#define DMC0_TIMING_DATA 0x23250304 // CL=5
#define DMC0_TIMING_DATA 0x23230304 //CL=3 important 2013 05 21 -BeiJing
#define DMC0_TIMING_PWR 0x09C80232 // TimingPower
#define DMC0_MEMCONTROL 0x00202400 // MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
//#define DMC0_MEMCONFIG_0 0x20E01323 // MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC0_MEMCONFIG_0 0x20F01313
//#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_ROW 0x28255287
//#define DMC0_TIMING_DATA 0x23240304 // TimingData CL=4
//#define DMC0_TIMING_DATA 0x23250304 // CL=5
#define DMC0_TIMING_DATA 0x23230304 //CL=3 important 2013 05 21 -BeiJing
#define DMC0_TIMING_PWR 0x09C80232 // TimingPower
#define DMC1_MEMCONTROL 0x00202400 // MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
//#define DMC1_MEMCONTROL 0x00212400
//#define DMC1_MEMCONFIG_0 0x40C01323 // MemConfig0 512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC1_MEMCONFIG_0 0x40F01313
//#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_ROW 0x28255287
//#define DMC1_TIMING_DATA 0x23240304 // TimingData CL=4
//#define DMC1_TIMING_DATA 0x23250304 // CL=5
#define DMC1_TIMING_DATA 0x23230304 //CL=3 important 2013 05 21 -BeiJing
#define DMC1_TIMING_PWR 0x08280232 // TimingPower
//#define DMC1_MEMCONTROL 0x00212400
//#define DMC1_MEMCONFIG_0 0x40C01323 // MemConfig0 512MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
#define DMC1_MEMCONFIG_0 0x40F01313
//#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_ROW 0x28255287
//#define DMC1_TIMING_DATA 0x23240304 // TimingData CL=4
//#define DMC1_TIMING_DATA 0x23250304 // CL=5
#define DMC1_TIMING_DATA 0x23230304 //CL=3 important 2013 05 21 -BeiJing
#define DMC1_TIMING_PWR 0x08280232 // TimingPower
#define DMC0_TIMINGA_REF 0x50e
#define DMC0_TIMING_ROW 0x14233287
#define DMC0_TIMING_DATA 0x12130005
#define DMC0_TIMING_PWR 0x0E140222
#define DMC1_TIMINGA_REF 0x618
#define DMC1_TIMING_ROW 0x11344309
#define DMC1_TIMING_DATA 0x12130005
#define DMC1_TIMING_PWR 0x0E190222
#define DMC0_TIMING_ROW 0x14233287
#define DMC0_TIMING_DATA 0x12130005
#define DMC0_TIMING_PWR 0x0E140222
#define DMC1_TIMINGA_REF 0x618
#define DMC1_TIMING_ROW 0x11344309
#define DMC1_TIMING_DATA 0x12130005
#define DMC1_TIMING_PWR 0x0E190222
#define CONFIG_NR_DRAM_BANKS 2 /* we have 2 bank of DRAM */
#define SDRAM_BANK_SIZE 0x10000000 /* 256 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*2) /* SDRAM Bank #2 */
//#define PHYS_SDRAM_2 (MEMORY_BASE_ADDRESS + SDRAM_BANK_SIZE) /* SDRAM Bank #2 */
#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE
#define CFG_FLASH_BASE 0x80000000
#define SDRAM_BANK_SIZE 0x10000000 /* 256 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*2) /* SDRAM Bank #2 */
//#define PHYS_SDRAM_2 (MEMORY_BASE_ADDRESS + SDRAM_BANK_SIZE) /* SDRAM Bank #2 */
#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE
#define CFG_FLASH_BASE 0x80000000
以下文件主要加入自己的定义
/inlcude/s5pc100.h中增加自己各项基地址的定义
/inlcude/s5pc100.h中增加自己各项基地址的定义
typedef enum {
S5PC1XX_UART0,
S5PC1XX_UART1,
S5PC1XX_UART2,
S5PC1XX_UART3,
} S5PC1XX_UARTS_NR;
#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004
#define BIT3 0x00000008
S5PC1XX_UART0,
S5PC1XX_UART1,
S5PC1XX_UART2,
S5PC1XX_UART3,
} S5PC1XX_UARTS_NR;
#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004
#define BIT3 0x00000008
...........
/cpu/s5pc11x/serial.c中
#elif defined(CONFIG_SERIAL2)
#define UART_NR S5PC11X_UART1
#define UART_NR S5PC11X_UART1
S5PC11X_UART *const uart = S5PC11X_GetBase_UART(UART_NR);
/lib_arm/board.c中增加
#if defined(CONFIG_SMDKC100)
#if defined(CONFIG_GENERIC_MMC)
puts ("SD/MMC: ");
mmc_exist = mmc_initialize(gd->bd);
if (mmc_exist != 0)
{
puts ("0 MB\n");
}
#endif
#if defined(CONFIG_CMD_ONENAND)
puts("OneNAND: ");
onenand_init();
#endif
#if defined(CONFIG_CMD_NAND)
puts("NAND: ");
nand_init();
#endif
#endif /* CONFIG_SMDKC100 */
#if defined(CONFIG_GENERIC_MMC)
puts ("SD/MMC: ");
mmc_exist = mmc_initialize(gd->bd);
if (mmc_exist != 0)
{
puts ("0 MB\n");
}
#endif
#if defined(CONFIG_CMD_ONENAND)
puts("OneNAND: ");
onenand_init();
#endif
#if defined(CONFIG_CMD_NAND)
puts("NAND: ");
nand_init();
#endif
#endif /* CONFIG_SMDKC100 */
方便u-boot的调试,因此,我要将此u-boot代码再做一修改,使其可以在内存中运行。 要想它在内存中运行,方法很简单,将 /cpu/s5pc11x/start.s 中的start.s中
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
此段代码中的bl cpu_init_crit注释掉,即不进行CPU的初始化工作
修改board\samsung\smdkc110\config.mk中text_base 值为TEXT_BASE = 0xcc800000
使用命令load ram 0xcc800000 0x17ea8 x将u-boot.bin装入内存。再用go 0xcc800000命令,即可。
至此,第2阶段工作完成。
第3阶段
本阶段任务,是给u-boot移植dm9000的网卡驱动。
u-boot自带网卡驱动,所以只要做些设置即可。
/include/configs/smdkv210single.h (加入dm9000定义,加入ping命令定义)
本阶段任务,是给u-boot移植dm9000的网卡驱动。
u-boot自带网卡驱动,所以只要做些设置即可。
/include/configs/smdkv210single.h (加入dm9000定义,加入ping命令定义)
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE (0x88000300)
#define CONFIG_DM9000_USE_16BIT
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+0x4)
#define DM9000_16BIT_DATA
#define CONFIG_DM9000_BASE (0x88000300)
#define CONFIG_DM9000_USE_16BIT
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+0x4)
#define DM9000_16BIT_DATA
#define CONFIG_BOOTARGS "console=ttySAC1,115200 root=/dev/mtdblock2 init=/linuxrc androidboot.console=ttySAC1"
#define CONFIG_ETHADDR 00:22:12:34:56:90
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.32.107
#define CONFIG_SERVERIP 192.168.32.43
#define CONFIG_GATEWAYIP 192.168.32.1
#define CONFIG_ETHADDR 00:22:12:34:56:90
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.32.107
#define CONFIG_SERVERIP 192.168.32.43
#define CONFIG_GATEWAYIP 192.168.32.1
#define CONFIG_CMD_PING
可以
ping通网络了。(也可以在u-boot启动后,修改相关参数,但因为现阶段还没有支持nandflash,参数无法保存,故在此改变较为方
便)
又发现,ping是能ping通了,但报could not establish link(不能建立链接)的错。不影响使用。参考网上的资料,发现这是因为
在网卡驱动中,/drivers/net/dm9000.c,有一段程序试图连接网卡的MII接口,而实际上MII接口并未使用
,所以有十秒的等待时间,且报错,将此段程序注释掉即可。
到此,本阶段任务完成。