u-boot-2014.10移植第27天----nand flash啟動(五)
硬體平臺:tq2440
開發環境:Ubuntu-3.11
u-boot版本:2014.10
本文允許轉載,請註明出處:http://blog.csdn.net/fulinus
為實現nand flash啟動,最好的方法是使用u-boot自身提供的SPL方式,就是藉助另一個相對獨立的u-boot-spl.bin執行檔案,將u-boot.bin拷貝到SDRAM中去,再執行u-boot.bin。這樣一來u-boot就可以再次重定向。我們這裡首先嚐試用一個老方法。
1、首先關閉“位置無關”的編譯選項,在arch/arm/config.mk檔案中,註釋“pie”:
# needed for relocation
# LDFLAGS_u-boot += -pie
2、修改基地址,在include/configs/tq2440.h配置檔案中,修改CONFIG_SYS_TEXT_BASE:
#define CONFIG_SYS_TEXT_BASE 0x33F80000
3、在board/samsung/tq2440目錄下新增nand_read_ll.c檔案,nand_read_ll.c檔案內容如下:
/* NAND FLASH控制器 */
#define NFCONF (*((volatile unsigned long *)0x4E000000))
#define NFCONT (*((volatile unsigned long *)0x4E000004))
#define NFCMMD (*((volatile unsigned long *)0x4E000008))
#define NFADDR (*((volatile unsigned long *)0x4E00000C))
#define NFDATA (*((volatile unsigned long *)0x4E000010))
#define NFSTAT (*((volatile unsigned long *)0x4E000020))
static int is_boot_from_norflash(void)
{
int val;
volatile int *p = (volatile int *)0;
val = *p;
*p = 0x12345678;
if(*p == 0x12345678){
/* 寫成功,是nand flash啟動 */
*p = val;
return 0;
}else{
/* Nor flash 不能像記憶體一樣寫 */
return 1;
}
}
void nand_init_ll(void)
{
#define TACLS 0
#define TWRPH0 1
#define TWRPH1 0
/* 設定時序 */
NFCONT = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
/* 使能Nand flash 控制器,初始化ECC, 禁止片選 */
NFCONT = (1<<4)|(1<<1)|(1<<0);
}
void clear_bss(void)
{
extern int __bss_start, __bss_end;
int *p = &__bss_start;
for(; p < &__bss_end; p++){
*p = 0;
}
}
static void nand_select(void)
{
NFCONT &= ~(1<<1);
}
static void nand_deselect(void)
{
NFCONT |= (1<<1);
}
static void nand_cmd(unsigned char cmd)
{
volatile int i;
NFCMMD = cmd;
for(i = 0; i < 10; i++);
}
static void nand_addr(unsigned int addr)
{
volatile int i;
unsigned int col = addr % 2048;
unsigned int page = addr / 2048;
NFADDR = col & 0xFF;
for(i = 0; i < 10; i++);
NFADDR = (col >> 8) & 0xFF;
for(i = 0; i < 10; i++);
NFADDR = page & 0xFF;
for(i = 0; i < 10; i++);
NFADDR = (page >> 8) & 0xFF;
for(i = 0; i < 10; i++);
NFADDR = (page >> 16) & 0xFF;
for(i = 0; i < 10; i++);
}
static void nand_wait_ready(void)
{
while(!(NFSTAT & 1));
}
static unsigned char nand_data(void)
{
return NFDATA;
}
static void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len)
{
int i = 0;
int col = addr % 2048;
/* 1.選中 */
nand_select();
while(i < len)
{
/* 2.發出讀命令:00h */
nand_cmd(0x00);
/* 3.發出地址指令 */
nand_addr(addr);
/* 4.發出讀命令:30h */
nand_cmd(0x30);
/* 5.判斷狀態 */
nand_wait_ready();
/* 6.讀資料 */
for(; (col < 2048) && (i < len); col++){
buf[i] = nand_data();
i++;
addr++;
}
col = 0;
}
/* 7.取消選中 */
nand_deselect();
}
void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{
int i = 0;
/* 如果是Nor flash 啟動 */
if(is_boot_from_norflash()){
while(i < len){
dest[i] = src[i];
i++;
}
}else{
nand_init_ll();
nand_read_ll((unsigned int)src, dest, len);
}
}
4、修改board/samsung/tq2440目錄下的Makefile檔案:
obj-y := tq2440.o
+ obj-y += nand_read_ll.o
obj-y += lowlevel_init.o
ENTRY(_main)
/*
* Set up initial C runtime environment and call board_init_f(0).
*/
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
ldr sp, =(CONFIG_SPL_STACK)
#else
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
mov r2, sp
sub sp, sp, #GD_SIZE /* allocate one GD above SP */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
mov r9, sp /* GD is above SP */
#if 1
__TEXT_BASE:
.word CONFIG_SYS_TEXT_BASE
mov r0, #0
ldr r1, __TEXT_BASE
ldr r2, __TEXT_BASE
ldr r3, =__bss_end
sub r2, r3, r2
bl copy_code_to_sdram
bl clear_bss
ldr pc, =call_board_init_f
call_board_init_f:
mov r0, #0
bl board_init_f
ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
sub r9, r9, #GD_SIZE /* new GD is below bd */
ldr r1, __TEXT_BASE
bl board_init_r
#else
mov r1, sp
mov r0, #0
clr_gd:
cmp r1, r2 /* while not at end of GD */
strlo r0, [r1] /* clear 32-bit GD word */
addlo r1, r1, #4 /* move to next */
blo clr_gd
#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SPL_BUILD)
sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN
str sp, [r9, #GD_MALLOC_BASE]
#endif
/* mov r0, #0 not needed due to above code */
bl board_init_f
#if ! defined(CONFIG_SPL_BUILD)
/*
* Set up intermediate environment (new sp and gd) and call
* relocate_code(addr_moni). Trick here is that we'll return
* 'here' but relocated.
*/
ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
sub r9, r9, #GD_SIZE /* new GD is below bd */
adr lr, here
ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */
add lr, lr, r0
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
b relocate_code
here:
/* Set up final (full) environment */
bl c_runtime_cpu_setup /* we still call old routine here */
ldr r0, =__bss_start /* this is auto-relocated! */
ldr r1, =__bss_end /* this is auto-relocated! */
mov r2, #0x00000000 /* prepare zero to clear BSS */
clbss_l:cmp r0, r1 /* while not at end of BSS */
strlo r2, [r0] /* clear 32-bit BSS word */
addlo r0, r0, #4 /* move to next */
blo clbss_l
bl coloured_LED_init
bl red_led_on
/* call board_init_r(gd_t *id, ulong dest_addr) */
mov r0, r9 /* gd_t */
ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */
/* call board_init_r */
ldr pc, =board_init_r /* this is auto-relocated! */
/* we should not return here. */
#endif
#endif
ENDPROC(_main)
6、修改arch/arm/lib/board.c 檔案中的board_init_f函式:
//void board_init_f(ulong bootflag)
unsigned int board_init_f(ulong bootflag)
。。。
//addr -= gd->mon_len;
//addr &= ~(4096 - 1);
addr = CONFIG_SYS_TEXT_BASE;
。。。
memcpy(id, (void *)gd, sizeof(gd_t));
return (unsigned int)id;
}
7、同時修改include/common.h標頭檔案中board_init_f函式的宣告:
//void board_init_f(ulong);
unsigned int board_init_f(ulong);
8、修改連線指令碼arch/arm/cpu/u-boot.lds檔案,將nand_read_ll.c檔案放在前4K位元組中:
.text :
{
*(.__image_copy_start)
*(.vectors)
CPUDIR/start.o (.text*)
board/samsung/tq2440/lowlevel_init.o(.text*)
board/samsung/tq2440/nand_read_ll.o(.text*)
*(.text*)
}
9、修改arch/arm/config.mk檔案,將checkarmreloc功能註釋掉:
# ALL-y += checkarmreloc
10、編譯
不成功,感覺這個方法很牽強,換一種;
明天繼續;
相關文章
- u-boot-2014.10移植第28天----nand flash啟動(六)bootNaN
- u-boot-2014.10移植第25天----nand flash啟動(三)bootNaN
- u-boot-2014.10移植第26天----nand flash啟動(四)bootNaN
- u-boot-2014.10移植第23天----nand flash啟動(一)bootNaN
- u-boot-2014.10移植第24天----nand flash啟動(二)bootNaN
- u-boot-2014.10移植第29天----nand flash的SPL啟動(一)bootNaN
- u-boot-2014.10移植第30天----nand flash的SPL啟動(二)bootNaN
- u-boot-2014.10移植第16天----Nor flash啟動boot
- u-boot-2014.10移植第21天----新增nand flash命令支援(三)bootNaN
- u-boot-2014.10移植第22天----新增nand flash命令支援(四)bootNaN
- u-boot-2014.10移植第19天----新增nand flash命令支援(一)bootNaN
- u-boot-2014.10移植第20天----新增nand flash命令支援(二)bootNaN
- u-boot-2014.10移植第15天----nor flash操作boot
- u-boot-2014.10移植第31天----核心啟動(一)boot
- S3C2440從NAND Flash啟動和NOR FLASH啟動的問題S3NaN
- ZYNQ FLASH+EMMC手動移植LINUX啟動Linux
- NAND FlashNaN
- NAND Flash和NOR Flash的區別NaN
- Mini2440 64M Nand Flash 更改為128M Nand FlashNaN
- nor flash 和nand flash 傻傻分不清楚NaN
- NAND FLASH的介面控制設計NaN
- NAND FLASH系統的權衡利弊NaN
- u-boot-2014.10移植第17天----新增DM9000網路卡支援(一)boot
- u-boot-2014.10移植第18天----新增DM9000網路卡支援(二)boot
- Nand Flash結構及錯誤機制NaN
- 關於NAND FLASH解釦的認識NaN
- NAND Flash是如何生產出來的?NaN
- ARM學習之Nand FLash控制器NaN
- 宏旺半導體科普SPI NAND Flash和SPI NOR Flash的區別NaN
- uboot1: 啟動流程和移植框架boot框架
- 怎麼看時序圖--nand flash的讀操作詳解時序圖NaN
- Nand Flash基礎知識與壞塊管理機制的研究NaN
- 東芝停工、NAND Flash又要漲價了?宏旺半導體:國產替代來臨NaN
- (轉)關於NAND flash的MTD分割槽與uboot中分割槽的理解NaNboot
- 痞子衡嵌入式:飛思卡爾i.MX RT系列MCU啟動那些事(8)- 從Raw NAND啟動NaN
- DRAMeXchange:2019年Q1 NAND Flash品牌商營收季減23.8%NaN營收
- TrendForce:2024年第一季全球NAND Flash產業營收季增28.1%NaN產業營收
- win10 microsoft edge flash player當前已禁用如何啟動Win10ROS