Linux系统移植实验之u-boot-2013.01的移植

时间:2021-12-09 16:31:40

实验三 u-boot-2013.01的移植

【实验目的】

了解u-boot 的代码结构及移植方法。

【实验环境】

1、 ubuntu 10.10发行版

2、 u-boot-2013.01

3、 FS_4412平台 EXYNOS 4412

4、 交叉编译器 arm-none-linux-gnueabi-gcc

【实验步骤】

一、建立自己的平台

1、 下载源码

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

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

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

$ tar xvf u-boot-2013.01.tar.bz2

$ cd u-boot-2013.01R

3、 指定交叉编译工具链

$ vim Makefile

    

ifeq ($(HOSTARCH),$(ARCH))

   CROSS_COMPILE ?=

#endif

    下添加

ifeq   (arm,$(ARCH))

   CROSS_COMPILE ?= arm-none-linux-gnueabi-

#endif

 

4、 指定产品CPU

我们产品用的CPUexynos 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

$ mv  board/samsung/fs4412/origen.c  board/samsung/fs4412/fs4412.c

$ vim  board/samsung/fs4412/Makefile   

修改 origen.o  为  fs4412.o

$ cp  include/configs/origen.h  include/configs/fs4412.h

$ vim  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.shu-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文件

$vim  board/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  

复位会看到串口信息

Linux系统移植实验之u-boot-2013.01的移植


二、网卡移植

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_ETHADDR11:22:33:44:55:66

#define CONFIG_IPADDR  192.168.9.200

#define CONFIG_SERVERIP        192.168.9.120

#define CONFIG_GATEWAYIP      192.168.9.1

#define CONFIG_NETMASK255.255.255.0

#endif

 

3、 重新编译u-boot

$ ./build.sh

  烧写新的u-boot_fs4412.bin  

 复位后

# ping  192.168.9.120 

Linux系统移植实验之u-boot-2013.01的移植


四、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);

 

/* 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-$(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) *///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

1、 重新编译u-boot

$ ./build.sh

  烧写新的u-boot_fs4412.bin  

 复位后

# mmcinfo

Linux系统移植实验之u-boot-2013.01的移植