亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標題: u-boot-2014-04在TQ2440上的移植 [打印本頁]

作者: 摩斯電碼    時間: 2014-06-30 09:15
標題: u-boot-2014-04在TQ2440上的移植
本帖最后由 摩斯電碼 于 2014-06-30 09:52 編輯

作者:  彭東林
郵箱:pengdonglin137@163.com
QQ405728433

到官網(wǎng)http://ftp.denx.de/pub/u-boot/下載u-boot-2014.04.tar.bz2
解壓后在board/samsung/目錄下仍然沒有2440,雖然沒有直接支持2440開發(fā)板,但其代碼已經(jīng)支持,只需添加相關(guān)配置即可。
一、 首先建立自己的開發(fā)板
拷貝board/samsung/smdk2410/目錄到board/tq2440
pengdl@debian:~/work/tq2440/u-boot-2014.04$ cp -a board/samsung/smdk2410/ board/tq2440
進入board/tq2440目錄修改
pengdl@debian:~/work/tq2440/u-boot-2014.04/board/tq2440$ mv smdk2410.c tq2440.c
修改該目錄下的Makefile
obj-y    := tq2440.o
拷貝配置文件(使用相似的smdk2410開發(fā)板的配置文件)
pengdl@debian:~/work/tq2440/u-boot-2014.04$ cp include/configs/smdk2410.h include/configs/tq2440.h
增加開發(fā)板配置選項
在頂層目錄下的Makefile中搜索不到smdk2410
在頂層目錄執(zhí)行如下命令
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "smdk2410" * -nR
./boards.cfg:74:
smdk2410                     arm         arm920t     -                   samsung        s3c24x0
./MAINTAINERS:774:        smdk2410        ARM920T
./board/samsung/smdk2410/Makefile:28:COBJS        := smdk2410.o
./board/tq2440/Makefile:28:COBJS        := smdk2410.o
./arch/arm/include/asm/mach-types.h:1646:# define machine_is_smdk2410()        (machine_arch_type == MACH_TYPE_SMDK2410)
./arch/arm/include/asm/mach-types.h:1648:# define machine_is_smdk2410()        (0)
從這里知道在頂層目錄下的boards.cfg文件中定義了smdk2410開發(fā)板的配置選項,仿照它定義TQ2440開發(fā)板的配置選項
# # Status, Arch, CPU:SPLCPU, SoC, Vendor, Board name, Target, Options, Maintainers                          
###########################################################################################################
Active  arm         arm920t        s3c24x0     -               tq2440                   tq2440                               -                                                                                                                                 -
由于我在board目錄下創(chuàng)建開發(fā)板目錄,所以Vendor指定為空
二、 配置時鐘
先大致看一下配置文件include/configs/tq2440.h
/*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_ARM920T                /* This is an ARM920T Core */
#define CONFIG_S3C24X0                /* in a SAMSUNG S3C24x0-type SoC */
#define CONFIG_S3C2410                /* specifically a SAMSUNG S3C2410 SoC */
#define CONFIG_SMDK2410                /* on a SAMSUNG SMDK2410 Board */
這里是高級別的一些配置,配置了S3C2410 SoC和SMDK2410 Board,跟我使用的開發(fā)板不一致
根據(jù)我自己的開發(fā)板tq2440進行如下配置
//#define CONFIG_S3C2410        /* specifically a SAMSUNG S3C2410 SoC */
#define CONFIG_S3C2440
//#define CONFIG_SMDK2410       /* on a SAMSUNG SMDK2410 Board */
#define CONFIG_AUTO_COMPLETE  //開啟命令自動補全
#define CONFIG_SYS_PROMPT        "TQ2440 # "                // 命令提示符
屏蔽一些暫時不用的支持,用的時候再加上
#if 0
#define CONFIG_CS8900                /* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE        0x19000300
#define CONFIG_CS8900_BUS16        /* the Linux driver does accesses as shorts */
#endif
#if 0
#define CONFIG_USB_OHCI
#define CONFIG_USB_KEYBOARD
#define CONFIG_USB_STORAGE
#define CONFIG_DOS_PARTITION
#endif
//#define CONFIG_CMD_DHCP
//#define CONFIG_CMD_NAND
//#define CONFIG_CMD_PING
//#define CONFIG_CMD_REGINFO
//#define CONFIG_CMD_USB
#if 0
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define CONFIG_YAFFS2
#define CONFIG_RBTREE
#endif
看下鏈接腳本arch/arm/cpu/u-boot.lds
CPUDIR/start.o (.text*)
從這里可以知道u-boot執(zhí)行的第一個文件是arch/arm/cpu/arm920t/start.S
        /* FCLK:HCLKCLK = 1:2:4 */
        /* default FCLK is 120 MHz ! */
        ldr        r0, =CLKDIVN
        mov        r1, #3
        str        r1, [r0]
上面幾行代碼是針對S3C2410
添加時鐘初始化代碼如下
# if defined(CONFIG_S3C2410)
        ldr        r1, =0x3ff
        ldr        r0, =INTSUBMSK
        str        r1, [r0]
# endif
# if defined(CONFIG_S3C2440)
        ldr        r1, =0x7fff
        ldr        r0, =INTSUBMSK        // 屏蔽子中斷
        str        r1, [r0]
# endif /* CONFIG_S3C2440 */
# if defined(CONFIG_S3C2440)
# define MPLLCON        0x4C000004        //系統(tǒng)主頻配置寄存器
# define UPLLCON        0x4C000008  //USB頻率配置寄存器
# define CAMDIVN        0x4C000018  //照相機時鐘分頻寄存器
        ldr r0, =CAMDIVN
        mov r1, #0
        str r1, [r0]
        ldr r0, =CLKDIVN
        mov r1, #0x05
        str r1, [r0]
        /*如果HDIVN不等于0CPU必須設(shè)置為異步總線模式*/
        mrc p15,0,r0,c1,c0,0
        orr r0,r0,#0xc0000000
        mcr p15,0,r0,c1,c0,0
        ldr r0, =UPLLCON
        ldr r1, =0x38022  // USB時鐘48MHZ
        str r1, [r0]
        /*
        **When you set MPLL&UPLL values, you have to set the UPLL
        **value first and then the MPLL value. (Needs intervals
        **approximately 7 NOP)
        */
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        ldr r0, =MPLLCON
        ldr r1, =0x5c011 //CPU時鐘400MHZ
        str r1, [r0]
# else
        /* FCLK:HCLKCLK = 1:2:4 */
        /* default FCLK is 120 MHz ! */
        ldr        r0, =CLKDIVN
        mov        r1, #3
        str        r1, [r0]
#endif /* CONFIG_S3C2440 */
#endif        /* CONFIG_S3C24X0 */
board/tq2440/tq2440.cboard_early_init_f()函數(shù)也初始化了時鐘,因為我在start.S中已初始化了時鐘,所以屏蔽掉board_early_init_f()中對時鐘的初始化代碼
//        struct s3c24x0_clock_power * const clk_power =
//                                        s3c24x0_get_base_clock_power();
        struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
#if 0
        /* to reduce PLL lock time, adjust the LOCKTIME register */
        writel(0xFFFFFF, &clk_power->locktime);

        /* configure MPLL */
        writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
               &clk_power->mpllcon);

        /* some delay between MPLL and UPLL */
        pll_delay(4000);

        /* configure UPLL */
        writel((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV,
               &clk_power->upllcon);

        /* some delay between MPLL and UPLL */
        pll_delay(8000);
#endif
可以先配置u-boot支持直接燒寫進內(nèi)存SDRAM運行
修改配置文件tq2440.h
#define CONFIG_SYS_TEXT_BASE         0x32000000
CONFIG_SYS_TEXT_BASE指定了代碼的加載地址,待會編譯好后生成可執(zhí)行二進制文件u—boot.bin,就要把u-boot.bin下載到該地址
我們現(xiàn)在需要直接燒寫進內(nèi)存運行,而底層初始化代碼還沒移植,所以我們需要跳過底層初始化
查看arch/arm/cpu/arm920t/start.S
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
        bl        cpu_init_crit
#endif
如果沒有定義CONFIG_SKIP_LOWLEVEL_INIT就跳轉(zhuǎn) cpu_init_crit函數(shù)執(zhí)行,該函數(shù)進行了一些底層的初始化,比如內(nèi)存。因為下面我們直接將u-boot下載到內(nèi)存中運行,如果在內(nèi)存中運行的同時再初始化內(nèi)存,那么內(nèi)存中的數(shù)據(jù)代碼會遭到**。
所以我們在配置文件tq2440.h中定義該宏
#define CONFIG_SKIP_LOWLEVEL_INIT
修改一下頂層Makefile
202  CROSS_COMPILE ?= arm-linux-
ARCH就不用我們手動配置了,因為在執(zhí)行make tq2440_config時,會解析boards.cfg文件,得到ARCH的值。
pengdl@debian:~/work/tq2440/u-boot-2014.04$ make tq2440_config
編譯完成生成可執(zhí)行二進制文件u—boot.bin,開發(fā)板啟動原有好的u-boot
u-boot.bin下載到SDRAM0x32000000地址,然后go 0x32000000運行
EmbedSky> tftp 0x32000000 u-boot.bin
(注意:在新版本的u-boot中,進行代碼重定位relocate之前就已經(jīng)在board_init_f中調(diào)用了全局性的代碼,這些全局性的代碼并不是位置無關(guān)的,所以這里需要將u-boot直接下載到它的鏈接地址處,防止程序跑飛)
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
T ###########
done
Bytes transferred = 153844 (258f4 hex)
EmbedSky> go 0x32000000
(注意:必須與剛才tftp下載到的地址相同)
## Starting application at 0x32000000 ...¡ø

U-Boot 2014.04 (Jun 28 2014 - 23:11:32)

CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled

tq2440.h中定義DEBUG
#define DEBUG
EmbedSky> tftp 0x32000000 u-boot.bin;go 0x32000000
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
T ############
done
Bytes transferred = 168860 (2939c hex)
## Starting application at 0x32000000 ...¡ø

U-Boot 2014.04 (Jun 29 2014 - 02:51:27)

U-Boot code: 32000000 -> 320246BC  BSS: -> 3202A0A4
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
monitor len: 0002A0A4
ramsize: 04000000
TLB table from 33ff0000 to 33ff4000
Top of RAM usable for U-Boot at: 33ff0000
Reserving 168k for U-Boot at: 33fc5000
Reserving 4160k for malloc() at: 33bb5000
Reserving 32 Bytes for Board Info at: 33bb4fe0
Reserving 160 Bytes for Global Data at: 33bb4f40
New Stack Pointer is: 33bb4f30
RAM Configuration:
Bank #0: 30000000 64 MiB
relocation Offset is: 01fc5000
WARNING: Caches not enabled
monitor flash len: 0002939C
Now running in RAM - U-Boot at: 33fc5000

經(jīng)過加打印,問題定位在board.c中的board_init_r在調(diào)用mem_malloc_init函數(shù)時出了問題,他完成的操作是將malloc_start標識的malloc區(qū)域清零,這里malloc區(qū)域的大小是4MB+160KB,發(fā)現(xiàn)在清除到2MB多的時候程序就掛了。
這個問題的原因好沒有找到,等待解決。目前臨時的解決辦法是將malloc區(qū)域的大小減小為2MB+160KB,做法是修改tq2440.h中,將
#define CONFIG_SYS_MALLOC_LEN        (4 * 1024 * 1024)
改為:
#define CONFIG_SYS_MALLOC_LEN        (2 * 1024 * 1024)
然后編譯運行,打印信息如下:
U-Boot code: 32000000 -> 320246BC  BSS: -> 3202A0A4
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
monitor len: 0002A0A4
ramsize: 04000000
TLB table from 33ff0000 to 33ff4000
Top of RAM usable for U-Boot at: 33ff0000
Reserving 168k for U-Boot at: 33fc5000
Reserving 2112k for malloc() at: 33db5000
Reserving 32 Bytes for Board Info at: 33db4fe0
Reserving 160 Bytes for Global Data at: 33db4f40
New Stack Pointer is: 33db4f30
RAM Configuration:
Bank #0: 30000000 64 MiB
relocation Offset is: 01fc5000
WARNING: Caches not enabled
monitor flash len: 0002939C
Now running in RAM - U-Boot at: 33fc5000
Flash: fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
fwc addr 0000aaaa cmd aa 00aa 16bit x 16 bit
fwc addr 00005554 cmd 55 0055 16bit x 16 bit
fwc addr 0000aaaa cmd 90 0090 16bit x 16 bit
fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
JEDEC PROBE: ID 1c 2249 0
fwc addr 00000000 cmd ff 00ff 16bit x 16 bit
fwc addr 00000000 cmd 90 0090 16bit x 16 bit
fwc addr 00000000 cmd ff 00ff 16bit x 16 bit
JEDEC PROBE: ID 16 ea00 0
*** failed ***
### ERROR ### Please RESET the board ###

未完待續(xù)。。。。。。

作者: 摩斯電碼    時間: 2014-06-30 09:16
一、 移植NOR FLASH
第二步Flash: *** failed ***
### ERROR ### Please RESET the board ###
卡在這里不動了
搜索“Flash:”
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "Flash:" * -nR
......
arch/arm/lib/board.c:557:       puts("Flash: ";
.....
進入查看
        puts("Flash: ";
        flash_size = flash_init();
        if (flash_size > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
                print_size(flash_size, "";
                /*
                 * Compute and print flash CRC if flashchecksum is set to 'y'
                 *
                 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
                 */
                if (getenv_yesno("flashchecksum" == 1) {
                        printf("  CRC: %08X", crc32(0,
                                (const unsigned char *) CONFIG_SYS_FLASH_BASE,
                                flash_size));
                }
                putc('\n');
# else        /* !CONFIG_SYS_FLASH_CHECKSUM */
                print_size(flash_size, "\n";
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
        } else {
                puts(failed);
                hang();
        }
failed在該文件中的定義如下
static char *failed = "*** failed ***\n";
函數(shù)hang()在該文件中的定義如下
void hang(void)
{
        puts("### ERROR ### Please RESET the board ###\n";
        for (;;
}
說明是flash初始化失敗
進入drivers/mtd/cfi_flash.c:flash_init函數(shù)
if (!flash_detect_legacy(cfi_flash_bank_addr(i), i))
flash_detect_legacy函數(shù)去探測flash
進入flash_detect_legacy函數(shù)
flash_read_jedec_ids(info);
debug("JEDEC PROBE: ID %x %x %x\n",
                                                info->manufacturer_id,
                                                info->device_id,
                                                info->device_id2);
if (jedec_flash_match(info, info->start[0]))
                break;
else
unmap_physmem((void *)info->start[0], MAP_NOCACHE);
jedec_flash_match函數(shù)將讀取到的flash信息與jedec_table進行匹配,如果匹配成功則填充flash_info,否則返回1,看來這里沒有匹配成功,在drivers/mtd/cfi_flash.cflash_detect_legacy函數(shù)去探測開發(fā)板的flash,打開調(diào)試信息的宏,將探測到的flash信息打印出來
#define DEBUG  (也可以加載tq2440.h)
重新編譯,開發(fā)板從NOR FLASH啟動,
EmbedSky> tftp 0x32000000 u-boot.bin;go 0x32000000
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
T ############
done
Bytes transferred = 168860 (2939c hex)
## Starting application at 0x32000000 ...
U-Boot 2014.04 (Jun 29 2014 - 02:57:57)
U-Boot code: 32000000 -> 320246BC  BSS: -> 3202A0A4
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
monitor len: 0002A0A4
ramsize: 04000000
TLB table from 33ff0000 to 33ff4000
Top of RAM usable for U-Boot at: 33ff0000
Reserving 168k for U-Boot at: 33fc5000
Reserving 2112k for malloc() at: 33db5000
Reserving 32 Bytes for Board Info at: 33db4fe0
Reserving 160 Bytes for Global Data at: 33db4f40
New Stack Pointer is: 33db4f30
RAM Configuration:
Bank #0: 30000000 64 MiB
relocation Offset is: 01fc5000
WARNING: Caches not enabled
monitor flash len: 0002939C
Now running in RAM - U-Boot at: 33fc5000
Flash: fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
fwc addr 0000aaaa cmd aa 00aa 16bit x 16 bit
fwc addr 00005554 cmd 55 0055 16bit x 16 bit
fwc addr 0000aaaa cmd 90 0090 16bit x 16 bit
fwc addr 00000000 cmd f0 00f0 16bit x 16 bit
JEDEC PROBE: ID 1c 2249 0
fwc addr 00000000 cmd ff 00ff 16bit x 16 bit
fwc addr 00000000 cmd 90 0090 16bit x 16 bit
fwc addr 00000000 cmd ff 00ff 16bit x 16 bit
JEDEC PROBE: ID 16 ea00 0
*** failed ***
### ERROR ### Please RESET the board ###
根據(jù)debug("JEDEC PROBE: ID %x %x %x\n",
                                                info->manufacturer_id,
                                                info->device_id,
                                                info->device_id2);
可以知道已經(jīng)探測到開發(fā)板的flash的廠家ID0x1c,設(shè)備ID0x2249
在jedec_table表中增加TQ2440開發(fā)板的NOR FLASH(EN29LV160AB)內(nèi)容
#ifdef CONFIG_SYS_FLASH_LEGACY_1024Kx16
    {    /* TQ2440 EN29LV160AB */
            .mfr_id     = 0x1c,          /* manufacturer_id */
            .dev_id     = 0x2249,   /* device_id */
            .name       = "EON EN29LV160AB",
            .uaddr      = {/* 因為NOR FLASHADDR0接到了S3C2440ADDR1 */
                [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
            },  
            .DevSize    = SIZE_2MiB,
            .CmdSet     = P_ID_AMD_STD,
            .NumEraseRegions= 4,
            .regions    = {
                ERASEINFO(0x04000, 1),
                ERASEINFO(0x02000, 2),  
                ERASEINFO(0x08000, 1),  
                ERASEINFO(0x10000, 31),
            }   
        },  
#endif
注釋掉剛才打開的宏
drivers/mtd/cfi_flash.c
//#define DEBUG
并在tq2440.h中定義CONFIG_SYS_FLASH_LEGACY_1024Kx16
//#define CONFIG_SYS_FLASH_LEGACY_512Kx16
#define CONFIG_SYS_FLASH_LEGACY_1024Kx16
重新編譯u-boot,從NOR FLASH啟動開發(fā)板
EmbedSky> tftp 0x32000000 u-boot.bin;go 0x32000000
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
T ###########
done
Bytes transferred = 153568 (257e0 hex)
## Starting application at 0x32000000 ...¡ø
U-Boot 2014.04 (Jun 29 2014 - 03:10:56)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: ERROR: too many flash sectors
2 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
TQ2440 #
出現(xiàn)一個錯誤too many flash sectors
搜索too many flash sectors
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "too many flash sectors" *  -nR
./drivers/mtd/jedec_flash.c:444:                                printf("ERROR: too many flash sectors\n";
查看代碼
if (sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT) {
                                printf("ERROR: too many flash sectors\n";
                                break;
                        }
                說明CONFIG_SYS_MAX_FLASH_SECT的值太小了,在配置文件tq2440.h修改該宏
                #define CONFIG_SYS_MAX_FLASH_SECT        (35)        //根據(jù)EN29LV160AB芯片手冊
重新編譯,從NOR FLASH啟動開發(fā)板
EmbedSky> tftp 0x32000000 u-boot.bin;go 0x32000000
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
T ###########
done
Bytes transferred = 153568 (257e0 hex)
## Starting application at 0x32000000 ...¡ø
U-Boot 2014.04 (Jun 29 2014 - 03:12:36)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
TQ2440 #
TQ2440 # flinfo
Bank # 1: EON EN29LV160AB flash (16 x 16)  Size: 2 MB in 35 Sectors
  AMD Legacy command set, Manufacturer ID: 0x1C, Device ID: 0x2249
  Erase timeout: 30000 ms, write timeout: 100 ms
  Sector Start Addresses:
  00000000   RO   00004000   RO   00006000   RO   00008000   RO   00010000   RO
  00020000   RO   00030000        00040000        00050000        00060000      
  00070000   RO   00080000        00090000        000A0000        000B0000      
  000C0000        000D0000        000E0000        000F0000        00100000      
  00110000        00120000        00130000        00140000        00150000      
  00160000        00170000        00180000        00190000        001A0000      
  001B0000        001C0000        001D0000        001E0000        001F0000      
測試flash讀寫是否正常
讀取0x32000000地址的0x10字節(jié)數(shù)據(jù)到0x0地址,然后比較兩份數(shù)據(jù)是否相等
注意:從flinfo中可以看出0地址所在扇區(qū)是RO,要先解保護
TQ2440 # protect off all
Un-Protect Flash Bank # 1
TQ2440 # cp.b 32000000 0 10
Copy to Flash... done
TQ2440 # cmp.b 0 32000000 10
Total of 16 byte(s) were the same
再來讀
TQ2440 # md.b 32000000 10
32000000: 13 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5    ................
TQ2440 # md.b 0 10
00000000: 13 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5    ................
讀出的兩份數(shù)據(jù)一樣
至此NOR FLASH移植完畢

未完待續(xù)。。。。。。


作者: 摩斯電碼    時間: 2014-06-30 09:17
一、 移植網(wǎng)卡DM9000
網(wǎng)卡DM9000的驅(qū)動為drivers/net/dm9000x.c,我們需要將它編譯進u-boot,查看drivers/net/Makefile
38 COBJS-$(CONFIG_DRIVER_DM9000) += dm9000x.o
如果定義了CONFIG_DRIVER_DM9000就將dm9000x.o編譯進u-boot,在配置文件tq2440.h中定義該宏
#define CONFIG_DRIVER_DM9000
在第一步已經(jīng)經(jīng)網(wǎng)卡CS8900的相關(guān)配置注釋掉了
重新編譯出錯
dm9000x.c: In function 'dm9000_outblk_8bit':
dm9000x.c:156: error: 'DM9000_DATA' undeclared (first use in this function)
DM9000_DATA沒有定義,參考mini2440.h的配置如下
#define CONFIG_DRIVER_DM9000
#define CONFIG_DM9000_NO_SROM  
(如果不設(shè)置這個宏,uboot會打印類似:
Warning: dm9000 MAC addresses don't match:
Address in SROM is         ff:ff:ff:ff:ff:ff
Address in environment is  00:0c:29:2a:5c:a5
的信息)
#define CONFIG_DM9000_BASE        0x20000000        //tq2440開發(fā)板的網(wǎng)卡dm9000接在S3C2440bank4 #define DM9000_IO                        CONFIG_DM9000_BASE
#define DM9000_DATA                        (CONFIG_DM9000_BASE+4)        // tq2440開發(fā)板的網(wǎng)卡dm9000cmd引腳接在S3C2440ADDR2
打開之前第一步暫時注釋掉的宏
#define CONFIG_CMD_PING
重新編譯,從NOR FLASH啟動u-boot
EmbedSky> tftp 0x32000000 u-boot.bin;go 0x32000000
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
T ###########
done
Bytes transferred = 154592 (25be0 hex)
## Starting application at 0x32000000 ...¡ø
U-Boot 2014.04 (Jun 29 2014 - 03:16:30)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
TQ2440 #
沒有找到網(wǎng)路
搜索Net
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "Net:" * -nR
......
arch/arm/lib/board.c:662:       puts("Net:   ");
......
查看單板文件board.c
puts("Net:   ");
        eth_initialize(gd->bd);
進入net/eth.c: eth_initialize函數(shù)
if (board_eth_init(bis) < 0)
進入board/tq2440/tq2440.c: board_eth_init函數(shù)
修改如下
int board_eth_init(bd_t *bis)
{
        int rc = 0;
#ifdef CONFIG_CS8900
        rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
#endif
#ifdef CONFIG_DRIVER_DM9000
        rc = dm9000_initialize(bis);
#endif
        return rc;
}
重新編譯,從NOR FLASH啟動u-boot
EmbedSky> tftp 0x32000000 u-boot.bin;go 0x32000000
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
T ###########
done
Bytes transferred = 160268 (2720c hex)
## Starting application at 0x32000000 ...¡ø
U-Boot 2014.04 (Jun 29 2014 - 03:20:16)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
TQ2440 # set ethaddr 00:12:34:56:ab:cd        設(shè)置mac地址
TQ2440 # set ipaddr 192.168.1.6                設(shè)置開發(fā)板IP地址
TQ2440 # set serverip 192.168.1.8                設(shè)置tftp服務(wù)器IP地址
TQ2440 # ping 192.168.1.8                                ping主機
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:12:34:56:ab:cd
could not establish link
Using dm9000 device
host 192.168.1.8 is alive
TQ2440 # tftpboot 31000000 u-boot.bin                下載文件
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:12:34:56:ab:cd
could not establish link
Using dm9000 device
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x31000000
Loading: ##############
         1.8 MiB/s
done
Bytes transferred = 198364 (306dc hex)
注意到新版u-boot在用tftp下載時會打印出下載速度,另外上面出現(xiàn)了一個錯誤could not establish link
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "could not establish link" * -nR
./drivers/net/dm9000x.c:376:                        printf("could not establish link\n");
查看代碼并修改
#if 0
        i = 0;
        while (!(dm9000_phy_read(1) & 0x20)) {        /* autonegation complete bit */
                udelay(1000);
                i++;
                if (i == 10000) {
                        printf("could not establish link\n");
                        return 0;
                }
        }
#endif
重新編譯,從NOR FLASH重啟開發(fā)板
EmbedSky> tftp 0x32000000 u-boot.bin;go 0x32000000
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
T ###########
done
Bytes transferred = 160140 (2718c hex)
## Starting application at 0x32000000 ...¡ø
U-Boot 2014.04 (Jun 29 2014 - 03:25:30)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
現(xiàn)在重新下載剛才的u-boot.bin
TQ2440 # tftp 0x30000000 u-boot.bin
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: ff:ff:ff:ff:ff:ff
WARNING: Bad MAC address (uninitialized EEPROM?)
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x30000000
Loading: T ###########
         30.3 KiB/s
done
Bytes transferred = 160140 (2718c hex)
剛才的錯誤解決了
至此網(wǎng)卡DM9000移植完畢

未完待續(xù)。。。。。。


作者: 摩斯電碼    時間: 2014-06-30 09:18
一、 支持NAND FLASH讀寫
修改配置文件include/configs/tq2440.h打開之前注釋掉的NAND相關(guān)的宏
#define CONFIG_CMD_NAND
編譯出錯
s3c2410_nand.c: In function 's3c2410_hwcontrol':
s3c2410_nand.c:57: warning: implicit declaration of function 's3c2410_get_base_nand'
s3c2410_nand.c:57: warning: initialization makes pointer from integer without a cast
s3c2410_nand.c:72: error: dereferencing pointer to incomplete type
s3c2410_nand.c:72: error: dereferencing pointer to incomplete type
s3c2410_nand.c:75: error: dereferencing pointer to incomplete type
s3c2410_nand.c:75: error: dereferencing pointer to incomplete type
查看代碼
struct s3c2410_nand *nand = s3c2410_get_base_nand();
struct s3c2410_nand的定義
#ifdef CONFIG_S3C2410
/* NAND FLASH (see S3C2410 manual chapter 6) */
struct s3c2410_nand {
        u32        nfconf;
        u32        nfcmd;
        u32        nfaddr;
        u32        nfdata;
        u32        nfstat;
        u32        nfecc;
};
#endif
s3c2410_get_base_nand()在s3c2410.h中聲明
s3c2410_nand.c中包含了頭文件s3c24x0_cpu.h,該文件內(nèi)容如下
#ifdef CONFIG_S3C2400
        #include <asm/arch/s3c2400.h>
#elif defined CONFIG_S3C2410
        #include <asm/arch/s3c2410.h>
#elif defined CONFIG_S3C2440
        #include <asm/arch/s3c2440.h>
#else
        #error Please define the s3c24x0 cpu type
#endif
而我在配置文件tq2440中注釋了宏CONFIG_S3C2410,添加了CONFIG_S3C2440
查看drivers/mtd/nand/Makefile
75 COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
CONFIG_NAND_S3C2410在tq2440.h中定義
drivers/mtd/nand/s3c2410_nand.c拷貝為drivers/mtd/nand/s3c2440_nand.c
pengdl@debian:~/work/tq2440/u-boot-2014.04$ cp drivers/mtd/nand/s3c2410_nand.c drivers/mtd/nand/s3c2440_nand.c
在drivers/mtd/nand/Makefile文件中增加一行
56   obj-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
將s3c2440_nand.c中所有的2410替換為2440
修改配置文件include/configs/tq2440.h
187 /*
188  * NAND configuration
189  */
190 #ifdef CONFIG_CMD_NAND
191 #ifdef CONFIG_S3C2440
192 #define CONFIG_NAND_S3C2440
193 #define CONFIG_SYS_S3C2440_NAND_HWECC
194 #else
195 #define CONFIG_NAND_S3C2410
196 #define CONFIG_SYS_S3C2410_NAND_HWECC
197 #endif
198 #define CONFIG_SYS_MAX_NAND_DEVICE  1
199 #define CONFIG_SYS_NAND_BASE        0x4E000000
200 #endif
重新編譯,從NOR FLASH啟動開發(fā)板
EmbedSky> tftp 0x32000000 u-boot.bin;go 0x32000000
.......
U-Boot 2014.04 (Jun 29 2014 - 03:42:02)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  0 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
TQ2440 #
搜索NAND:
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "NAND:" * -nR
......
arch/arm/lib/board.c:584:       puts("NAND:  ";
......
查看代碼
#if defined(CONFIG_CMD_NAND)
        puts("NAND:  ";
        nand_init();                /* go init the NAND */
#endif
一路跟蹤下去,列出函數(shù)調(diào)用順序
nand_init-> nand_init_chip-> board_nand_init
                                                                -> nand_scan-> nand_scan_ident
其中board_nand_init是與板相關(guān)的初始化
nand_scan_ident函數(shù)中
        /* Read the flash type */
        type = nand_get_flash_type(mtd, chip, busw,
                                &nand_maf_id, &nand_dev_id, table);
        if (IS_ERR(type)) {
#ifndef CONFIG_SYS_NAND_QUIET_TEST
                printk(KERN_WARNING "No NAND device found!!!\n";
#endif
                chip->select_chip(mtd, -1);
                return PTR_ERR(type);
        }
說明上面的nand_get_flash_type獲取失敗
修改drivers/mtd/nand/s3c2440_nand.c中的board_nand_init()函數(shù)
#define S3C2440_NFCONF_TACLS(x)    ((x)<<12)
#define S3C2440_NFCONF_TWRPH0(x)   ((x)<<
#define S3C2440_NFCONF_TWRPH1(x)   ((x)<<4)
......
#if defined(CONFIG_S3C24XX_CUSTOM_NAND_TIMING)
        tacls  = CONFIG_S3C24XX_TACLS;
        twrph0 = CONFIG_S3C24XX_TWRPH0;
        twrph1 =  CONFIG_S3C24XX_TWRPH1;
#else
        tacls = 0;
        twrph0 = 1;
        twrph1 = 0;
#endif
        //cfg = S3C2440_NFCONF_EN;
        cfg |= S3C2440_NFCONF_TACLS(tacls);
        cfg |= S3C2440_NFCONF_TWRPH0(twrph0);
        cfg |= S3C2440_NFCONF_TWRPH1(twrph1);
        writel(cfg, &nand_reg->nfconf);
/*初始化ECC、禁止片選、使能NAND FLASH控制器*/
        writel((1 << 4)|(1 << 1)|(1 << 0), &nand_reg->nfcont);
修改默認的drivers/mtd/nand/nand_base.c: nand_select_chip函數(shù)
        case 0:        // 選中
                chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
                break;
修改s3c2440_hwcontrol()函數(shù)
        if (ctrl & NAND_CTRL_CHANGE) {
                ulong IO_ADDR_W = (ulong)nand;
                if (!(ctrl & NAND_CLE))
                        IO_ADDR_W |= S3C2440_ADDR_NCLE;
                if (!(ctrl & NAND_ALE))
                        IO_ADDR_W |= S3C2440_ADDR_NALE;
                if (cmd == NAND_CMD_NONE)
                        IO_ADDR_W = &nand->nfdata;
                       
                chip->IO_ADDR_W = (void *)IO_ADDR_W;
                if (ctrl & NAND_NCE)        // 使能選中
                        writel(readl(&nand->nfcont) & ~(1 << 1),
                               &nand->nfcont);
                else                // 取消選中
                        writel(readl(&nand->nfcont) | (1 << 1),
                               &nand->nfcont);
        }
修改
#define S3C2440_ADDR_NALE 8
#define S3C2440_ADDR_NCLE 0xc
#define S3C2440_NFCONF_nFCE        (1<<1)
重新編譯燒到,從NOR FLASh啟動開發(fā)板
TQ2440 # tftp 32000000 u-boot.bin;go 32000000
測試
SDRAM0x32000000地址的0xff字節(jié)數(shù)據(jù)寫到NAND FLASH0地址
TQ2440 # nand write 32000000 0 ff       
NAND write: device 0 offset 0x0, size 0xff
255 bytes written: OK
NAND FLASH0地址讀0xff字節(jié)數(shù)據(jù)到SDRAM0x31000000地址
TQ2440 # nand read 31000000 0 ff
NAND read: device 0 offset 0x0, size 0xff
255 bytes read: OK
比較
TQ2440 # cmp.b 31000000 32000000 ff
Total of 255 bytes were the same

未完待續(xù)。。。。。。


作者: 摩斯電碼    時間: 2014-06-30 09:18
一、 修改代碼支持NOR FLASH啟動
修改配置文件tq2440.h
#define CONFIG_SYS_TEXT_BASE           0x0
(這里必須設(shè)置為0,因為這個版本的uboot中尚未進行代碼重定位之前,就調(diào)用了很多全局性的代碼,所以需要設(shè)置為0,否則程序會跑飛)
//#define CONFIG_SKIP_LOWLEVEL_INIT
(如果不定義CONFIG_SKIP_LOWLEVEL_INIT,u-boot在從NorFlash啟動時會執(zhí)行內(nèi)存初始化代碼
190     /*
191      * we do sys-critical inits only at reboot,
192      * not when booting from ram!
193      */
194 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
195     bl  cpu_init_crit
196 #endif
197
198     bl  _main
修改內(nèi)存初始化代碼board/tq2440/lowlevel_init.S
#define REFCNT                        0x4f4    #修改內(nèi)存初始化參數(shù)
重新編譯,從NOR FLASH啟動,使用原先好的u-boot將新的u-boot.bin燒寫到NOR FLASH
EmbedSky> tftp 0x32000000 u-boot.bin
dm9000 i/o: 0x20000300, id: 0x90000a46
MAC: 0a:1b:2c:3d:4e:5f
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
checksum bad
T ###############
done
Bytes transferred = 215096 (34838 hex)
EmbedSky> protect off all
Un-Protect Flash Bank # 1
EmbedSky> erase 0 +40000
Erasing sector  0 ... ok.
Erasing sector  1 ... ok.
Erasing sector  2 ... ok.
Erasing sector  3 ... ok.
Erasing sector  4 ... ok.
Erasing sector  5 ... ok.
Erasing sector  6 ... ok.
Erased 7 sectors
EmbedSky> cp.b 0x32000000 0x0 0x40000
Copy to Flash... done
ÿmbedSky> reset
U-Boot 2014.04 (Jun 29 2014 - 04:07:20)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
TQ2440 #
二、 保存環(huán)境變量到NAND FLASH并添加分區(qū)
默認是把環(huán)境變量保存到NOR FLASH的,環(huán)境變量是通過執(zhí)行saveenv命令保存的,查看一下該命令的實現(xiàn)代碼。搜索“saveenv
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "saveenv" common/ -nR
common/env_flash.c:122:int saveenv(void)
common/env_flash.c:245:int saveenv(void)
common/env_nand.c:174:int saveenv(void)
common/env_nand.c:226:int saveenv(void)
搜索出了env_flash.c和env_fnand.c,分別用于將環(huán)境變量保存到NOR FLASHNAND FLASH
查看common/Makefile
57 COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o
60 COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
我們需要在配置文件tq2440.h中去掉CONFIG_ENV_IS_IN_FLASH,增加CONFIG_ENV_IS_IN_NAND
修改配置文件tq2440.h
#if 0
#define CONFIG_ENV_ADDR                        (CONFIG_SYS_FLASH_BASE + 0x070000)
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE                        0x10000
#endif
#define CONFIG_ENV_IS_IN_NAND
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
重新編譯,出錯
/home/work/u-boot-2013.01/include/environment.h:88: error: #error "Need to define CONFIG_ENV_OFFSET when using CONFIG_ENV_IS_IN_NAND"
/home/work/u-boot-2013.01/include/environment.h:95: error: #error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_NAND"
在配置文件tq2440.h中定義這兩個宏
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET        0x40000        // 256K for u-boot
#define CONFIG_ENV_SIZE         0x20000        // 128K for environment
重新編譯,從NOR FLASH啟動開發(fā)板
U-Boot 2014.04 (Jun 29 2014 - 04:31:22)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
TQ2440 # protect off all;erase 0 +40000;tftp 32000000 u-boot.bin;cp.b 32000000 0 40000
Un-Protect Flash Bank # 1
....... done
Erased 7 sectors
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: ff:ff:ff:ff:ff:ff
WARNING: Bad MAC address (uninitialized EEPROM?)
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: T ###############
         41 KiB/s
done
Bytes transferred = 215572 (34a14 hex)
Copy to Flash... 9....8....7....6....5....4....3....2....1....done
TQ2440 # reset
resetting ...
U-Boot 2014.04 (Jun 29 2014 - 04:31:22)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
出現(xiàn)*** Warning - bad CRC, using default environment,這是因為NAND FLASH中沒有有效的環(huán)境變量,執(zhí)行saveenv命令將環(huán)境變量保存到NAND FLASH,重啟就不會有這樣的提示了
TQ2440 # saveenv
Saving Environment to NAND...
Erasing NAND...
Erasing at 0x40000 -- 100% complete.
Writing to NAND... OK
TQ2440 # reset
resetting ...
U-Boot 2014.04 (Jun 29 2014 - 04:31:22)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
TQ2440 # mtd
Unknown command 'mtd' - try 'help'
默認沒有分區(qū)命令,查看一下common/Makefile
140 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
說明需要定義CONFIG_CMD_MTDPARTS才會編譯mtd命令
tq2440.h中其實已經(jīng)定義了該宏,只是之前被我注釋掉了,現(xiàn)在打開它
#if 0
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#endif
#define CONFIG_CMD_MTDPARTS
#if 0
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define CONFIG_YAFFS2
#define CONFIG_RBTREE
#endif
重新編譯,出錯
/home/work/u-boot-2013.01/common/cmd_mtdparts.c:306: undefined reference to `get_mtd_device_nm'
查看代碼知道get_mtd_device_nm在drivers/mtd/mtdcore.c中定義,查看drivers/mtd/Makefile
28 COBJS-$(CONFIG_MTD_DEVICE) += mtdcore.o
需要定義CONFIG_MTD_DEVICE才會編譯mtdcore.c
tq2440.h中其實已經(jīng)定義了該宏,只是之前被我注釋掉了,現(xiàn)在打開它
#if 0
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#endif
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#if 0
#define CONFIG_MTD_PARTITIONS
#define CONFIG_YAFFS2
#define CONFIG_RBTREE
#endif
重新編譯,從NOR FLASH啟動開發(fā)板
TQ2440 # protect off all;erase 0 +40000;tftp 32000000 u-boot.bin;cp.b 32000000 0 40000
……
TQ2440 # reset
……
TQ2440 # mtdparts
mtdids not defined, no default present
出錯了,搜索mtdids not defined, no default present
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "mtdids not defined, no default present" * -nR
common/cmd_mtdparts.c:1751:   printf("mtdids not defined, no default present\n";
查看代碼
if (mtdids_default) {
                        debug("mtdids variable not defined, using default\n";
                        ids = mtdids_default;
                        setenv("mtdids", (char *)ids);
                } else {
                        printf("mtdids not defined, no default present\n";
                        return 1;
                }
說明mtdids_default為假,mtdids_default定義為
#if defined(MTDIDS_DEFAULT)
static const char *const mtdids_default = MTDIDS_DEFAULT;
#else
static const char *const mtdids_default = NULL;
#endif
#if defined(MTDPARTS_DEFAULT)
static const char *const mtdparts_default = MTDPARTS_DEFAULT;
#else
static const char *const mtdparts_default = NULL;
#endif
需要在配置文件tq2440.h定義MTDIDS_DEFAULT和MTDPARTS_DEFAULT,參考common/cmd_mtdparts.c
* Examples:
*
* 1 NOR Flash, with 1 single writable partition:
* mtdids=nor0=edb7312-nor
* mtdparts=mtdparts=edb7312-nor:-
*
* 1 NOR Flash with 2 partitions, 1 NAND with one
* mtdids=nor0=edb7312-nor,nand0=edb7312-nand
* mtdparts=mtdparts=edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nandhome)
tq2440.h中定義
#define MTDIDS_DEFAULT        "nand0=tq2440-0"
#define MTDPARTS_DEFAULT        "mtdparts=tq2440-0:1m(u-boot),"        \
                                                "1m(params),"                \
                                                "3m(kernel),"        \
                                                "-(rootfs)"
tq2440.h中設(shè)置默認環(huán)境變量
#define CONFIG_NETMASK                255.255.255.0
#define CONFIG_IPADDR                192.168.1.6
#define CONFIG_SERVERIP                192.168.1.8
#define CONFIG_ETHADDR                00:11:22:33:44:aa
#define CONFIG_BOOTARGS        "root=/dev/mtdblock2 rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200"
#define CONFIG_BOOTCOMMAND        "nand read 32000000 kernel\;bootm 32000000"
重新編譯,從NOR FLASH啟動開發(fā)板
TQ2440 # protect off all;erase 0 +40000;tftp 32000000 u-boot.bin;cp.b 32000000 0 40000
……
TQ2440 # reset
……
TQ2440 # mtdparts
mtdparts variable not set, see 'help mtdparts'
no partitions defined
defaults:
mtdids  : nand0=tq2440-0
mtdparts: mtdparts=tq2440-0:1m(u-boot),1m(params),3m(kernel),-(rootfs)
TQ2440 # mtdparts default
TQ2440 # save                注意一定要保存,否則重啟就沒了
TQ2440 # mtdparts
device nand0 <tq2440-0>, # parts = 4
#: name                size            offset          mask_flags
0: u-boot              0x00100000      0x00000000      0
1: params              0x00100000      0x00100000      0
2: kernel              0x00300000      0x00200000      0
3: rootfs              0x0fb00000      0x00500000      0
active partition: nand0,0 - (u-boot) 0x00100000 @ 0x00000000
defaults:
mtdids  : nand0=tq2440-0
mtdparts: mtdparts=tq2440-0:1m(u-boot),1m(params),3m(kernel),-(rootfs)
TQ2440 #

未完待續(xù)。。。。。。


作者: 摩斯電碼    時間: 2014-06-30 09:22
一、 支持NAND FLASH啟動
新版u-boot在鏈接時加了“-pie”選項
-pie
           Produce a position independent executable on targets which support it.  For predictable results, you must also specify the same set of options that were used to generate code (-fpie, -fPIE, or model suboptions) when you specify this option.
產(chǎn)生的代碼中,沒有絕對地址,全部使用相對地址,故而代碼可以被加載器加載到內(nèi)存的任意
位置,都可以正確的執(zhí)行。
最終u-boot.bin中多了這些段
.rel.dyn : {
                __rel_dyn_start = .;
                *(.rel*)
                __rel_dyn_end = .;
        }
        .dynsym : {
                __dynsym_start = .;
                *(.dynsym)
        }
NOR FLASH把代碼復制到SDRAM,程序的鏈接地址是0,訪問全局變量、靜態(tài)變量、調(diào)用函數(shù)時是使用基于0地址編譯得到的地址,現(xiàn)在把程序復制到了SDRAM(0x3000000),需要修改代碼,把原來的地址改為新地址。這樣太復雜了,還是使用老版本的方法。
去掉“-pie”選項,在u-boot源碼搜索“-pie
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "\-pie" . -nR
......
./arch/arm/config.mk:83:LDFLAGS_u-boot += -pie
......
去除arch/arm/config.mk:83:LDFLAGS_u-boot += -pie中的“-pie
82 # needed for relocation
83 #LDFLAGS_u-boot += -pie
修改配置文件include/configs/tq2440.h,給u-boot分配512KB
#define CONFIG_SYS_TEXT_BASE          0x33f80000
增加文件board/tq2440/nand_read_ll.c并修改相應(yīng)的Makefile
obj-y        := tq2440.o
obj-y        += nand_read_ll.o
obj-y        += lowlevel_init.o
nand_read_ll.c文件內(nèi)容如下:
/* NAND FLASH控制器 */
#define NFCONF (*((volatile unsigned long *)0x4E000000))
#define NFCONT (*((volatile unsigned long *)0x4E000004))
#define NFCMMD (*((volatile unsigned char *)0x4E00000)
#define NFADDR (*((volatile unsigned char *)0x4E00000C))
#define NFDATA (*((volatile unsigned char *)0x4E000010))
#define NFSTAT (*((volatile unsigned char *)0x4E000020))
static void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len);
static int isBootFromNorFlash(void)
{
        volatile int *p = (volatile int *)0;
        int val;
        val = *p;
        *p = 0x12345678;
        if (*p == 0x1234567
        {
                /* 寫成功, nand啟動 */
                *p = val;
                return 0;
        }
        else
        {
                /* NOR不能像內(nèi)存一樣寫 */
                return 1;
        }
}
void nand_init_ll(void)
{
#define TACLS   0
#define TWRPH0  1
#define TWRPH1  0
        /* 設(shè)置時序 */
        NFCONF = (TACLS<<12)|(TWRPH0<<|(TWRPH1<<4);
        /* 使能NAND Flash控制器, 初始化ECC, 禁止片選 */
        NFCONT = (1<<4)|(1<<1)|(1<<0);       
}
void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{       
        int i = 0;
       
        /* 如果是NOR啟動 */
        if (isBootFromNorFlash())
        {
                while (i < len)
                {
                        dest = src;
                        i++;
                }
        }
        else
        {
                nand_init_ll();
                nand_read_ll((unsigned int)src, dest, len);
        }
}
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)
{
        unsigned int col  = addr % 2048;
        unsigned int page = addr / 2048;
        volatile int i;
        NFADDR = col & 0xff;
        for (i = 0; i < 10; i++);
        NFADDR = (col >> & 0xff;
        for (i = 0; i < 10; i++);
       
        NFADDR  = page & 0xff;
        for (i = 0; i < 10; i++);
        NFADDR  = (page >> & 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 col = addr % 2048;
        int i = 0;
               
        /* 1. 選中 */
        nand_select();
        while (i < len)
        {
                /* 2. 發(fā)出讀命令00h */
                nand_cmd(0x00);
                /* 3. 發(fā)出地址(5步發(fā)出) */
                nand_addr(addr);
                /* 4. 發(fā)出讀命令30h */
                nand_cmd(0x30);
                /* 5. 判斷狀態(tài) */
                nand_wait_ready();
                /* 6. 讀數(shù)據(jù) */
                for (; (col < 204 && (i < len); col++)
                {
                        buf = nand_data();
                        i++;
                        addr++;
                }
               
                col = 0;
        }
        /* 7. 取消選中 */               
        nand_deselect();
}
通過閱讀u-boot源碼arch/arm/cpu/arm920t/start.S
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
        bl        cpu_init_crit
#endif
        bl        _main
跳轉(zhuǎn)到arch/arm/lib/crt0.S:_main
修改arch/arm/lib/crt0.S為:
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 */
        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        r0, #0
        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)
修改arch/arm/lib/board.c中的函數(shù)board_init_f為:

        然后再board_init_f的結(jié)尾添加:

即將board_init_r要用的第一個參數(shù)返回,也就是重定向后gd結(jié)構(gòu)體的起始地址。
修改include/common.h

修改arch/arm/lib/board.c中的函數(shù)board_init_f
//addr -= gd->mon_len;
//addr &= ~(4096 - 1);
addr = CONFIG_SYS_TEXT_BASE;
然后編譯,編譯完成后,執(zhí)行make u-boot.dis,生成u-boot的反匯編文件,看一下start.o、nand_read_ll.o、lowlevel_init.o是否被連接到了u-boot的前面4KB范圍內(nèi):

從上面的圖中可以看到,copy_code_to_sdramclear_bss的地址已經(jīng)超過4KB了,前面我們把CONFIG_SYS_TEXT_BASE設(shè)置為了0x33f80000,但是copy_code_to_sdram的地址已經(jīng)到了0x33f81464,0x33f81464-0x33f80000=0x1464>0x1000,顯然超多了4KB(十六進制就是0x1000),所以需要修改鏈接腳本和Makefile,將nand_read_lllowlevel_init.S 鏈接到uboot的前4KB內(nèi),具體做法如下:
修改鏈接腳本arch/arm/cpu/u-boot.lds把start.onand_read_ll.o、lowlevel_init.o編譯到前面4KB
修改board/tq2440/Makefile
obj-y        := tq2440.o
extra-y        := nand_read_ll.o
extra-y        += lowlevel_init.o
修改arch/arm/cpu/u-boot.lds
        . = ALIGN(4);
        .text :
        {
                *(.__image_copy_start)
                CPUDIR/start.o (.text*)
                board/tq2440/lowlevel_init.o (.text*)
                board/tq2440/nand_read_ll.o (.text*)
                *(.text*)
        }
重新編譯:
  ......
  HOSTLD  tools/dumpimage
  HOSTLD  tools/mkimage
  CC      arch/arm/lib/board.o
  LD      arch/arm/lib/built-in.o
  AS      board/tq2440/lowlevel_init.o
  CC      common/main.o
  CC      common/cmd_version.o
  LD      common/built-in.o
  CC      lib/display_options.o
  LD      lib/built-in.o
  LDS     u-boot.lds
  LD      u-boot
u-boot contains unexpected relocations:
make: *** [checkarmreloc] Error 1
搜索 “u-boot contains unexpected relocations”
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "u-boot contains unexpected relocations" * -nR
沒有搜索到任何內(nèi)容,那么我們搜索checkarmreloc
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "checkarmreloc" * -nR
arch/arm/config.mk:105:ALL-y += checkarmreloc
Makefile:1123:checkarmreloc: u-boot
在頂層Makefile中有如下語句:
1121 # ARM relocations should all be R_ARM_RELATIVE (32-bit) or
1122 # R_AARCH64_RELATIVE (64-bit).
1123 checkarmreloc: u-boot                                                                                                           
1124     @RELOC="`$(CROSS_COMPILE)readelf -r -W $< | cut -d ' ' -f 4 | \
1125         grep R_A | sort -u`"; \
1126     if test "$$RELOC" != "R_ARM_RELATIVE" -a \
1127          "$$RELOC" != "R_AARCH64_RELATIVE"; then \
1128         echo "$< contains unexpected relocations: $$RELOC"; \
1129         false; \
1130     fi
那么我們就別編譯checkarmreloc了,所以我們修改arch/arm/config.mk的第105行:
105 #ALL-y += checkarmreloc
重新編譯,從NOR FLASH啟動開發(fā)板,將u-boot.bin燒到NAND FLASH
TQ2440 # nand erase 0 40000;tftp 32000000 u-boot.bin;nand write 32000000 0 40000
NAND erase: device 0 offset 0x0, size 0x40000
Erasing at 0x20000 -- 100% complete.
OK
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2a:5c:a5
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'u-boot.bin'.
Load address: 0x32000000
Loading: T ###############
         39.1 KiB/s
done
Bytes transferred = 209400 (331f8 hex)
NAND write: device 0 offset 0x0, size 0x40000
262144 bytes written: OK
TQ2440 #
NAND FLASh啟動開發(fā)板
TQ2440 # reset
resetting ...
U-Boot 2014.04 (Jun 29 2014 - 07:58:40)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###
卡在這里不動了,由于從NAND啟動,CPU檢測不到NOR FLASH,具體代碼如下arch/arm/lib/board.c
flash_size = flash_init();
        if (flash_size > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
                print_size(flash_size, "";
                /*
                 * Compute and print flash CRC if flashchecksum is set to 'y'
                 *
                 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
                 */
                if (getenv_yesno("flashchecksum" == 1) {
                        printf("  CRC: %08X", crc32(0,
                                (const unsigned char *) CONFIG_SYS_FLASH_BASE,
                                flash_size));
                }
                putc('\n');
# else        /* !CONFIG_SYS_FLASH_CHECKSUM */
                print_size(flash_size, "\n";
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
        } else {
                puts(failed);
                hang();
        }
其中failed定義為
#if !defined(CONFIG_SYS_NO_FLASH)
static char *failed = "*** failed ***\n";
#endif
函數(shù)hang()定義為
void hang(void)
{
        puts("### ERROR ### Please RESET the board ###\n";
        for (;;
}
我們直接注釋掉上面的hang();
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
        } else {
                puts(failed);
                //hang();
        }
#endif
重新編譯,從NOR FLASH啟動開發(fā)板,將u-boot.bin燒到NAND FLASH,從NAND啟動
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: *** failed ***
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
Hit any key to stop autoboot:  0
TQ2440 #


作者: 摩斯電碼    時間: 2014-06-30 09:24
一、 支持燒寫yaffs文件系統(tǒng)
執(zhí)行? Nand
TQ2440 # ? nand
nand - NAND sub-system
Usage:
……
沒有.yaffs后綴,在源碼目錄搜索.yaffs
pengdl@debian:~/work/tq2440/u-boot-2014.04$ grep "\.yaffs" * -nR
......
common/cmd_nand.c:709:          } else if (!strcmp(s, ".yaffs") {
......
查看代碼
708 #ifdef CONFIG_CMD_NAND_YAFFS
709         } else if (!strcmp(s, ".yaffs") {                                                                                      
710             if (read) {
711                 printf("Unknown nand command suffix '%s'.\n", s);
712                 return 1;
713             }
714             ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
715                         maxsize, (u_char *)addr,
716                         WITH_YAFFS_OOB);
717 #endif
需要在配置文件tq2440.h中定義CONFIG_CMD_NAND_YAFFS
#define CONFIG_CMD_NAND_YAFFS
重新編譯,燒寫到NandFlash中:
TQ2440 # nand ?
nand - NAND sub-system
Usage:
……
nand write.yaffs - addr off|partition size
    write 'size' bytes starting at offset 'off' with yaffs format
from memory address 'addr', skipping bad blocks.
……
TQ2440 #
先直接燒寫試一下
TQ2440 # tftp 32000000 uImage;nand erase.part kernel;
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2a:5c:a5
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'uImage'.
Load address: 0x32000000
Loading: T #################################################################
         #################################################################
         ############################
         361.3 KiB/s
done
Bytes transferred = 2317984 (235ea0 hex)
NAND erase.part: mtdparts variable not set, see 'help mtdparts'
incorrect device type in kernel
     TQ2440 # mtdpart default
TQ2440 # saveenv
Saving Environment to NAND...
Erasing NAND...
Erasing at 0x40000 -- 100% complete.
Writing to NAND... OK
TQ2440 # nand erase.part kernel
NAND erase.part: device 0 offset 0x200000, size 0x300000
Erasing at 0x4e0000 -- 100% complete.
OK
TQ2440 # nand write 32000000 kernel                燒寫內(nèi)核
NAND write: device 0 offset 0x200000, size 0x300000
3145728 bytes written: OK
TQ2440 # tftp 30000000 root.bin        確保yaffs文件系統(tǒng)是好的
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2a:5c:a5
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'root.bin'.
Load address: 0x30000000
Loading: T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##########
         778.3 KiB/s
done
Bytes transferred = 6825984 (682800 hex)
TQ2440 # nand erase.part rootfs
TQ2440 # nand write.yaffs 30000000 rootfs $filesize
設(shè)置u-boot啟動參數(shù)
TQ2440 # set bootargs root=/dev/mtdblock2 rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200
TQ2440 # set bootcmd nand read 32000000 kernel\;bootm 32000000
TQ2440 # save
TQ2440 # reset
resetting ...
U-Boot 2014.04 (Jun 29 2014 - 08:14:15)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: *** failed ***
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
Hit any key to stop autoboot:  0
NAND read: device 0 offset 0x200000, size 0x300000
3145728 bytes read: OK
## Booting kernel from Legacy Image at 32000000 ...
   Image Name:   Linux-3.8.7
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2317920 Bytes = 2.2 MiB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Error: unrecognized/unsupported machine ID (r1 = 0x000000c1).
Available machine support:
ID (hex)        NAME
000000a8        SMDK2440
Please check your kernel config and/or bootloader.
不支持的機器ID
由于我用的是tq2440自帶的內(nèi)核,tq2440的機器ID168,修改arch/arm/mach-types.h,添加TQ2440的機器ID

兩種解決辦法:
1、 設(shè)置環(huán)境變量machid
TQ2440 # set machid a8
TQ2440 # save
2、 修改board/tq2440/tq2440.c: board_init函數(shù)
gd->bd->bi_arch_number = MACH_TYPE_TQ2440;
解決后重啟開發(fā)板
resetting ...
U-Boot 2014.04 (Jun 29 2014 - 08:14:15)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: *** failed ***
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
Hit any key to stop autoboot:  0
NAND read: device 0 offset 0x200000, size 0x300000
3145728 bytes read: OK
## Booting kernel from Legacy Image at 32000000 ...
   Image Name:   Linux-2.6.30.4-EmbedSky
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2415756 Bytes = 2.3 MiB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
Using machid 0xa8 from environment
Starting kernel ...
Uncompressing Linux................................................................................................................................................................ done, booting the kernel.
Linux version 2.6.30.4-EmbedSky (pengdl@debian) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-176) ) #1 Sat Jun 21 02:35:07 EDT 2014
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
................
NET: Registered protocol family 17
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
lib80211: common routines for IEEE802.11 drivers
s3c2410-rtc s3c2410-rtc: setting system clock to 2013-03-03 18:07:17 UTC (1362334037)
yaffs: dev is 32505858 name is "mtdblock2"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.2, "mtdblock2"
block 325 is bad
block 330 is bad
block 519 is bad
block 1252 is bad
block 1753 is bad
block 1754 is bad
yaffs_read_super: isCheckpointed 0
VFS: Mounted root (yaffs2 filesystem) on device 31:2.
Freeing init memory: 240K
Warning: unable to open an initial console.
Failed to execute /linuxrc.  Attempting defaults...
Kernel panic - not syncing: No init found.  Try passing init= option to kernel.
Backtrace:
[<c0048fd4>] (dump_backtrace+0x0/0x10c) from [<c036f630>] (dump_stack+0x18/0x1c)
r7:00000000 r6:c04e8d40 r5:c04e8700 r4:c04b0248
[<c036f618>] (dump_stack+0x0/0x1c) from [<c036f680>] (panic+0x4c/0x124)
[<c036f634>] (panic+0x0/0x124) from [<c00444f0>] (init_post+0xec/0x17
r3:00000000 r2:00000000 r1:c051f000 r0:c043c77c
[<c0044404>] (init_post+0x0/0x17 from [<c000847c>] (kernel_init+0xcc/0xf4)
r5:c001f860 r4:c001fcc8
[<c00083b0>] (kernel_init+0x0/0xf4) from [<c0059f30>] (do_exit+0x0/0x620)
r7:00000000 r6:00000000 r5:00000000 r4:00000000
已經(jīng)掛載上yaffs2文件系統(tǒng),因為yaffs文件系統(tǒng)是好的,所以是u-boot燒寫yaffs文件系統(tǒng)的問題
YAFFS中,文件是以固定大小的數(shù)據(jù)塊進行存儲的,塊的大小可以是512字節(jié)、1 024字節(jié)或者2 048字節(jié)。這種實現(xiàn)依賴于它能夠?qū)⒁粋數(shù)據(jù)塊頭和每個數(shù)據(jù)塊關(guān)聯(lián)起來。每個文件(包括目錄)都有一個數(shù)據(jù)塊頭與之相對應(yīng),數(shù)據(jù)塊頭中保存了ECC(Error Correction Code)和文件系統(tǒng)的組織信息,用于錯誤檢測和壞塊處理。
TQ2440開發(fā)板用的NAND FLASH每頁2k
用UltraEdit打開剛才燒寫的root.bin文件和燒到NAND FLASH里的數(shù)據(jù)對比
u-boot中執(zhí)行
TQ2440 # nand dump 500000
Page 00500000 dump:
        03 00 00 00 01 00 00 00  ff ff 00 00 00 00 00 00
     ………………………………………………
        ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
OOB:
        ff ff ff ff ff ff ff ff
        ff ff ff ff ff ff ff ff
        ff ff ff ff ff ff ff ff
        ff ff ff ff ff ff ff ff
        ff ff ff ff ff ff ff ff
        aa 9a a7 ff f3 03 ff ff
        ff ff ff ff ff ff ff ff
        ff ff ff ff ff ff ff ff
TQ2440 #
通過對比發(fā)現(xiàn)燒到NAND FLASH里的數(shù)據(jù)和原文件不一致
查看代碼common/cmd_nand.c
#ifdef CONFIG_CMD_NAND_YAFFS
                } else if (!strcmp(s, ".yaffs") {
                        if (read) {
                                printf("Unknown nand command suffix '%s'.\n", s);
                                return 1;
                        }
                        ret = nand_write_skip_bad(nand, off, &rwsize,
                                                (u_char *)addr,
                                                WITH_YAFFS_OOB);
#endif
調(diào)用函數(shù)drivers/mtd/nand/nand_util.c: nand_write_skip_bad,注意這里傳入了一個標志WITH_YAFFS_OOB
drivers/mtd/nand/nand_util.c:nand_write_skip_bad()函數(shù)
if (!need_skip && !(flags & WITH_DROP_FFS)) {
                rval = nand_write (nand, offset, length, buffer);
這里如果沒有壞塊而且沒有指定WITH_DROP_FFS標志就執(zhí)行nand_write (nand, offset, length, buffer);
而我們需要執(zhí)行write_oob(nand, offset, &ops);所以應(yīng)該加上之前傳入的參數(shù)
if (!need_skip && !(flags & WITH_DROP_FFS) && !(flags & WITH_YAFFS_OOB))
ops.mode = MTD_OOB_RAW; /* 原來為AUTO,應(yīng)該為原始 */
重新編譯,燒寫新的u-boot.bin,重新燒寫yaffs文件系統(tǒng)
TQ2440 # nand erase.part u-boot;tftp 32000000 u-boot.bin;nand write 32000000 u-boot
TQ2440 # reset
TQ2440 # tftp 0x32000000 root.bin;nand erase.part rootfs;nand write.yaffs 0x32000000 rootfs $filesize
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:2a:5c:a5
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.8; our IP address is 192.168.1.6
Filename 'root.bin'.
Load address: 0x32000000
Loading: T #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ##########
         777.3 KiB/s
done
Bytes transferred = 6825984 (682800 hex)
NAND erase.part: device 0 offset 0x500000, size 0xfb00000
Skipping bad block at  0x02d80000                                          
Skipping bad block at  0x02e20000                                          
Skipping bad block at  0x045c0000                                          
Skipping bad block at  0x0a160000                                          
Skipping bad block at  0x0e000000                                          
Skipping bad block at  0x0e020000                                          
Erasing at 0xffe0000 -- 100% complete.
OK
NAND write: device 0 offset 0x500000, size 0x682800
6825984 bytes written: OK
TQ2440 # reset
……
s3c2410-rtc s3c2410-rtc: setting system clock to 2013-03-03 18:11:59 UTC (1362334319)
yaffs: dev is 32505858 name is "mtdblock2"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.2, "mtdblock2"
block 325 is bad
block 330 is bad
block 519 is bad
block 1252 is bad
block 1753 is bad
block 1754 is bad
yaffs_read_super: isCheckpointed 0
VFS: Mounted root (yaffs2 filesystem) on device 31:2.
Freeing init memory: 240K
mmc0: new SDHC card at address 1234
mmcblk0: mmc0:1234 SA04G 3.63 GiB
mmcblk0: p1
FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
Please press Enter to activate this console.
[root@TQ2440 /]#
[root@TQ2440 /]#

未完待續(xù)。。。。。。


作者: 摩斯電碼    時間: 2014-06-30 09:25
一、 添加NAND FLASH 硬件ECC
tq2440.h中定義如下宏
#define CONFIG_S3C2440_NAND_HWECC
#ifdef CONFIG_S3C2440_NAND_HWECC
#define CONFIG_SYS_NAND_ECCSIZE                2048
#define CONFIG_SYS_NAND_ECCBYTES            4
#endif
修改arch/arm/include/asm/arch-s3c24x0/s3c24x0.h:s3c2440_nand結(jié)構(gòu)體,添加寄存器
        u32        nfstat0;
        u32        nfstat1;
        u32 nfmecc0;
        u32 nfmecc1;
        u32 nfsecc;
        u32 nfsblk;
        u32 nfeblk;
修改drivers/mtd/nand/s3c2440_nand.c
void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
        struct s3c2440_nand *nand = s3c2440_get_base_nand();
        debug("s3c2440_nand_enable_hwecc(%p, %d)\n", mtd, mode);
        /* 初始化ECC */
        writel(readl(&nand->nfcont) | (1 << 4), &nand->nfcont);
}
static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
                                      u_char *ecc_code)
{
        struct s3c2440_nand *nand = s3c2440_get_base_nand();
        writel(readl(&nand->nfcont)| (1 << 5),&nand->nfcont);        /* 鎖定main區(qū)ECC */
        /* 讀取寄存器NFMECC0,該寄存器存放著由硬件生成的main區(qū)ECC */
        u32  mecc0;
        mecc0 = readl(&nand->nfmecc0);
        ecc_code[0] = mecc0 & 0xff;
        ecc_code[1] = (mecc0 >> &0xff;
        ecc_code[2] = (mecc0 >> 16) &0xff;
        ecc_code[3] =(mecc0 >> 24) & 0xff;
        debug("s3c2440_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x 0x%02x\n",
               mtd , ecc_code[0], ecc_code[1], ecc_code[2], ecc_code[3]);
        return 0;
}
static int s3c2440_nand_correct_data(struct mtd_info *mtd, u_char *dat,
                                     u_char *read_ecc, u_char *calc_ecc)
{
        struct  s3c2440_nand *nand = s3c2440_get_base_nand();
        u32  meccdata0, meccdata1, estat0, err_byte_addr;
        int  ret = -1;
        u8  repaired;
        meccdata0 = (read_ecc[1] << 16) | read_ecc[0];
        meccdata1 = (read_ecc[3] << 16) | read_ecc[2];
        writel(meccdata0, &nand->nfeccd0);
        writel(meccdata1, &nand->nfeccd1);
        /*Read ecc status */
        estat0 = readl(&nand->nfstat0);  
        switch(estat0 & 0x3) {
        case  0: /* No error */
                ret= 0;
                break;
        case  1:
                /*
                * 1 bit error (Correctable)
                * (nfestat0 >> 7) & 0x7ff    :error byte number
                * (nfestat0 >> 4) & 0x7      :error bit number
                */
                err_byte_addr = (estat0 >> 7) & 0x7ff;
                repaired = dat[err_byte_addr] ^ (1 << ((estat0 >> 4) & 0x7));
                printf("s3c2440_nand_correct_data: 1 bit error detected at byte %ld. Correcting from 0x%02x to 0x%02x...OK\n",
                                err_byte_addr, dat[err_byte_addr], repaired);
                dat[err_byte_addr] = repaired;
                ret= 0;
                break;
        case  2: /* Multiple error */
        case  3: /* ECC area error */
                printf("s3c2440_nand_correct_data: ECC uncorrectable errordetected. " "Not correctable.\n";
                ret= -1;
                break;
        }
        return ret;
}
tq2440.h中定義CONFIG_MTD_NAND_VERIFY_WRITE實現(xiàn)把所寫的數(shù)據(jù)再讀取一遍,然后與被寫入的數(shù)據(jù)之間進行比較來判斷所寫數(shù)據(jù)的正確性。
#define CONFIG_MTD_NAND_VERIFY_WRITE
drivers/mtd/nand/nand_base.cnand_write_page函數(shù)
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
        /* Send command to read back the data */
        chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
        if (chip->verify_buf(mtd, buf, mtd->writesize))
                return -EIO;
#endif

未完待續(xù)。。。。。。


作者: 摩斯電碼    時間: 2014-06-30 09:25
本帖最后由 摩斯電碼 于 2014-06-30 09:33 編輯

一、 最后
最后可以將malloc區(qū)域的大小重新改成4M+160KB,修改tq2440.h
#define CONFIG_SYS_MALLOC_LEN        (2 * 1024 * 1024)
改為:
#define CONFIG_SYS_MALLOC_LEN        (4 * 1024 * 1024)
重新編譯,下載運行,正常。

二、 制作補丁
進入將剛才移植好的u-boot-2014.04頂層目錄,執(zhí)行如下命令
pengdl@debian:~/work/tq2440$ mv u-boot-2014.04 u-boot-2014.04_tq2440_god_v2
pengdl@debian:~/work/tq2440$ cd u-boot-2014.04_tq2440_god_v2
pengdl@debian:~/work/tq2440/u-boot-2014.04_tq2440_god_v2$ make distclean
解壓未修改過的
pengdl@debian:~/work/tq2440$ tar -xjf u-boot-2014.04.tar.bz2
制作補丁
pengdl@debian:~/work/tq2440$ diff -urwNB u-boot-2014.04 u-boot-2014.04_tq2440_god_v2/ > u-boot-2014.04_tq2440_v2.patch
打補丁
進入未修改的u-boot-2014.04源碼目錄
pengdl@debian:~/work/tq2440/u-boot-2014.04$ patch -p1 < ../u-boot-2014.04_tq2440_v2.patch
pengdl@debian:~/work/tq2440/u-boot-2014.04$ make tq2440_config
pengdl@debian:~/work/tq2440/u-boot-2014.04$ make
三、 用到的一些命令:
NorFlash中燒寫uboot:
protect off all
tftp 0x30000000 u-boot.bin
erase 0 +40000
cp.b 0x30000000 0x0 0x40000
NandFlash中燒寫uboot
tftp 0x30000000 u-boot.bin
nand erase.part u-boot   
#前提是在tq2440中做了配置:
#define MTDIDS_DEFAULT        "nand0=tq2440-0"
#define MTDPARTS_DEFAULT        "mtdparts=tq2440-0:1m(u-boot),"        \
                                                "1m(params),"                \
                                                "3m(kernel),"        \
                                                "-(rootfs)"
#參見第七步
nand write 0x30000000 u-boot 0x40000
NandFlash中燒寫內(nèi)核:
tftp 0x30000000 uImage
nand erase.part kernel
nand write 0x30000000 kernel 0x300000
NandFlash中燒寫yaffs格式的rootfs
tftp 0x30000000 root.bin
nand erase.part rootfs
nand write.yaffs 0x30000000 rootfs $filesize


最后,附上移植文檔和patch

移植文檔

u-boot-2014.04移植手冊(TQ2440).pdf (509.33 KB, 下載次數(shù): 2215)

patch

u-boot-2014.04_tq2440_v2.rar (10.66 KB, 下載次數(shù): 89)


另外一篇移植文檔和補丁,可以與上面的一篇相互參考:

移植文檔

uboot_2014_04移植到tq2440.pdf (1.84 MB, 下載次數(shù): 250)

patch

u-boot-2014.04_tq2440.rar (10.17 KB, 下載次數(shù): 79)




作者: Xrz369    時間: 2014-07-11 17:16
mark一下,正想學習
作者: soilfish    時間: 2014-07-31 09:29
  算是堅持看完 很好  恢常支持樓豬
作者: hgy_259    時間: 2014-08-11 13:50
我移植到u-boot-2014.07到j(luò)z2440,在支持nand flash讀寫的那部分,nand read出現(xiàn)錯誤,怎么改?

nand讀出錯.jpg (16.71 KB, 下載次數(shù): 86)

nand讀出錯.jpg

作者: jwnydy    時間: 2014-08-20 16:15
怒贊,圍觀中。。。。
作者: M_O_Bz    時間: 2014-09-13 01:33
在crt0.S中都沒有初始化nand flash啊怎么可能從nand flash 啟動?樓主漏了啊
作者: M_O_Bz    時間: 2014-09-13 18:18
參考了你寫的帖子,我把最新的uboot(u-boot-2014.07)移植到了mini2440上,補丁在下面連接,有需要的朋友可以參考下。
https://github.com/54shady/u-boot-2014.07/tree/master
作者: zhj1011    時間: 2014-09-18 17:22
寫的不錯,很詳細   
作者: 摩斯電碼    時間: 2014-11-02 23:04
回復 14# M_O_Bz


    在copy_code_to_sdram函數(shù)中有nand_init_ll();
作者: fulinux    時間: 2014-11-08 15:55
加載地址弄的太小了,設(shè)置的是0x3200000,而malloc分配的區(qū)域是在代碼下面的,而SDRAM的起始地址就是0x30000000,所以就會出現(xiàn)問題。
作者: kozmers    時間: 2015-01-01 22:54
告別詳細,收藏了
作者: denggww123    時間: 2015-02-28 17:35
頂一下 你好




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2