TQ2440移植u-boot2016.11全過程記錄-【1】單板建立並啓動

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
    在這裏插入圖片描述
    成功啓動!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章