歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> u-boot-2010.06在unsp2440上的移植

u-boot-2010.06在unsp2440上的移植

日期:2017/3/1 11:15:41   编辑:Linux編程

一、 步驟說明:

  • 進行u-boot的移植,我們分成以下幾步完成:
  • NorFlash啟動
  • 可以讀寫NAND FLASH
  • NAND啟動
  • 支持網絡、USB下載
  • 支持讀寫SD上內核及根文件系統
  • 支持USB從下載

U-Boot源代碼下載地址 http://www.linuxidc.com/Linux/2011-07/38897.htm

二、 啟動流程簡介

  • u-boot的stage1代碼通常放在cpu/xxxx/start.S文件中,他用匯編語言寫成;
  • u-boot的stage2代碼通常放在lib_xxxx/board.c文件中,他用C語言寫成。
  • 各個部分的流程圖如下:

步驟一:建立u-boot下的 unsp2440開發板目錄結構

在u-boot的目錄樹中默認沒有S3C2440芯片的支持,但是其同S3C2410相差不多,我們根據S3C2410的一些配置修改得到對2440芯片的支持,u-boot默認僅支持Nor啟動,我們第一步完成U-boot在NORFLASH上的啟動。

目前u-boot對很多CPU直接支持,可以查看board目錄的一些子目錄,如:board/samsung/目錄下就是對三星一些ARM處理器的支持,有smdk2400、smdk2410和smdk6400,但沒有2440,所以我們就在這裡建立自己的開發板項目。

(1) 因2440和2410的資源差不多,主頻和外設有點差別,所以就在board/samsung/下建立自己開發板的項目,取名叫unsp2440

(2) #tar jxvf u-boot-2010.06.tar.bz2 //解壓源碼

(3) #cd u-boot-2010.06/board/samsung/ //進入目錄

(4) #cp smdk2410/ unsp2440/ -R //將2410目錄復制一份並重命名為unsp2440

#cd unsp2440 //進入unsp2440目錄

#mv smdk2410.c unsp2440.c //將unsp2440下的smdk2410.c改名為unsp2440.c

#vi board/samsung/unsp2440/Makefile //修改unsp2440下Makefile的編譯項,如下:

COBJS := unsp2440.o flash.o //因在unsp2440下我們將smdk2410.c改名為unsp2440.c

(5) #cp include/configs/smdk2410.h include/configs/unsp2440.h //建立2440頭文件

(6) 修改u-boot跟目錄下的Makefile文件

查找到smdk2410_config的地方,在他下面按照smdk2410_config的格式建立unsp2440_config的編譯選項,另外還要指定交叉編譯器

smdk2410_config :unconfig //2410編譯選項格式

@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0

unsp2440_config :unconfig //2440編譯選項格式

@$(MKCONFIG) $(@:_config=) arm arm920t unsp2440 samsung s3c24x0

CROSS_COMPILE ?= arm-linux- //指定交叉編譯器為arm-linux-gcc

*說明:

  • arm: CPU的架構(ARCH)
  • arm920t: CPU的類型
  • unsp2440 : 對應在board目錄下建立新的開發板項目的目錄
  • samsung: 新開發板項目目錄的上級目錄,如直接在board下建立新的開發板項目的目錄,則這裡就為NULL
  • s3c24x0: CPU型號

*注意:編譯選項格式的第二行要用Tab鍵開始,否則編譯會出錯

(7) 測試編譯新建的unsp2440開發板項目

  • #make unsp2440_config //如果出現Configuring for unsp2440 board...則表示設置正確
  • #make //編譯後在根目錄下會出現u-boot.bin文件,則u-boot移植的第一步就算完成了

到此為止,u-boot對自己的unsp2440開發板還沒有任何用處,以上的移植只是搭建了一個unsp2440開發板u-boot的框架,要使其功能實現,還要根據unsp2440開發板的具體資源情況來對u-boot源碼進行修改。

步驟二:u-boot支持s3C2440 NOR啟動

根據u-boot啟動流程圖的步驟來分析或者修改添加u-boot源碼,使之適合unsp2440開發板(注:修改或添加的地方都用紅色表示)。

(1) unsp2440開發板u-boot的stage1入口點分析

前面我們知道了程序的入口點是arch/arm/arm920t/start.S,那麼我們就打開unsp2440開發板u-boot第一個要運行的程序arch/arm/arm920t/start.S(即u-boot的stage1部分),查找到_start的位置如下:

.globl _start

_start: b start_code //將程序的執行跳轉到start_code處

從這個匯編代碼可以看到程序又跳轉到start_code處開始執行,那麼再查找到start_code處的代碼如下:

/*

* the actual start code

*/

start_code:

/*

* set the cpu to SVC32 mode

*/

mrs r0, cpsr

bic r0, r0, #0x1f

orr r0, r0, #0xd3

msr cpsr, r0

/******dec by dengwei************/

/*bl coloured_LED_init*/

/*bl red_LED_on*/

//此處兩行是對AT91RM9200DK開發板上的LED進行初始化的,作為測試使用,我們這裡用不到,所以注釋掉

(2) unsp2440開發板u-boot的stage1階段的硬件設備初始化。

在include/configs/unsp2440.h頭文件中添加CONFIG_S3C2440宏

#vi include/configs/unsp2440.h

#define CONFIG_ARM920T 1 /* This is an ARM920T Core */

#define CONFIG_S3C24X0 1 /* in a SAMSUNG S3C24x0-type SoC */

#define CONFIG_S3C2410 1 /* specifically a SAMSUNG S3C2410 SoC */

#define CONFIG_SMDK2410 1 /* on a SAMSUNG SMDK2410 Board */

#define CONFIG_S3C2440 1 /* specifically a SAMSUNG S3C2440 SoC */

(3) 在u-boot中添加對S3C2440一些寄存器的支持、添加中斷禁止部分和時鐘設置部分。

1)中斷寄存器

由於2410和2440的寄存器及地址大部分是一致的,所以這裡就直接在2410的基礎上再加上對2440的支持即可,代碼如下:

#vi cpu/arm920t/start.S

# if defined(CONFIG_S3C2410)

ldr r1, =0x3ff

ldr r0, =INTSUBMSK

str r1, [r0]

# endif

/************add by dengwei**********/

//關閉子中斷屏蔽寄存器

# if defined(CONFIG_S3C2440)

ldr r1, =0x7ff

ldr r0, =INTSUBMSK

str r1, [r0]

# endif

2)時鐘管理:

/*******add by dengwei*************************************/

# if defined(CONFIG_S3C2440) //添加s3c2440的時鐘部分

#define MPLLCON 0x4C000004 //系統主頻配置寄存器基地址

#define UPLLCON 0x4C000008 //USB時鐘頻率配置寄存器基地址

ldr r0, =CLKDIVN //設置分頻系數FCLK:HCLKCLK = 1:4:8

mov r1, #5

str r1, [r0]

ldr r0, =MPLLCON //設置系統主頻為405MHz

ldr r1, =0x7F021

str r1, [r0]

ldr r0, =UPLLCON //設置USB時鐘頻率為48MHz

ldr r1, =0x38022

str r1, [r0]

#else

/* FCLK:HCLK:PCLK = 1:2:4 */

/* default FCLK is 120 MHz ! */

ldr r0, =CLKDIVN

mov r1, #3

str r1, [r0]

#endif

以上方法是在匯編中直接改變系統的時鐘頻率,為了實現u-boot���改方便同時實現同時支持2410,2440啟動,我們也可以把時鐘的初始化放在一個C文件中,做更加復雜的操作

/時鐘初始化

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

bl clock_init

#endif

S3C2440在start.S中修改以上信息,只是修改了第一階段的時鐘,u-boot在第二階段會重新初始化系統時鐘,還要分別在board/samsung/unsp2440/unsp2440.c和arch/arm/cpu/arm920t/s3c24x0/speed.c中修改或添加部分代碼,如下:

因為2410跟2440的的時鐘控制稍有不同,因此需要根據具體硬件選擇不同的參數

/* support both of S3C2410 and S3C2440, by dengwei */

extern const char *mtdparts_default;

if ((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002))

{

/* arch number of SMDK2410-Board */

gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

//2410 MTD分區表信息

//mtdparts_default = MTDPARTS_DEFAULT2410;

//2410啟動引導參數

//setenv("bootargs", CONFIG_BOOTARGS2410);

}

else

{

/* arch number of UNSP2440-Board */

gd->bd->bi_arch_number = MACH_TYPE_S3C2440;

/*2440MTD分區表信息*/

//mtdparts_default = MTDPARTS_DEFAULT2440;

//*2440啟動引導參數

//setenv("bootargs", CONFIG_BOOTARGS2440);

}

#vi board/samsung/unsp2440/unsp2440.c

//設置主頻和USB時鐘頻率參數與start.S中的一致

#define FCLK_SPEED 2

#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */

#define M_MDIV 0xC3

#define M_PDIV 0x4

#define M_SDIV 0x1

#elif FCLK_SPEED==1 /* Fout = 202.8MHz */

#define M_MDIV 0xA1

#define M_PDIV 0x3

#define M_SDIV 0x1

#elif FCLK_SPEED==2 //即默認HCLK等於405M

#define M_MDIV 0x7f

#define M_PDIV 0x2

#define M_SDIV 0x1

#endif

#define USB_CLOCK 2 //USB默認為48M

#if USB_CLOCK==0

#define U_M_MDIV 0xA1

#define U_M_PDIV 0x3

#define U_M_SDIV 0x1

#elif USB_CLOCK==1

#define U_M_MDIV 0x48

#define U_M_PDIV 0x3

#define U_M_SDIV 0x2

#elif USB_CLOCK==2

#define U_M_MDIV 0x38

#define U_M_PDIV 0x2

#define U_M_SDIV 0x2

#endif

#vi arch/arm/cpu/arm920t/s3c24x0/speed.c

//根據設置的分頻系數FCLK:HCLK:CLK = 1:4:8修改獲取時鐘頻率的函數

static ulong get_PLLCLK(int pllreg)

{

struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();

ulong r, m, p, s;

if (pllreg == MPLL)

r = readl(&clk_power->MPLLCON);

else if (pllreg == UPLL)

r = readl(&clk_power->UPLLCON);

else

hang();

m = ((r & 0xFF000) >> 12) + 8;

p = ((r & 0x003F0) >> 4) + 2;

s = r & 0x3;

/******add by dengwei**********/

#if defined(CONFIG_S3C2440)

if(pllreg == MPLL)

{

//參考S3C2440芯片手冊上的公式:PLL=(2 * m * Fin)/(p * 2s)

return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));

}

#endif

return (CONFIG_SYS_CLK_FREQ * m) / (p << s);

}

/* return HCLK frequency */

ulong get_HCLK(void)

{

struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();

/*******add by dengwei******/

#if defined(CONFIG_S3C2440)

return(get_FCLK()/4);

#endif

return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK();

}

好了!修改完畢,我們重新編譯並將u-boot.bin使用H-JTAG下載到開發板的NOR FLASH中,觀察是否會打印啟動信息。

Copyright © Linux教程網 All Rights Reserved