為AM335x移植Linux內核主線代碼(7)使用SD卡中的U-Boot操作NAND Flash

ARM 473瀏覽

使用OK335xD核心板上的NAND Flash,無論是速度還是穩定性,都比SD卡好,所以接下來的任務是使用SD中的U-Boot操作NAND Flash,把需要的鏡像燒錄進去之后,就可以從NAND Flash啟動了!

第一步:按照《U-Boot for AM335x》的步驟準備好:
OK335x開發板
按照TI公司官方文檔的要求,格式化的SD卡(create-sdcard.sh)
準備一份編譯通過的可用的U-Boot源代碼(uart/mmc0/eth/gpio/i2c功能)
uImage和文件系統鏡像

第二步:修改U-Boot源代碼中mux部分:
static struct module_pin_mux nand_pin_mux[] = {
{OFFSET(gpmc_ad0),????? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_ad1),????? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_ad2),????? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_ad3),????? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_ad4),????? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_ad5),????? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_ad6),????? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_ad7),????? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_wait0),??? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_wpn),????? MODE(0) | PULLUP_EN | RXACTIVE},
{OFFSET(gpmc_csn0),???? MODE(0) | PULLUP_EN},
{OFFSET(gpmc_oen_ren),? MODE(0) | PULLUP_EN},
{OFFSET(gpmc_wen),????? MODE(0) | PULLUP_EN},
{OFFSET(gpmc_be0n_cle), MODE(0) | PULLUP_EN},
{-1},
};

別忘了執行下面這句:
configure_module_pin_mux(nand_pin_mux);

第三步:在U-Boot源代碼中board_init函數中添加:
gpmc_init();

第四步:在include/configs/maria_am335x.h中添加:
#define CONFIG_CMD_NAND
#define CONFIG_SYS_MAX_NAND_DEVICE????? 1
#define CONFIG_SYS_NAND_BASE??????????? 0x800000

#define CONFIG_NAND_OMAP_GPMC
#define CONFIG_NAND_OMAP_ELM
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#define CONFIG_SYS_NAND_PAGE_COUNT????? (CONFIG_SYS_NAND_BLOCK_SIZE /
CONFIG_SYS_NAND_PAGE_SIZE)
#define CONFIG_SYS_NAND_PAGE_SIZE?????? 2048
#define CONFIG_SYS_NAND_OOBSIZE???????? 64
#define CONFIG_SYS_NAND_BLOCK_SIZE????? (128*1024)
#define CONFIG_SYS_NAND_BAD_BLOCK_POS?? NAND_LARGE_BADBLOCK_POS
#define CONFIG_SYS_NAND_ECCPOS????????? { 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 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, }

#define CONFIG_SYS_NAND_ECCSIZE???????? 512
#define CONFIG_SYS_NAND_ECCBYTES??????? 14
#define CONFIG_SYS_NAND_ONFI_DETECTION
#define CONFIG_NAND_OMAP_ECCSCHEME????? OMAP_ECC_BCH8_CODE_HW
#define CONFIG_SYS_NAND_U_BOOT_START??? CONFIG_SYS_TEXT_BASE
#define CONFIG_SYS_NAND_U_BOOT_OFFS???? 0x80000

為什么不直接只用CONFIG_NAND,這些宏不就跟著定義了嗎?
因為CONFIG_NAND的含義是從NAND啟動,而這里只是要對NAND Flash進行讀取和燒寫操作,booting設備還是SD卡。

第五步:修改arch/arm/cpu/armv7/am33xx/mem.c中的"gpmc_init"函數:
void gpmc_init(void)
{
gpmc_cfg = (struct gpmc *)GPMC_BASE;
const u32? gpmc_regs[GPMC_MAX_REG] = {? M_NAND_GPMC_CONFIG1,
M_NAND_GPMC_CONFIG2,
M_NAND_GPMC_CONFIG3,
M_NAND_GPMC_CONFIG4,
M_NAND_GPMC_CONFIG5,
M_NAND_GPMC_CONFIG6,
0
};
u32 size = GPMC_SIZE_256M;
u32 base = CONFIG_SYS_NAND_BASE;

writel(0x00000008, &gpmc_cfg->sysconfig);
writel(0x00000000, &gpmc_cfg->irqstatus);
writel(0x00000000, &gpmc_cfg->irqenable);
writel(0x00000012, &gpmc_cfg->config);

writel(0, &gpmc_cfg->cs[0].config7);
sdelay(1000);

enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
}

這是因為gpmc_init依賴于CONFIG_NAND,要不然基本不干活,因此去掉它的宏判斷。

第六步:編譯它:
make ARCH=arm CROSS_COMPILE=/opt/arm-arago-linux-gcc/usr/bin/arm-linux-gnueabihf- -j8 O=../build maria_am335x_config
make ARCH=arm CROSS_COMPILE=/opt/arm-arago-linux-gcc/usr/bin/arm-linux-gnueabihf- -j8 O=../build all

第七步:將生成的MLO和u-boot.img放置到SD卡中:
cp ../build/MLO ../build/u-boot.img /run/media/maria/boot/

第八步:開發板插入SD卡,設置為從SD卡啟動,上電。
在命令提示符下輸入:
U-Boot# set ipaddr 192.168.1.117
U-Boot# set serverip 192.168.1.116

U-Boot# tftp 0x82000000 MLO
U-Boot# nand erase 0x0 0x20000
U-Boot# nand write.i 0x82000000 0x0 0x20000

U-Boot# tftp 0x82000000 u-boot.img
U-Boot# nand erase 0x80000 0x40000
U-Boot# nand write.i 0x82000000 0x80000 0x40000

這些命令的含義是,從tftp服務器上獲取MLO和u-boot.img,存放在SDRAM的0x82000000處,并分別燒寫在NAND Flash的0x0和0x80000地址。拔除SD卡,重新上電,就能看到U-Boot從NAND Flash啟動的串口打印信息了!

NOTICE: 存放在tftp上的MLO和u-boot.img不能是Forlinx光盤里面的鏡像,也不是上面所述的這個,而是需要使用全新的源代碼重新編譯。因為Forlinx和這里的MLO和u-boot.img都是從SD卡啟動的,全新編譯出來的應該是從NAND Flash啟動。參照boards.cfg文件!

現在,這張SD卡就相當于一個下載器了,可以使用它實現讀取和燒寫存儲器的功能,包括串口、SD卡和NAND Flash操作,這也說明,U-Boot的重要性,硬件開發絕對繞不開它!

王中王鉄算盘历史开奖记录