我用的的是天嵌的TQ2440開發(fā)板 uboot目錄分析: board:與開發(fā)板相關(guān)的目錄 common:存放通用函數(shù)命令 cpu:特定cpu架構(gòu)目錄如我們的arm920t doc:uboot的使用,開發(fā)文檔 driver:uboot支持的設備驅(qū)動程序 fs:支持的文件系統(tǒng) include:系統(tǒng)的頭文件(lib打頭的是與體系結(jié)構(gòu)相關(guān)的lib文件) post:上電自檢程序 tools:uboot自帶的工具文件頭 具體操作步驟: uboot第一階段啟動過程:硬件的初始化 cpu/arm920t/start.S 第二階段啟動過程:lib-arm/board.c中的intstart_armboot函數(shù) 解壓U-BOOT-1.1.6 #tarxjvf u-boot-1.1.6 進入u-boot進行修改 #cdu-boot-1.1.6 #ls #vi cpu/arm920t/config.mk 把-moft-float注釋掉(這個表示軟浮點,我們采用硬浮點) 保存退出 進入U-BOOT目錄,修改Makefile: 在smdk2410_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
加上 TQ2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t TQ2440 NULL s3c24x0
各項的意思如下:
arm: CPU的架構(gòu)(ARCH)
arm920t: CPU的類型(CPU),其對應于cpu/arm920t子目錄。
TQ2440: 開發(fā)板的型號(BOARD),對應于board/TQ2440目錄。
NULL: 開發(fā)者/或經(jīng)銷商(vender)。
s3c24x0: 片上系統(tǒng)(SOC)。
在第128行: ifeq ($(ARCH),arm) CROSS_COMPILE = arm-linux- 指定交叉編譯器,我使用的是3.4.1,這里也可以寫絕對路徑 修改完Makefile后,在board目錄下,新建自己的開發(fā)板目錄TQ2440,把smdk2410目錄下的所有文件拷到TQ2440,把smdk2410.c改為TQ2440.c。修改該目錄下的Makefile,把smdk2410.o改為TX2410.o。 COBJS := TQ2440.o flash.o 將board目錄下所有文件夾全部刪除,只留TQ2440 在include/configs目錄下創(chuàng)建板子的配置頭文件,把smdk2410.h改名為TQ2440.h,再把所有的文件全部刪除,只留TQ2440.h (注解:這里刪除的方式是——先把保留文件移到上層目錄,在把目錄里的文件全部刪除后,再把保留文件移回 #mv TQ2440 ../ #rm -rf * #ls #mv ../TQ2440 ./ #ls ) 測試能否編譯成功: 執(zhí)行make TQ2440_config 出現(xiàn)make: execvp: …………/mkconfig: 權(quán)限不夠 查看mkconfig的權(quán)限,發(fā)現(xiàn)沒有可執(zhí)行權(quán)限,用chmod 764mkconfig加上權(quán)限 然后再make,成功后可出現(xiàn) Configuring for TQ2440board..... 修改SDRAM配置,在board/TQ2440/lowlevel_init.S中,檢查 #define B6_BWSCON (DW32) 位寬為32 把B1_BWSCON 改為(DW16) B5_BWSCON改為(DW8) 根據(jù)HCLK設置SDRAM 的刷新參數(shù),主要是REFCNT寄存器,開發(fā)板HCLK為100M 將 #defineREFCNT 0x1113 改為 #define REFCNT 0x4f4 增加對S3C2440的支持,2440的時鐘計算公式、NAND操作和2410不太一樣。 對于2440開發(fā)板,將FCLK設為400MHz,分頻比為FCLK:HCLK:PCLK=1:4:8。 修改board/TQ2440/TQ2440.c中的board_init函數(shù) #defineS3C2440_MPLL_400MHZ ((0x7f<<12)|(0x02<<4)|(0x01)) #defineS3C2440_UPLL_48MHZ ((0x38<<12)|(0x02<<4)|(0x02)) #defineS3C2440_CLKDIV 0x05 #defineS3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00)) #defineS3C2410_UPLL_48MHZ ((0x28<<12)|(0x01<<4)|(0x02)) #defineS3C2410_CLKDIV 0x03 int board_init (void) { S3C24X0_CLOCK_POWER * const clk_power =S3C24X0_GetBase_CLOCK_POWER(); S3C24X0_GPIO* const gpio = S3C24X0_GetBase_GPIO(); gpio->GPACON = 0x007FFFFF; gpio->GPBCON = 0x00044555; gpio->GPBUP = 0x000007FF; gpio->GPCCON = 0xAAAAAAAA; gpio->GPCUP = 0x0000FFFF; gpio->GPDCON = 0xAAAAAAAA; gpio->GPDUP = 0x0000FFFF; gpio->GPECON = 0xAAAAAAAA; gpio->GPEUP = 0x0000FFFF; gpio->GPFCON = 0x000055AA; gpio->GPFUP = 0x000000FF; gpio->GPGCON = 0xFF95FFBA; gpio->GPGUP = 0x0000FFFF; gpio->GPHCON = 0x002AFAAA; gpio->GPHUP = 0x000007FF; if((gpio->GSTATUS1 == 0x32410000) ||(gpio->GSTATUS1 == 0x32410002)) { clk_power->CLKDIVN = S3C2410_CLKDIV; __asm__( "mrc p15, 0,r1, c1, c0,0\n" "orr r1, r1,#0xc0000000\n" "mcr p15, 0,r1, c1, c0,0\n" :::"r1" ); clk_power->LOCKTIME = 0xFFFFFF; clk_power->MPLLCON= S3C2410_MPLL_200MHZ; delay (4000); clk_power->UPLLCON = S3C2410_UPLL_48MHZ; delay (8000); gd->bd->bi_arch_number =MACH_TYPE_SMDK2410; } else { clk_power->CLKDIVN = S3C2440_CLKDIV; __asm__( "mrc p15, 0,r1, c1, c0,0\n" "orr r1, r1,#0xc0000000\n" "mcr p15, 0,r1, c1, c0,0\n" :::"r1" ); clk_power->LOCKTIME = 0xFFFFFF; clk_power->MPLLCON = S3C2440_MPLL_400MHZ; delay (4000); clk_power->UPLLCON = S3C2440_UPLL_48MHZ; delay (8000); gd->bd->bi_arch_number =MACH_TYPE_S3C2440; } gd->bd->bi_boot_params =0x30000100; icache_enable(); dcache_enable(); return0; } 在cpu/arm920t/s3c24X0/speed.c中修改: 在程序開頭增加一行DECLARE_GLOBAL_DATA_PTR;,這樣才可以使用gd變量 修改get_PLLCLK函數(shù): static ulong get_PLLCLK(int pllreg) { S3C24X0_CLOCK_POWER * const clk_power =S3C24X0_GetBase_CLOCK_POWER(); ulong r, m,p, s; if (pllreg== MPLL) r =clk_power->MPLLCON; else if(pllreg == UPLL) r =clk_power->UPLLCON; else hang(); m = ((r& 0xFF000) >> 12) +8; p = ((r& 0x003F0) >> 4) +2; s = r& 0x3; if(gd->bd->bi_arch_number ==MACH_TYPE_SMDK2410) return((CONFIG_SYS_CLK_FREQ * m) / (p<< s)); else return((CONFIG_SYS_CLK_FREQ * m * 2) / (p<<s)); } 修改get_HCLK, get_PCLK: #defineS3C2440_CLKDIVN_PDIVN (1<<0) #defineS3C2440_CLKDIVN_HDIVN_MASK (3<<1) #defineS3C2440_CLKDIVN_HDIVN_1 (0<<1) #defineS3C2440_CLKDIVN_HDIVN_2 (1<<1) #defineS3C2440_CLKDIVN_HDIVN_4_8 (2<<1) #defineS3C2440_CLKDIVN_HDIVN_3_6 (3<<1) #defineS3C2440_CLKDIVN_UCLK (1<<3) #defineS3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0) #defineS3C2440_CAMDIVN_CAMCLK_SEL (1<<4) #defineS3C2440_CAMDIVN_HCLK3_HALF (1<<8) #defineS3C2440_CAMDIVN_HCLK4_HALF (1<<9) #defineS3C2440_CAMDIVN_DVSEN (1<<12) ulong get_HCLK(void) { S3C24X0_CLOCK_POWER * const clk_power =S3C24X0_GetBase_CLOCK_POWER(); unsignedlong clkdiv; unsignedlong camdiv; int hdiv =1; if(gd->bd->bi_arch_number ==MACH_TYPE_SMDK2410) return((clk_power->CLKDIVN & 0x2) ?get_FCLK()/2 : get_FCLK()); else { clkdiv = clk_power->CLKDIVN; camdiv = clk_power->CAMDIVN; switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) { case S3C2440_CLKDIVN_HDIVN_1: hdiv = 1; break; case S3C2440_CLKDIVN_HDIVN_2: hdiv = 2; break; case S3C2440_CLKDIVN_HDIVN_4_8: hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 :4; break; case S3C2440_CLKDIVN_HDIVN_3_6: hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 :3; break; } return get_FCLK() / hdiv; } } ulong get_PCLK(void) { S3C24X0_CLOCK_POWER * const clk_power =S3C24X0_GetBase_CLOCK_POWER(); unsignedlong clkdiv; unsignedlong camdiv; int hdiv =1; if(gd->bd->bi_arch_number ==MACH_TYPE_SMDK2410) return((clk_power->CLKDIVN & 0x1) ?get_HCLK()/2 : get_HCLK()); else { clkdiv = clk_power->CLKDIVN; camdiv = clk_power->CAMDIVN; switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) { case S3C2440_CLKDIVN_HDIVN_1: hdiv = 1; break; case S3C2440_CLKDIVN_HDIVN_2: hdiv = 2; break; case S3C2440_CLKDIVN_HDIVN_4_8: hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 :4; break; case S3C2440_CLKDIVN_HDIVN_3_6: hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 :3; break; } return get_FCLK() / hdiv / ((clkdiv &S3C2440_CLKDIVN_PDIVN)? 2:1); } } 重新執(zhí)行makeTQ2440_config make all 生成u-boot.bin,由于還沒有增加NAND Flash的支持,所以可燒入NOR Flash中運行 在make all時會出現(xiàn)錯誤:沒有CAMDIVN 這個要在include/s3c24x0.h中定義,在129行S3C24X0_CLOCK_POWER結(jié)構(gòu)體中增加:S3C24X0_REG32 CAMDIVN; 支持NAND Flash 首先在配置文件include/configs/TQ2440.h的宏CONFIG_COMMANDS中增加CFG_CMD_NAND(大概在82行) 編譯,出現(xiàn)nand.c的錯誤和警告 解決:在include/configs/TQ2440.h的最后面增加3個宏: #defineCFG_NAND_BASE 0 //無實際意義:基地址,在board_nand_init中重新定義 #defineCFG_MAX_NAND_DEVICE 1 //NAND Flash設備數(shù)目為1 #defineNAND_MAX_CHIPS 1 //每個NAND設備由1個NADN芯片組成 修改配置文件后再編譯,只有一個錯誤了“board_nand_init”函數(shù)未定義 board_nand_init需要自己編寫,在cpu/arm920t/s3c24x0下新建nand_flash.c 編寫之前,需要針對S3C2440 NAND Flash定義一些數(shù)據(jù)結(jié)構(gòu)和函數(shù) 在include/s3c24x0.h中增加S3C2440_NAND數(shù)據(jù)結(jié)構(gòu)(168行) typedef struct { S3C24X0_REG32 NFCONF; S3C24X0_REG32 NFCONT; S3C24X0_REG32 NFCMD; S3C24X0_REG32 NFADDR; S3C24X0_REG32 NFDATA; S3C24X0_REG32 NFMECCD0; S3C24X0_REG32 NFMECCD1; S3C24X0_REG32 NFSECCD; S3C24X0_REG32 NFSTAT; S3C24X0_REG32 NFESTAT0; S3C24X0_REG32 NFESTAT1; S3C24X0_REG32 NFMECC0; S3C24X0_REG32 NFMECC1; S3C24X0_REG32 NFSECC; S3C24X0_REG32 NFSBLK; S3C24X0_REG32 NFEBLK; } S3C2440_NAND; 在include/s3c2410.h中仿照S3C2410_GetBase_NAND函數(shù)(96行) 定義2440的函數(shù): static inline S3C2440_NAND * constS3C2440_GetBase_NAND(void) { return(S3C2440_NAND * const)S3C2410_NAND_BASE; } 在cpu/arm920t/s3c24x0/nand_flash.c中添加代碼,是從Linux-2.6.13中/drivers/mtd/nand/s3c2410.c中移植過來的,代碼略。 修改cpu/arm920t/s3c24x0/Makefile: COBJS = 加上一項nand_flash.o 編譯后生成uboot鏡像,但這里注意,現(xiàn)在還不支持NAND FLASH啟動,只能燒到NORFLASH中。要支持NANDFLASH啟動,要修改cpu/arm920t/start.S,還要編寫nand啟動函數(shù),這里先不考慮,復制現(xiàn)成的代碼過來,以后再說。 支持網(wǎng)卡芯片DM9000 在driver下,有網(wǎng)卡驅(qū)動DM9000x.c 和 DM9000x.h DM9000接在BANK4,位寬16 在include/configs/TQ2440.h中設置網(wǎng)卡基地址: 在56行處,將CS8900的定義改成: #defineCONFIG_DRIVER_DM9000 1 #defineCONFIG_DM9000_BASE 0x20000300 #defineDM9000_IO CONFIG_DM9000_BASE #defineDM9000_DATA (CONFIG_DM9000_BASE + 4) #define CONFIG_DM9000_USE_16BIT 在drivers目錄下,只留nand nand_legacy dm9000x.cdm9000x.h Makefile 其他文件全部刪除,修改Makefile: COBJS = dm9000x.o 修改頂層目錄的Makefile:將209行的內(nèi)容 LIBS +=drivers/sk98lin/libsk98lin.a 刪除 可以將頂層目錄下沒用的lib_x文件夾刪除,只留lib_arm lib_generic 編譯可生成支持網(wǎng)卡的uboot 設置Linux啟動參數(shù) 在77行處,加兩個宏定義: #defineCONFIG_SETUP_MEMORY_TAGS 1 #defineCONFIG_CMDLINE_TAG 1 在#include<cmd_confdefs.h>后面的一些啟動參數(shù)修改如下: #define CONFIG_BOOTDELAY 3 #defineCONFIG_BOOTARGS "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" #defineCONFIG_ETHADDR 08:00:3e:26:0a:5b #defineCONFIG_NETMASK 255.255.255.0 #defineCONFIG_IPADDR 192.168.220.6 #defineCONFIG_SERVERIP 192.168.220.19 #define CONFIG_BOOTCOMMAND "nboot 0x32000000 0 0x50000; bootm 0x32000000" 這個是uboot的命令提示符,可修改 #define CFG_PROMPT "TQ2440>" 燒些程序總結(jié):由于我用的是筆記本,沒有并口,所以我選擇了jlink進行燒寫,運用的jlink驅(qū)動是4.08版本的,我的天嵌開發(fā)板的NORflash 是天嵌說明書中的p119的第三個版本的,型號為 EON EN29LV160AB2048KB 35 7F0049 7F2249 16,但是jlink自帶的flash沒有該版本的,所以我需要先把天嵌提供的flash集合去替換掉jlink安裝目錄下的那個flash集合,這樣才能使用。
特別要注意的是!!燒寫完u-boot后要把jlink和開發(fā)板斷開后重啟開發(fā)板,不然的話開發(fā)板將無法正常啟動通過串口打印信息的!
|