您的位置:首页 > 运维架构 > Linux

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

2016-11-07 13:53 375 查看

实验三 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

我们产品用的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
$ 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、 确认第一条指令有运行到  (点灯法)

l 在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
 

l 添加三星加密方式

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

$cp  sdfuse_q  u-boot-2013.01  -rf
      
注:sdfuse_q
三星提供的加密处理

$cp
 CodeSign4SecureBoot  u-boot-2013.01  -rf
    
注:CodeSign4SecureBoot
三星提供的安全启动方式  

 

l 修改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


 

l 拷贝编译脚本

$ 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文件

$vim  board/samsung/fs4412/lowlevel_init.S
l 添加临时栈



lowlevel_init:
后添加

ldr  sp,=0x02060000 @use iRom stack in bl2
 

l 添加关闭看门狗代码



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  
 

l 添加串口初始化代码

在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  

复位会看到串口信息

二、网卡移植

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.9.200
#define CONFIG_SERVERIP        192.168.9.120
#define CONFIG_GATEWAYIP      192.168.9.1
#define CONFIG_NETMASK
255.255.255.0
#endif
 

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);
 
/* 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: