u-boot-2013.04-rc1 在ok6410的移植
1.解壓
tar -jxvf u-boot-2013.04-rc1.tar.bz2
2.刪除不必要的文件
/arch/下除arm
/arch/arm/cpu/下除arm1176和uboot.lds
/arch/arm/include/asm/arch-* 除 arch-64xx
/board/下除samsung
/board/samsung/下smdk*除smdk6400
/nand_spl/board/下除samsung
/include/configs/下除smdk6400.h
3.準備ok6410的單板信息
mv board/samsung/smdk6400 board/samsung/ok6410
mv board/samsung/ok6410/smdk6400_nand_spl.c board/samsung/ok6410/ok6410_nand_spl.c
mv board/samsung/ok6410/smdk6400.c board/samsung/ok6410/ok6410.c
board/samsung/ok6410/ok6410.c 中 smdk6400 改爲 ok6410 s3c6400 -> s3c6410
board/samsung/ok6410/makefile 中 smdk6400 改爲 ok6410
4.建立nand_spl
mv nand_spl/board/samsung/smdk6400 nand_spl/board/samsung/ok6410
nand_spl/board/samsung/ok6400/makefile 中 smdk6400 改爲 ok6410
5.建立頭文件
mv arch/arm/include/asm/arch-s3c64xx/s3c6400.h arch/arm/include/asm/arch-s3c64xx/s3c6410.h
arch/arm/include/asm/arch-s3c64xx/s3c6410.h 中
#define DMC1_MEM_CFG 0X0001001A /* burst 4, 14-bit row, 10-bit col */
#define DMC1_MEM_CFG2 0XB45
#define DMC1_CHIP0_CFG 0X150F0 /* 0X5000_0000~0X5FFF_FFFF(256MB) */
mv include/configs/smdk6400.h include/configs/ok6410.h
include/configs/ok6410.h 中 S3C6400 改爲 S3C6410
#define CONFIG_SYS_PROMPT "ok6410#"
#define CONFIG_IDENT_STRING "for ok6410"
#define PHYS_SDRAM_1_SIZE 0x10000000 /* 256MB */
6.處理器makefile
arch/arm/cpu/arm1176/s3c64xx/makefile 中 S3C6400 改爲 S3C6410
7.其他
ok6410.c 和 lowlevel_init.S 中 smdk6400 -> ok6410 s3c6400 -> s3c6410
arch/arm/cpu/arm1176/s3c64xx中
cpu_init.S reset.S speed.c timer.c
drivers/usb/host/s3c64xx-hcd.c
drivers/mtd/nand/s3c64xx.c
drivers/serial/s3c64xx.c
include/common.h CONFIG_S3C6400 -> CONFIG_S3C6410
drivers/usb/host/ohci-hcd.c CONFIG_S3C6400 -> CONFIG_S3C6410
8.頂層makefile
SMDK6400 -> OK6410
9.編譯
export BUILD_DIR=./build
make ok6410_config
make all
DEBUG:
#arm-linux-ld:/home/forlinx/u-boot/u-boot-2013.04-rc1/build/u-boot.lds:19: syntax error
/home/forlinx/u-boot/u-boot-2013.04-rc1/board/samsung/ok6410/u-boot-nand.lds 中
align -> ALIGN
#/home/forlinx/u-boot/u-boot-2013.04-rc1/build/nand_spl/board/samsung/ok6410/start.S:227: undefined reference to `_main'
nand_spl/board/samsung/ok6410/Makefile 中
SOBJS = start.o cpu_init.o lowlevel_init.o crt0.o
$(obj)crt0.S:
@rm -f $@
@ln -s $(TOPDIR)/arch/arm/lib/crt0.S $@
/arch/arm/lib/crt0.S 中註釋
@bl coloured_LED_init
@bl red_led_on
10.MMC啓動
編寫 arch/arm/cpu/arm1176/s3c64xx/s3c6410_sdboot.c
arch/arm/cpu/arm1176/s3c64xx/Makefile中
COBJS-$(CONFIG_S3C6410) += cpu_init.o speed.o
COBJS-$(CONFIG_BOOT_SD) += s3c6410_sdboot.o
COBJS-y += timer.o init.o
arch/arm/cpu/arm1176/start.S中
#if defined(CONFIG_BOOT_SD) && !defined(CONFIG_NAND_SPL)
ldr sp,=CONFIG_SYS_INIT_SP_ADDR
bl BootCopyMMCtoMem
cmp r0,#0
copyerror:
beq copyerror
ldr pc,=_main @to BL2 in SDRAM
#else
bl _main
#endif
include/configs/ok6410.h中
#define CONFIG_BOOT_SD
board/samsung/ok6410/lowlevel_init.S中
LED初始化修改
時鐘初始化修改:
/* FOUT of EPLL is 96MHz */
@ldr r1, =0x200203
ldr r1, =0x80200103 @ldr r1, =0x80200203
MMU表修改:
/* 256MB for SDRAM 0xC0000000 -> 0x50000000 */
.set __base, 0x500
/*.rept 0xC80 - 0xC00 by Ronny*/
.rept 0xD00 - 0xC00
FL_SECTION_ENTRY __base, 3, 0, 1, 1
.set __base, __base + 1
.endr
/* access is not allowed. */
/*.rept 0x1000 - 0xC80 by Ronny*/
.rept 0x1000 - 0xD00
.word 0x00000000
.endr
include/configs/ok6410.h中
#define CONFIG_MACH_TYPE 1626
#define CONFIG_SYS_HZ 1562500
#define CONFIG_ENV_SIZE 0X80000
#define CONFIG_ENV_OFFSET 0X0080000
#define CONFIG_SYS_NAND_U_BOOT_OFFS (16*1024)
#define CONFIG_SYS_NAND_U_BOOT_SIZE (496*1024)
#define CONFIG_SYS_NAND_PAGE_SIZE 4096
#define CONFIG_SYS_NAND_PAGE_COUNT 128
#define CONFIG_SYS_NAND_BLOCK_SIZE (128*4096)
#define CONFIG_SYS_NO_FLASH
include/flash.h中
#ifdef CONFIG_SYS_NO_FLASH
鏈接文件修改
board/samsung/ok6410/u-boot-nand.lds:
.text :
{
arch/arm/cpu/arm1176/start.o (.text)
board/samsung/ok6410/libok6410.o (.text)
*(.text)
}
raise : signal #8 caught異常
arch/arm/cpu/arm1176/s3c64xx/timer.c中
DECLARE_GLOBAL_DATA_PTR;
//static ulong timer_load_val;
//static unsigned long lastdec;
//static unsigned long long timestamp;
#define timer_load_val (gd->arch.timer_rate_hz)
#define lastdec (gd->arch.lastinc)
#define timestamp (gd->arch.timer_reset_value)
ulong get_timer_masked(void)
{
unsigned long long res = get_ticks();
//do_div (res, (timer_load_val / (100 * CONFIG_SYS_HZ)));
return res;
}
11.添加MMC驅動
編寫 drivers/mmc/s3c6410_sdhci.c
include/configs/ok6410.h :
#define CONFIG_MMC //select mmc device as block device
#define CONFIG_GENERIC_MMC //added mmc.c
#define CONFIG_CMD_MMC //added cmd_mmc.c
#define CONFIG_SDHCI //added sdhci.c
#define CONFIG_MMC_SDMA
#define CONFIG_S3C6410_SDHCI //added s3c6410_sdhci.c
dirvers/mmc/sdhci.c :
#define SDHCI_DEFAULT_BOUNDARY_SIZE (1024*512)
add_sdhci()
{
..
mmc->b_max = 1024; //blocks
sdhci_reset(host, SDHCI_RESET_ALL);
mmc_register(mmc);
return 0;
}
註釋
//mask |= SDHCI_INT_DATA_END;
drivers/mmc/Makefile
COBJS-$(CONFIG_S3C6410_SDHCI) += s3c6410_sdhci.o
對應uboot的命令
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices
fatinfo mmc 0
fatls mmc 0
fatload mmc 0 50000000 u-boot-nand.bin
12.添加hello命令
編寫 common/cmd_hello.c
common/Makefile
COBJS-$(CONFIG_CMD_HELLO) += cmd_hello.o
ok6410.h
#define CONFIG_CMD_HELLO
#MMC環境變量
ok6410.h
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_SYS_MMC_ENV_DEV 0
#ifndef CONFIG_ENV_IS_IN_MMC
#define CONFIG_ENV_IS_IN_NAND
#endif
對應命令
env default [-f] -a - [forcibly] reset default environment
env default [-f] var [...] - [forcibly] reset variable(s) to their default values
env delete [-f] var [...] - [forcibly] delete variable(s)
env edit name - edit environment variable
env export [-t | -b | -c] [-s size] addr [var ...] - export environment
env import [-d] [-t | -b | -c] addr [size] - import environment
env print [-a | name ...] - print environment
env run var [...] - run commands in an environment variable
env save - save environment
env set [-f] name [arg ...]
setenv
saveenv
printenv
13.cache
arch/arm/lib/cache.c中
void __enable_caches(void)
{
icache_enable();
if(!icache_status()){
puts("WARING: iCache not enabled\n");
}
dcache_enable();
if(!dcache_status()){
puts("WARING: dCache not enabled\n");
}
//puts("WARNING: Caches not enabled\n");
}
14.添加NAND驅動
///////// nand //////////////
#define CONFIG_S3C6410_CUSTOM_NAND_TIMING
#define CONFIG_S3C6410_TACLS 7 //hclk*tacls 0~7
#define CONFIG_S3C6410_TWRPH0 7 //hclk*(twrph0+1) 0~7
#define CONFIG_S3C6410_TWRPH1 7 //hclk*(twrph1+1) 0~7
#define CONFIG_SYS_NAND_U_BOOT_OFFS (16*1024)
#define CONFIG_SYS_NAND_U_BOOT_SIZE (496*1024)
#define CONFIG_SYS_NAND_PAGE_SIZE 4096
#define CONFIG_SYS_NAND_PAGE_COUNT 128
#define CONFIG_SYS_NAND_BLOCK_SIZE (128*4096)
//#define CONFIG_SYS_NAND_SELECT_DEVICE
#define CONFIG_SYS_S3C_NAND_HWECC
#define CONFIG_NAND_BL1_8BIT_ECC
#define CONFIG_SYS_NAND_ECCSIZE 512
#define CONFIG_SYS_NAND_ECCBYTES 13
#define CONFIG_SYS_NAND_OOBSIZE 218
#define CONFIG_SYS_NAND_ECCPOS {114,115,116,117,118,119,120,121,122,123,\
124,125,126,127,128,129,130,131,132,133,\
134,135,136,137,138,139,140,141,142,143,\
144,145,146,147,148,149,150,151,152,153,\
154,155,156,157,158,159,160,161,162,163,\
164,165,166,167,168,169,170,171,172,173,\
174,175,176,177,178,179,180,181,182,183,\
184,185,186,187,188,189,190,191,192,193,\
194,195,196,197,198,199,200,201,202,203,\
204,205,206,207,208,209,210,211,212,213,\
214,215,216,217}
nand_base.c 中的nand_get_flash_type()函數的讀id有bug,讀id前沒有片選中nand,記得修改,這裏不貼出
drivers/mtd/nand/s3c64xx.c :
#if defined(CONFIG_S3C6410_CUSTOM_NAND_TIMING)
tacls = CONFIG_S3C6410_TACLS;
twrph0 = CONFIG_S3C6410_TWRPH0;
twrph1 = CONFIG_S3C6410_TWRPH1;
cfg = readl(NFCONF);
cfg &= ~(tacls << 12);
cfg &= ~(twrph0 << 8);
cfg &= ~(twrph1 << 4);
cfg |= (tacls << 12);
cfg |= (twrph0 << 8);
cfg |= (twrph1 << 4);
writel(cfg,NFCONF);
cfg = readl(NFCONT);
cfg |= 0x7;
writel(cfg,NFCONT);
#endif
arch/arm/include/arch-s3c64xx/s3c6410.h :
#define NF8ECCERR0 __REG(ELFIN_NAND_BASE + 0x44)
#define NF8ECCERR1 __REG(ELFIN_NAND_BASE + 0x48)
#define NF8ECCERR2 __REG(ELFIN_NAND_BASE + 0x4c)
#define NFM8ECC0 __REG(ELFIN_NAND_BASE + 0x50)
#define NFM8ECC1 __REG(ELFIN_NAND_BASE + 0x54)
#define NFM8ECC2 __REG(ELFIN_NAND_BASE + 0x58)
#define NFM8ECC3 __REG(ELFIN_NAND_BASE + 0x5c)
#define NFMLC8BITPT0 __REG(ELFIN_NAND_BASE + 0x60)
#define NFMLC8BITPT1 __REG(ELFIN_NAND_BASE + 0x64)
board/samsung/ok6410/lowlevel_init.S :
nand_asm_init:
ldr r0, =ELFIN_NAND_BASE
ldr r1, [r0, #NFCONF_OFFSET]
orr r1, r1, #0x10
orr r1, r1, #0x300
str r1, [r0, #NFCONF_OFFSET]
ldr r1, [r0, #NFCONT_OFFSET]
orr r1, r1, #0x07
str r1, [r0, #NFCONT_OFFSET]
mov pc, lr
nand_base.c:
static struct nand_ecclayout nand_oob_218 = {
.eccbytes = 104,
.eccpos = {
24,25,26,27,28,29,30,31,32,33,
34,35,36,37,38,39,40,41,42,43,
44,45,46,47,48,49,50,51,52,53,
54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,
74,75,76,77,78,79,80,81,82,83,
84,85,86,87,88,89,90,91,92,93,
94,95,96,97,98,99,100,101,102,103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127},
.oobfree = {
{.offset = 2,
.length = 22} }
};
nand_scan_tail()
{
...
case 218:
chip->ecc.layout = &nand_oob_218;
break;
}
nand_get_flash_type()
{
.....
}
uboot中的命令
nand info - show available NAND devices
nand device [dev] - show or set current device
nand read - addr off|partition size
nand write - addr off|partition size
read/write 'size' bytes starting at offset 'off'
to/from memory address 'addr', skipping bad blocks.
nand read.raw - addr off|partition [count]
nand write.raw - addr off|partition [count]
Use read.raw/write.raw to avoid ECC and access the flash as-is.
nand erase[.spread] [clean] off size - erase 'size' bytes from offset 'off'
With '.spread', erase enough for given file size, otherwise,
'size' includes skipped bad blocks.
nand erase.part [clean] partition - erase entire mtd partition'
nand erase.chip [clean] - erase entire chip'
nand bad - show bad blocks
nand dump[.oob] off - dump page
nand scrub [-y] off size | scrub.part partition | scrub.chip really clean NAND erasing bad blocks (UNSAFE)
nand markbad off [...] - mark bad block(s) at offset (UNSAFE)
nand biterr off - make a bit error at offset (UNSAFE)
nand read/write 的 size必須爲頁對齊
15.nand_spl
cmd_nand.c:
do_nand()
{
...
#endif
}else if(!read && s !=NULL && (!strcmp(s,".uboot")) && nand->writesize == 4096){
rwsize = 4096;
nand_write(nand,off,&rwsize,(u_char*)addr);
off += 4096;
addr += 2048;
nand_write(nand,off,&rwsize,(u_char*)addr);
off += 4096;
addr += 2048;
nand_write(nand,off,&rwsize,(u_char*)addr);
off += 4096;
addr += 2048;
nand_write(nand,off,&rwsize,(u_char*)addr);
off += 4096;
addr += 2048;
rwsize = CONFIG_SYS_NAND_U_BOOT_SIZE - 8*1024;
ret = nand_write(nand,off,&rwsize,(u_char*)addr);
#ifdef CONFIG_CMD_NAND_YAFFS
...
}
nand_spl/board/samsung/ok6410/config.mk
PAD_TO := $(shell expr $$[$(CONFIG_SYS_TEXT_BASE) + 8192]) #有bug
PAD_TO := $(shell expr $(CONFIG_SYS_TEXT_BASE) + 8192)
make 後 build/下u-boot.bin大小減u-boot-nand.bin爲8192
nand_spl工程中的所有中間文件
SOBJS = start.o cpu_init.o lowlevel_init.o crt0.o
COBJS = nand_boot.o nand_ecc.o s3c64xx.o ok6410_nand_spl.o nand_base.o
crt0.S中的_main中的board_init_f()在生成u-boot.bin和u-boot-nand.bin時有所不同
u-boot.bin in arch/arm/lib/crt0.S
u-boot-nand.bin in board/samsung/ok6410/ok6410_nand_spl.c
crt0.S:
#if defined(CONFIG_NAND_SPL)
/* deprecated, use instead CONFIG_SPL_BUILD */
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
/*bss_clean:*/ /* bug*/
ldr r0, =__bss_start /* this is auto-relocated! */
ldr r1, =__bss_end__ /* this is auto-relocated! */
mov r2, #0x00000000 /* prepare zero to clear BSS */
bss_clean:
cmp r0,r1
strlo r2,[r0]
addlo r0,r0,#4
blo bss_clean
ldr pc,=nand_boot
#elif defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
ok6410.h:
#ifdef CONFIG_ENABLE_MMU
#define CONFIG_SYS_MAPPED_RAM_BASE 0xc0000000
//#define CONFIG_BOOTCOMMAND "nand read 0xc0018000 0x100000 0x500000;" \
"bootm 0xc0018000"
#else
#define CONFIG_SYS_MAPPED_RAM_BASE CONFIG_SYS_SDRAM_BASE
//#define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x100000 0x500000;" \
"bootm 0x50018000"
#endif
#ifdef CONFIG_BOOT_SD
#define CONFIG_BOOTCOMMAND "fatload mmc 0 50008000 u-boot-nand.bin;" \
"nand erase.chip;" \
"nand write.uboot 50008000 0 0"
#else
#define CONFIG_BOOTCOMMAND "fatload mmc 0 50008000 uImage;" \
"bootm 50008000"
#endif
16.DM9000網卡驅動移植
#if 0
#define CONFIG_CS8900 /* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE 0x18800300
#define CONFIG_CS8900_BUS16 /* follow the Linux driver */
#endif
//dm9000 macros
#define CONFIG_DM9000
#define CONFIG_DM9000_NO_SROM 1
#define CONFIG_DRIVER_DM9000 1
//dm9000
#define CONFIG_DM9000_BASE 0x18800300
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE + 0X04)
#define CONFIG_DM9000_USE_16BIT
#define CONFIG_ETHADDR 00:40:5c:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.244.244
#define CONFIG_SERVERIP 192.168.244.132
#define CONFIG_GETEWAYIP 192.168.244.1
board/samsung/ok6410/ok6410.c:
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_CS8900
rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
#endif
#ifdef CONFIG_DM9000
rc = dm9000_initialize(bis);
#endif
return rc;
}