1. 程式人生 > >Exynos4412 Uboot 移植(五)—— Uboot 移植過程

Exynos4412 Uboot 移植(五)—— Uboot 移植過程

Uboot 版本:u-boot-2013.01

開發板:FS_4412 平臺(Exynos4412,可以根據自己的板子修改,只要是4412的過程都是一樣的)

一、建立自己的平臺

1、下載原始碼

我們可以在下面這個網站上下載最新的和以前任一版本的uboot

ftp://ftp.denx.de/pub/u-boot/

這裡我們使用的是u-boot-2013.01

2、解壓uboot 原始碼並進入目錄


3、指定交叉編譯工具鏈

a -- 開啟根目錄下的Makefile


b -- 新增交叉編譯工具鏈資訊


4、指定產品CPU

我們產品用的CPU 是exynos 4412

檢視u-boot 原始碼該CPU 是否已支援

U-boot 已支援,見arch/arm/cpu/armv7/exynos/

5、指定產品BOARD

找一個最類似的board 配置修改, 這裡我們參考的是board/samsung/origen/

a -- 修改board/samsung/ 板級相關資料夾,複製 board/samsung/origen/,重新命名為fs4412

 

b -- 修改board/samsung/fs4412/Makefile資訊


修改 origen.o 為 fs4412.o


c -- 修改include/configs/fs4412.h配置檔案

這裡同樣是先複製 inlcude/configs/origen.h,生成 inlcude/configs/fs4412.h


開啟fs4412.h,修改以下檔案:

將原來的#define CONFIG_SYS_PROMPT "ORIGEN #" 改成


將原來的#define CONFIG_IDENT_STRING for ORIGEN 改成


d -- 配置boards.cfg

開啟uboot根目錄下的boards.cfg,在origen後新增


6、編譯u-boot

$ make distclean
$ make fs4412_config (可以在inlcude/config.mk及include/config.h下看到配置好的資訊)
$ make


編譯完成後生成的u-boot.bin 就是可執行的映象檔案。

燒寫uboot 命令:

tftp 41000000 u-boot.bin

movi write uboot 41000000

但是該檔案還不能在我們板子上執行,我們需要對u-boot 原始碼進行相應的修改。

二、實現能看到串列埠終端資訊

1、確認第一條指令有執行到(點燈法)

a -- 在arch/arm/cpu/armv7/start.S 134 行後新增點燈程式


b --  新增三星加密方式

exynos 需要三星提供的初始引導加密後,我們的u-boot,才能被引導執行

將sdfuse_q 目錄拷貝到u-boot-2013.01 原始碼目錄下

注:sdfuse_q 三星提供的加密處理

將CodeSign4SecureBoot 目錄拷貝到u-boot-2013.01 原始碼目錄下

注:CodeSign4SecureBoot 三星提供的安全啟動方式

c -- 修改Makefile

$vim Makefile

修改實現sdfuse_q 的編譯


下新增


注意是tab 鍵縮排的,否則makefile 編譯報錯

注意如果執行了make distclean 需重新拷貝CodeSign4SecureBoot

d -- 拷貝編譯指令碼

將 build.sh 拷貝到uboot 根目錄下,並加上執行許可權,並執行該指令碼 注:build.sh 指令碼方式完成自動新增加密方式,是自己編寫的


編譯生成所需檔案u-boot_fs4412.bin

燒寫新的u-boot_fs4412.bin

復位,發現燈有點亮,說明我們的u-boot 有執行到

附:build.sh指令碼檔案

#!/bin/sh

sec_path="CodeSign4SecureBoot/"
CPU_JOB_NUM=$(grep processor /proc/cpuinfo | awk '{field=$NF};END{print field+1}')
ROOT_DIR=$(pwd)
CUR_DIR=${ROOT_DIR##*/}

case "$1" in
	clean)
		echo make clean
		make mrproper
		;;
	*)
			
		if [ ! -d $sec_path ]
		then
			echo "**********************************************"
			echo "[ERR]please get the CodeSign4SecureBoot first"
			echo "**********************************************"
			return
		fi
		
		make fs4412_config
		
		make -j$CPU_JOB_NUM
		
		if [ ! -f checksum_bl2_14k.bin ]
		then
			echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
			echo "There are some error(s) while building uboot, please use command make to check."
			echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
			exit 0
		fi
		
		cp -rf checksum_bl2_14k.bin $sec_path
		cp -rf u-boot.bin $sec_path
		rm checksum_bl2_14k.bin
		
		cd $sec_path
		cat E4412_N.bl1.SCP2G.bin bl2.bin all00_padding.bin u-boot.bin tzsw_SMDK4412_SCP_2GB.bin > u-boot-fs4412.bin
		mv u-boot-fs4412.bin $ROOT_DIR
		
		rm checksum_bl2_14k.bin
		rm u-boot.bin

		echo 
		echo 
		;;
		
esac

2、實現串列埠輸出

修改lowlevel_init.S 檔案

$vim board/samsung/fs4412/lowlevel_init.S

a -- 新增臨時棧


lowlevel_init:

後新增


b --  新增關閉看門狗程式碼

beq wakeup_reset

後新增


c -- 新增串列埠初始化程式碼

在uart_asm_init: 的

str r1, [r0, #EXYNOS4_GPIO_A1_CON_OFFSET]

後新增


註釋掉trustzone 初始化

註釋掉

bl uart_asm_init

下的

bl tzpc_init


重新編譯u-boot

$ ./build.sh

燒寫新的u-boot_fs4412.bin

復位會看到串列埠資訊

三、網絡卡移植

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)   // 0clk         address set-up
#define DM9000_Tcos     (0x1)   // 4clk         chip selection set-up
#define DM9000_Tacc     (0x5)   // 14clk        access cycle
#define DM9000_Tcoh     (0x1)   // 1clk         chip selection hold
#define DM9000_Tah      (0xC)   // 4clk         address holding time
#define DM9000_Tacp     (0x9)   // 6clk         page mode access cycle
#define DM9000_PMC      (0x1)   // normal(1data)page mode configuration


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 */

前面新增


3、重新編譯u-boot

$ ./build.sh

燒寫新的u-boot_fs4412.bin

復位後

# ping 192.168.9.120

四、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 <asm/arch/mmc.h>

後面新增

#include <asm/arch/clk.h>
#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 <movi.h>
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);

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

	return 0;
}


2、新增相關命令

$ cp cmd_movi.c common/
$ cp cmd_mmc.c common/
$ cp cmd_mmc_fdisk.c common/

修改Makefile

$ vim common/Makefile

COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o

後新增

COBJS-$(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

$vim drivers/mmc/Makefile

新增

COBJS-$(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)  
 * #define emmcdbg(fmt,args...) 
 */
 #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

復位後

# mmcinfo