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

时间:2022-05-21 16:34:52

Uboot 版本:u-boot-2013.01

开发板:FS_4412 平台(Exynos4412,可以根据自己的板子修改,只要是4412的过程都是一样的)


一、建立自己的平台

1、下载源码

我们可以在下面这个网站上下载最新的和以前任一版本的uboot

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

这里我们使用的是u-boot-2013.01


2、解压uboot 源码并进入目录

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


3、指定交叉编译工具链

a -- 打开根目录下的Makefile

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

b -- 添加交叉编译工具链信息

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


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

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


b -- 修改board/samsung/fs4412/Makefile信息

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

修改 origen.o 为 fs4412.o

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


c -- 修改include/configs/fs4412.h配置文件

这里同样是先复制 inlcude/configs/origen.h,生成 inlcude/configs/fs4412.h

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

打开fs4412.h,修改以下文件:

将原来的#define CONFIG_SYS_PROMPT "ORIGEN #" 改成

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

将原来的#define CONFIG_IDENT_STRING for ORIGEN 改成

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


d -- 配置boards.cfg

打开uboot根目录下的boards.cfg,在origen后新增

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


6、编译u-boot

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

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

编译完成后生成的u-boot.bin 就是可执行的镜像文件。

烧写uboot 命令:

tftp 41000000 u-boot.bin

movi write uboot 41000000

但是该文件还不能在我们板子上运行,我们需要对u-boot 源代码进行相应的修改。



二、实现能看到串口终端信息

1、确认第一条指令有运行到(点灯法)

a -- 在arch/arm/cpu/armv7/start.S 134 行后添加点灯程序

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


b --  添加三星加密方式

exynos 需要三星提供的初始引导加密后,我们的u-boot,才能被引导运行

将sdfuse_q 目录拷贝到u-boot-2013.01 源码目录下

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

将CodeSign4SecureBoot 目录拷贝到u-boot-2013.01 源码目录下

注:CodeSign4SecureBoot 三星提供的安全启动方式


c -- 修改Makefile

$vim Makefile

修改实现sdfuse_q 的编译

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

下添加

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

注意是tab 键缩进的,否则makefile 编译报错

注意如果执行了make distclean 需重新拷贝CodeSign4SecureBoot


d -- 拷贝编译脚本

将 build.sh 拷贝到uboot 根目录下,并加上执行权限,并执行该脚本 注:build.sh 脚本方式完成自动添加加密方式,是自己编写的

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

编译生成所需文件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:

后添加

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


b --  添加关闭看门狗代码

beq wakeup_reset

后添加

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


c -- 添加串口初始化代码

在uart_asm_init: 的

str r1, [r0, #EXYNOS4_GPIO_A1_CON_OFFSET]

后添加

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

注释掉trustzone 初始化

注释掉

bl uart_asm_init

下的

bl tzpc_init

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

重新编译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

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


在文件末尾

#endif /* __CONFIG_H */

前面添加

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


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

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


修改板级文件

$vim board/samsung/fs4412/fs4412.c

#include <asm/arch/mmc.h>

后面添加

#include <asm/arch/clk.h>
#include "origen_setup.h"

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


#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

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


添加驱动

$ 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

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


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