u-boot移植

【实验环境】
1、ubuntu 14.04
2、u-boot-2013.01
3、FS_4412平台(EXYNOS 4412)
4、交叉编译器 arm-none-linux-gnueabi-gcc

开始移植:
一、建立自己的平台
1、下载源码 ftp://ftp.denx.de/pub/u-boot/
我们采用的是u-boot-2013.01
2、解压uboot源码并进入目录
把压缩文件拷贝到虚拟机,并解压
$ tar xvf u-boot-2013.01.tar.bz2
$ cd u-boot-2013.013
3、指定交叉编译工具链
$ vim Makefile

ifeq ( ( H O S T A R C H ) , (HOSTARCH), (HOSTARCH),(ARCH))
CROSS_COMPILE ?=
#endif
改为
ifeq(arm,$(ARCH))
CROSS_COMPILE ?= arm-none-linux-gnueabi-
#endif
4、指定产品CPU
我们产品用的CPU是 exynos 4412
查看u-boot源码该CPU 是否已支持
U-boot已支持,见 arch/arm/cpu/armv7/exynos
5、指定产品BOARD
找一个最类似的board配置修改, 这里我们参考的是board/samsung/origen/
$ cp -rf board/samsung/origen/ board/samsung/fs4412
$cd board/samsung/fs4412/
$mv origen.c fs4412.c
$ vim board/samsung/fs4412/Makefile
修改origen.o 为 fs4412.o
$ cd include/configs/
$ vi include/configs/fs4412.h
修改
#define CONFIG_SYS_PROMPT “ORIGEN #”

#define CONFIG_SYS_PROMPT “fs4412 #”

修改
#define CONFIG_IDENT_STRING for ORIGEN

#define CONFIG_IDENT_STRING for fs4412
#vim boards.cfg
参考
origen arm armv7 origen samsung exynos
并在后面新增
fs4412 arm armv7 fs4412 samsung exynos
6、编译u-boot
$ make distclean
$ make fs4412_config
$ make
编译完成后生成的u-boot.bin就是可执行的镜像文件。
但是该文件还不能在我们板子上运行,我们需要对u-boot源代码进行相应的修改。

二、实现能看到串口终端信息
1、确认第一条指令有运行到(点灯法)
在arch/arm/cpu/armv7/start.S 134 行后添加点灯程序
程序从这里启动,添加点灯程序,监控运行
#if 1
ldr r0, =0x11000c40 @GPK2_7 led2
ldr r1, [r0]
bic r1, r1, #0xf0000000
orr r1, r1, #0x10000000
str r1, [r0]

	ldr r0, =0x11000c44
	mov r1,#0xff
	str r1, [r0]

#endif
添加三星加密方式
exynos 需要三星提供的初始引导加密后,我们的u-boot,才能被引导运行
$cp sdfuse_q u-boot-2013.01-rf
注:sdfuse_q 三星提供的加密处理
$cp CodeSign4SecureBoot u-boot-2013.01 -rf
注:CodeSign4SecureBoot 三星提供的安全启动方式

修改Makefile
$vim Makefile
修改实现sdfuse_q的编译

$(obj)u-boot.bin: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
$(BOARD_SIZE_CHECK)
下添加
@#./mkuboot
@split -b 14336 u-boot.bin bl2
@+make -C sdfuse_q/
@#cp u-boot.bin u-boot-4212.bin
@#cp u-boot.bin u-boot-4412.bin
@#./sdfuse_q/add_sign
@./sdfuse_q/chksum
@./sdfuse_q/add_padding
@rm bl2a*
@echo
注意是tab键缩进的,否则makefile编译报错
注意如果执行了make distclean 需重新拷贝CodeSign4SecureBoot

拷贝编译脚本
$cp build.sh u-boot-2013.01
$chmod 777 u-boot-2013.01/ build.sh
$ ./buildsh
注:build.sh 脚本方式完成自动添加加密方式,
编译生成所需文件u-boot_fs4412.bin
烧写新的u-boot_fs4412.bin
复位,发现灯有点亮,说明我们的u-boot有运行到

2、实现串口输出
修改lowlevel_init.S文件
$vimboard/samsung/fs4412/lowlevel_init.S
添加临时栈

lowlevel_init:
后添加
ldr sp,=0x02060000 @use iRom stack in bl2

添加关闭看门狗代码

beq wakeup_reset
后添加
#if 1 /*for close watchdog /
/
PS-Hold high /
ldr r0, =0x1002330c
ldr r1, [r0]
orr r1, r1, #0x300
str r1, [r0]
ldr r0, =0x11000c08
ldr r1, =0x0
str r1, [r0]
/
Clear MASK_WDT_RESET_REQUEST */
ldr r0, =0x1002040c
ldr r1, =0x00
str r1, [r0]
#endif

添加串口初始化代码
在uart_asm_init: 的
str r1, [r0, #EXYNOS4_GPIO_A1_CON_OFFSET]
后添加
ldr r0, =0x10030000
ldr r1, =0x666666
ldr r2, =CLK_SRC_PERIL0_OFFSET
str r1, [r0, r2]
ldr r1, =0x777777
ldr r2, =CLK_DIV_PERIL0_OFFSET
str r1, [r0, r2]

注释掉trustzone初始化
注释掉
bl uart_asm_init
下的
bl tzpc_init

重新编译u-boot

$ ./build.sh
烧写新的u-boot_fs4412.bin
复位会看到串口信息
u-boot移植_第1张图片

三、网卡移植
1、添加网络初始化代码
$vim board/samsung/fs4412/fs4412.c
在struct exynos4_gpio_part2 *gpio2; 后添加
#ifdef CONFIG_DRIVER_DM9000
#define EXYNOS4412_SROMC_BASE 0X12570000

#define DM9000_Tacs (0x1)
#define DM9000_Tcos (0x1)
#define DM9000_Tacc (0x5)
#define DM9000_Tcoh (0x1)
#define DM9000_Tah (0xC)
#define DM9000_Tacp (0x9)
#define DM9000_PMC (0x1)

struct exynos_sromc {
unsigned int bw;
unsigned int bc[6];
};

/*

  • s5p_config_sromc() - select the proper SROMC Bank and configure the

  • band width control and bank control registers

  • srom_bank - SROM

  • srom_bw_conf - SMC Band witdh reg configuration value

  • srom_bc_conf - SMC Bank Control reg configuration value
    */
    void exynos_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf)
    {
    unsigned int tmp;
    struct exynos_sromc *srom = (struct exynos_sromc *)(EXYNOS4412_SROMC_BASE);

     /* Configure SMC_BW register to handle proper SROMC bank */
    

tmp = srom->bw;
tmp&= ~(0xF << (srom_bank * 4));
tmp |= srom_bw_conf;
srom->bw = tmp;

    /* Configure SMC_BC register */

srom->bc[srom_bank] = srom_bc_conf;
}
static void dm9000aep_pre_init(void)
{
unsigned int tmp;
unsigned char smc_bank_num = 1;
unsigned int smc_bw_conf=0;
unsigned int smc_bc_conf=0;

   /* gpio configuration */

writel(0x00220020, 0x11000000 + 0x120);
writel(0x00002222, 0x11000000 + 0x140);
/* 16 Bit bus width */
writel(0x22222222, 0x11000000 + 0x180);
writel(0x0000FFFF, 0x11000000 + 0x188);
writel(0x22222222, 0x11000000 + 0x1C0);
writel(0x0000FFFF, 0x11000000 + 0x1C8);
writel(0x22222222, 0x11000000 + 0x1E0);
writel(0x0000FFFF, 0x11000000 + 0x1E8);
smc_bw_conf &= ~(0xf<<4);
smc_bw_conf |= (1<<7) | (1<<6) | (1<<5) | (1<<4);
smc_bc_conf = ((DM9000_Tacs << 28)
| (DM9000_Tcos << 24)
| (DM9000_Tacc << 16)
| (DM9000_Tcoh << 12)
| (DM9000_Tah << 8)
| (DM9000_Tacp << 4)
| (DM9000_PMC));
exynos_config_sromc(smc_bank_num,smc_bw_conf,smc_bc_conf);
}
#endif

在gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); 后添加

#ifdef CONFIG_DRIVER_DM9000
dm9000aep_pre_init();
#endif

在文件末尾添加

#ifdef CONFIG_CMD_NET
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_DRIVER_DM9000
rc = dm9000_initialize(bis);
#endif
return rc;
}
#endif
2、 修改配置文件添加网络相关配置
$ vim include/configs/fs4412.h
修改
#undef CONFIG_CMD_PING

#def ine CONFIG_CMD_PING

修改
#undef CONFIG_CMD_NET  
为
#def ine  CONFIG_CMD_NET

在文件末尾
#endif	/* __CONFIG_H */   
前面添加

#ifdef CONFIG_CMD_NET
#define CONFIG_NET_MULTI
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x05000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
#define CONFIG_DM9000_USE_16BIT
#define CONFIG_DM9000_NO_SROM 1
#define CONFIG_ETHADDR 11:22:33:44:55:66
#define CONFIG_IPADDR 192.168.1.100
#define CONFIG_SERVERIP 192.168.1.50
#define CONFIG_GATEWAYIP 192.168.1.1
#define CONFIG_NETMASK 255.255.255.0
#endif
3、重新编译u-boot
$ ./build.sh
烧写新的u-boot_fs4412.bin
复位后

u-boot移植_第2张图片

四、FLASH移植(EMMC)
1、 初始化EMMC
$cp movi.c arch/arm/cpu/armv7/exynos/
$vim arch/arm/cpu/armv7/exynos/Makefile
在pinmux.o 后添加movi.o

修改板级文件
$vim board/samsung/fs4412/fs4412.c

#include
后面添加
#include
#include “origen_setup.h”


#ifdef CONFIG_GENERIC_MMC
后面添加
u32 sclk_mmc4; /clock source for emmc controller/
#define __REGMY(x) (*((volatile u32 *)(x)))
#define CLK_SRC_FSYS __REGMY(EXYNOS4_CLOCK_BASE + CLK_SRC_FSYS_OFFSET)
#define CLK_DIV_FSYS3 __REGMY(EXYNOS4_CLOCK_BASE + CLK_DIV_FSYS3_OFFSET)

int emmc_init()
{
u32 tmp;
u32 clock;
u32 i;
/* setup_hsmmc_clock /
/
MMC4 clock src = SCLKMPLL /
tmp = CLK_SRC_FSYS & ~(0x000f0000);
CLK_SRC_FSYS = tmp | 0x00060000;
/
MMC4 clock div */
tmp = CLK_DIV_FSYS3 & ~(0x0000ff0f);
clock = get_pll_clk(MPLL)/1000000;

for(i=0 ; i<=0xf; i++)  {
sclk_mmc4=(clock/(i+1));

		if(sclk_mmc4 <= 160) //200
     {
			CLK_DIV_FSYS3 = tmp | (i<<0);
			break;
		}
	}
emmcdbg("[mjdbg] sclk_mmc4:%d MHZ; mmc_ratio: %d\n",sclk_mmc4,i);
sclk_mmc4 *= 1000000;

/*
* MMC4 EMMC GPIO CONFIG
*
* GPK0[0]	SD_4_CLK
* GPK0[1]	SD_4_CMD
* GPK0[2]	SD_4_CDn
* GPK0[3:6]	SD_4_DATA[0:3]
*/
writel(readl(0x11000048)&~(0xf),0x11000048); //SD_4_CLK/SD_4_CMD pull-down enable
writel(readl(0x11000040)&~(0xff),0x11000040);//cdn set to be output

writel(readl(0x11000048)&~(3<<4),0x11000048); //cdn pull-down disable
writel(readl(0x11000044)&~(1<<2),0x11000044); //cdn output 0 to shutdown the emmc power
writel(readl(0x11000040)&~(0xf<<8)|(1<<8),0x11000040);//cdn set to be output
udelay(100*1000);
writel(readl(0x11000044)|(1<<2),0x11000044); //cdn output 1


writel(0x03333133, 0x11000040);

writel(0x00003FF0, 0x11000048);
writel(0x00002AAA, 0x1100004C);

#ifdef CONFIG_EMMC_8Bit
writel(0x04444000, 0x11000060);
writel(0x00003FC0, 0x11000068);
writel(0x00002AAA, 0x1100006C);
#endif

#ifdef USE_MMC4
smdk_s5p_mshc_init();
#endif
}

将 int board_mmc_init(bd_t *bis)函数内容改写为
int board_mmc_init(bd_t *bis)
{
int i, err;
#ifdef CONFIG_EMMC
err = emmc_init();
#endif
return err;
}

在末尾添加

#ifdef CONFIG_BOARD_LATE_INIT
#include
int chk_bootdev(void)//mj for boot device check
{
char run_cmd[100];
struct mmc *mmc;
int boot_dev = 0;
int cmp_off = 0x10;
ulong start_blk, blkcnt;

	mmc = find_mmc_device(0);

	if (mmc == NULL)
	{
		printf("There is no eMMC card, Booting device is SD card\n");
		boot_dev = 1;
		return boot_dev;
}
	start_blk = (24*1024/MOVI_BLKSIZE);
	blkcnt = 0x10;

	sprintf(run_cmd,"emmc open 0");
	run_command(run_cmd, 0);

	sprintf(run_cmd,"mmc read 0 %lx %lx %lx",CFG_PHY_KERNEL_BASE,start_blk,blkcnt);
run_command(run_cmd, 0);

	/* switch mmc to normal paritition */
	sprintf(run_cmd,"emmc close 0");
	run_command(run_cmd, 0);

	return 0;

}

int board_late_init (void)
{
int boot_dev =0 ;
char boot_cmd[100];
boot_dev = chk_bootdev();
if(!boot_dev)
{
printf("\n\nChecking Boot Mode … EMMC4.41\n");
}
return 0;
}
#endif

2、 添加相关命令
$ cp cmd_movi.c common/
$ cp cmd_mmc.c common/
$ cp cmd_mmc_fdisk.c common/

修改Makefile

$ vim common/Makefile

COBJS- ( C O N F I G C M D M M C ) + = c m d m m c . o 后 添 加 C O B J S − (CONFIG_CMD_MMC) += cmd_mmc.o 后添加 COBJS- (CONFIGCMDMMC)+=cmdmmc.oCOBJS(CONFIG_CMD_MMC) += cmd_mmc_fdisk.o
COBJS-$(CONFIG_CMD_MOVINAND) += cmd_movi.o

添加驱动

$ cp mmc.c drivers/mmc/
$ cp s5p_mshc.c drivers/mmc/
$ cp mmc.h include/
$ cp movi.h include/
$ cp s5p_mshc.h include/

修改Makefile

v i m d r i v e r s / m m c / M a k e f i l e 添 加 C O B J S − vim drivers/mmc/Makefile 添加 COBJS- vimdrivers/mmc/MakefileCOBJS(CONFIG_S5P_MSHC) += s5p_mshc.o

3、添加EMMC相关配置
$vim include/configs/fs4412.h
添加
#define CONFIG_EVT1 1 /* EVT1 */
#ifdef CONFIG_EVT1
#define CONFIG_EMMC44_CH4 //eMMC44_CH4 (OMPIN[5:1] = 4)

#ifdef CONFIG_SDMMC_CH2
#define CONFIG_S3C_HSMMC
#undef DEBUG_S3C_HSMMC
#define USE_MMC2
#endif

#ifdef CONFIG_EMMC44_CH4
#define CONFIG_S5P_MSHC
#define CONFIG_EMMC 1
#define USE_MMC4
/* #define CONFIG_EMMC_8Bit /
#define CONFIG_EMMC_EMERGENCY
/
#define emmcdbg(fmt,args…) printf(fmt ,##args) *///for emmc debug
#define emmcdbg(fmt,args…)
#endif

#endif /end CONFIG_EVT1/
#define CONFIG_CMD_MOVINAND
#define CONFIG_CLK_1000_400_200
#define CFG_PHY_UBOOT_BASE CONFIG_SYS_SDRAM_BASE + 0x3e00000
#define CFG_PHY_KERNEL_BASE CONFIG_SYS_SDRAM_BASE + 0x8000

#define BOOT_MMCSD 0x3
#define BOOT_EMMC43 0x6
#define BOOT_EMMC441 0x7
#define CONFIG_BOARD_LATE_INIT
4、 重新编译u-boot
$ ./build.sh
烧写新的u-boot_fs4412.bin
复位后
# mmc info

移植完成!!!!

你可能感兴趣的:(系统移植)