TQ2440移植u-boot2016.11-單板建立並啓動
移植說明
u-boot2016.11是S3C2440最後一版的uboot支持,所以選擇了此版本進行移植,交叉編譯器使用的是天嵌官方的交叉編譯器,版本爲4.4.3,使用的ubuntu1404系統。
(一)新建TQ2440單板
編輯u-boot頂層Makefile文件
gedit Makefile
定位到:
# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))
CROSS_COMPILE ?=
endif
在下方插入:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
這兩句的作用爲指定編譯熟悉和交叉編譯工具鏈。
將以下兩句屏蔽掉,如果不屏蔽掉,後續會修改配置頭文件中的默認宏定義而導致配置檢查無法通過。
新建tq2440單板:
- 創建tq2440單板:
cp -a board/samsung/smdk2410 board/samsung/tq2440
mv board/samsung/tq2440/smdk2410.c board/samsung/tq2440/tq2440.c
- 拷貝頭文件:
cp include/configs/smdk2410.h include/configs/tq2440.h
- 拷貝配置文件:
cp configs/smdk2410_defconfig configs/tq2440_defconfig
修改board/samsung/tq2440/目錄下的文件:
- 修改Kconfig文件:
gedit board/samsung/tq2440/Kconfig
- 修改板卡支持維護信息文件MAINTAINERS:
gedit board/samsung/tq2440/MAINTAINERS
- 修改Makefile:
gedit board/samsung/tq2440/Makefile
- 修改configs/tq2440_defconfig文件:
gedit configs/tq2440_defconfig
- 修改arch/arm/Kconfig文件:
-
定位到:
config TARGET_SMDK2410 bool "Support smdk2410" select CPU_ARM920T
下方添加:
config TARGET_TQ2440 bool "Support tq2440" select CPU_ARM920T
-
定位到:
source "board/samsung/smdk2410/Kconfig
在下一行添加:
source "board/samsung/tq2440/Kconfig
-
修改內核引導機器碼信息:
arch/arm/include/asm/mach-types.h
TQ2440官方linux系統內核的機器碼爲168,所以我們需要修改u-boot的機器識別碼,否則在啓動引導內核時無法識別。
定位到:
#define MACH_TYPE_SMDK2410 193
在下方插入一行:
#define MACH_TYPE_TQ2440 168
定位到:
#ifdef CONFIG_ARCH_SMDK2410
# ifdef machine_arch_type
# undef machine_arch_type
# define machine_arch_type __machine_arch_type
# else
# define machine_arch_type MACH_TYPE_SMDK2410
# endif
# define machine_is_smdk2410() (machine_arch_type == MACH_TYPE_SMDK2410)
#else
# define machine_is_smdk2410() (0)
#endif
在下方添加:
#ifdef CONFIG_ARCH_TQ2440
# ifdef machine_arch_type
# undef machine_arch_type
# define machine_arch_type __machine_arch_type
# else
# define machine_arch_type MACH_TYPE_TQ2440
# endif
# define machine_is_tq2440() (machine_arch_type == MACH_TYPE_TQ2440)
#else
# define machine_is_tq2440() (0)
#endif
到此單板建立完成,編譯一下看看是否成功:
make distclean
make tq2440_defconfig
make
OK,沒問題,到此第一階段的單板建立完成,後續開始移植修改代碼。
(二)初始化代碼修改
修改彙編啓動文件arch/arm/cpu/arm920t/start.S
,將其中的代碼替換爲以下:
/*
* armboot - Startup Code for ARM920 CPU-core
*
* Copyright (c) 2001 Marius Gröger <[email protected]>
* Copyright (c) 2002 Alex Züpke <[email protected]>
* Copyright (c) 2002 Gary Jennejohn <[email protected]>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm-offsets.h>
#include <common.h>
#include <config.h>
/*
*************************************************************************
*
* Startup Code (called from the ARM reset exception vector)
*
* do important init only if we don't start from memory!
* relocate armboot to ram
* setup stack
* jump to second stage
*
*************************************************************************
*/
.globl reset
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0
#define pWTCON 0x53000000
#define INTMSK 0x4A000008 /* Interrupt-Controller base addresses */
#define INTSUBMSK 0x4A00001C
#define CLKDIVN 0x4C000014 /* clock divisor register */
#define MPLLCON 0x4C000004
#define UPLLCON 0x4C000008
/* turn off the watchdog */
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
/* mask all IRQs by setting all bits in the INTMR - default */
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
ldr r1, =0x7ff
ldr r0, =INTSUBMSK
str r1, [r0]
/* FCLK:HCLK:PCLK = 1:4:8 */
/* default FCLK is 405 MHz ! */
ldr r0, =CLKDIVN
mov r1, #5
str r1, [r0]
/* set asynchronous bus mod */
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
/* When you set MPLL&UPLL values, you have
* to set the UPLL value first and then the MPLL value.
* (Needs intervals approximately 7 NOP)
*/
/* set upllcon is 48MHz */
ldr r0, =UPLLCON
ldr r1, =((0x38 << 12) | (0x2 << 4) | (0x2 << 0))
str r1, [r0]
/* delay 7 nop */
nop
nop
nop
nop
nop
nop
nop
/* set mpllcon is 405MHz */
ldr r0, =MPLLCON
ldr r1, =((0x7F << 12) | (0x2 << 4) | (0x1 << 0))
str r1, [r0]
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
bl _main
/*------------------------------------------------------------------------------*/
.globl c_runtime_cpu_setup
c_runtime_cpu_setup:
mov pc, lr
/*
*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 1 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
mov ip, lr
bl lowlevel_init
mov lr, ip
#endif
mov pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
注意:這裏我在這個彙編文件中設置了UPLLCON寄存器,目的是因爲後續移植linux內核後,當使用USB鼠標或者U盤時,由於未先
設置UPLLCON寄存器導致在linux內核啓動配置USB時鐘時會設置失敗,錯誤信息大概爲usb 1-1: device descriptor read/64, error -110
的字樣,這個錯誤是USB鼠標或U盤插入後能顯示有設備插入但是無法枚舉,也就是USB時鐘沒有配置爲48M導致的,所以在此將USB的時鐘設置爲了48M,UPLLCON和MPLLCON寄存器是有設置順序的,要先設置UPLLCON然後延時7個時鐘在設置MPLLCON,這在S3C2440芯片數據手冊中有說明:
修改SDRAM初始化代碼文件board/samsung/tq2440/lowlevel_init.S
:
定位到:
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32
.word 0x30
.word 0x30
替換爲:
SMRDATA:
.long 0x22011110 @ BWSCON
.long 0x00000700 @ BANKCON0
.long 0x00000700 @ BANKCON1
.long 0x00000700 @ BANKCON2
.long 0x00000700 @ BANKCON3
.long 0x00000700 @ BANKCON4
.long 0x00000700 @ BANKCON5
.long 0x00018005 @ BANKCON6
.long 0x00018005 @ BANKCON7
.long 0x008C07A3 @ REFRESH
.long 0x000000B1 @ BANKSIZE,1的二進制爲001,表示內存爲64M,具體請看BANKSIZE寄存器
.long 0x00000030 @ MRSRB6
.long 0x00000030 @ MRSRB7
修改板卡初始化代碼文件board/samsung/tq2440/tq2440.c
:
定位到:
#define FCLK_SPEED 1
#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
#endif
#define USB_CLOCK 1
#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
#endif
替換爲:
#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) /* Fout = 405MHz */
#define M_MDIV 0x7f
#define M_PDIV 0x2
#define M_SDIV 0x1
#endif
#define USB_CLOCK 2
#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
修改IO口,點亮LED燈:
TQ2440板載4個LED燈接到了GPB8-GPB5,蜂鳴器接到了GPB0,GPB共有11個引腳,由高到低依次爲GPB10-GPB0,由GPBCON、GPBUP和GPBDAT三個寄存器控制。
- GPBCON(0x56000010):每兩位控制一個引腳,爲00時表示輸入引腳,爲01時表示輸出引腳,
爲10時表示複用功能;- GPBDAT(0x56000014):每一位表示一個引腳的輸入或輸出狀態;
- GPBUP(0x56000018):每一位控制一個引腳,爲0時表示使用上拉電阻,爲1表示禁用上拉電
阻。
找到board_early_init_f
函數,定位到writel(0x00044555, &gpio->gpbcon)
,代碼將0x00044555
寫入到了GPBCON
寄存器,二進制爲1000100010101010101
,也就是說將GPB10、GPB8、GPB6配置爲了輸入,其他配置爲了輸出;我們需要將GPB8-GPB5和GPB0配置爲輸出模式,其他引腳配置爲複用模式,用計算器計算一下爲:
所以將0x00044555
改爲0x002956A9
即可。
原本的代碼將0x000007FF
寫入到了GPBUP
寄存器,0x7FF就是控制了11位,也就是將GPB的11個IO全部禁止使用上拉電阻,此處無需更改。
找到board_init
函數,修改爲:
注意gd->bd->bi_boot_params = 0x30000100
這行代碼,這裏指定了在SDRAM中運行時的環境變量保存位置,暫時不修改,後面移植過程中在研究。
修改板卡初始化代碼頭文件:
gedit include/configs/tq2440.h
- 將
S3C2410
替換爲S3C2440
- 將
SMDK2410
替換爲TQ2440
創建NAND Flash 驅動
-
cp drivers/mtd/nand/s3c2410_nand.c drivers/mtd/nand/s3c2440_nand.c
-
gedit drivers/mtd/nand/s3c2440_nand.c
,將文件中的S3C2410
替換爲S3C2440
-
gedit drivers/mtd/nand/Makefile
定位到:obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
在下一行加入:obj-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
設置從SDRAM啓動代碼
gedit arch/arm/cpu/arm920t/start.S
- 在開頭定義一個宏
CONFIG_SKIP_LOWLEVEL_INIT
,目的是在arch/arm/cpu/arm920t/start.S
中跳過SDRAM的初始化,否則我們將程序通過tftp下載到內存處時,就會將SDRAM重新初始化破壞掉代碼。 - 修改宏
CONFIG_SYS_TEXT_BASE
的值爲0x30008000
,一會我們使用tftp將u-boot.bin下載到這個地址。
編譯一下無誤後使用天嵌自帶的u-boot將剛編譯出來u-boot.bin下載到內存0x30008000地址處,然後運行:
tftp 0x30008000 uboot.bin
go 0x30008000
成功啓動!