介紹
1 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
| Flash Device = N Block Blocl = N Page Page = N Byte + OOB
Nand Flash +-------------------------------------+ | B1 | B2 | ... | B16 | | | | | | +-------------------------------------+
+----+ | B1 | => N Page + OOB | | +----+
Page 大小有 512, 2048, 4096, 8192 (bytes),常見的為 2048 (bytes) page 容量 512 bytes 的稱 small page,大於等2k bytes 都稱為large page
Spare or OOB (out of boundary) 每一個 page 在實體的結構中除了 2k bytes的使用空間,還會有 64 bytes 額外的容量 供hw/sw儲存一些額外的資訊,通常會用來儲存ecc的data,來效正nand flash使用久後會有bit不能使用的問題
Block nand flash chip 寫入的最小單位, 每 64 page 即為一個block 因為 page size 會有不同,block size 也就不同 一顆chip裡有多少block,是依nand flash的大小而定,但通常是 2 的冪次方。
Read/Write operation nand flash 讀寫方式異於一般的磁性儲性裝置。因為結構上的問題 如果要針對特定的 page 寫入,只能把資料寫由1 -> 0, 如果要0->1 那只能針對整個 block (64 pages)做動作,此動作稱為 erase,而寫入page的動作稱為 program, 一般 nand chip 的資料都會標明erase/program的時間 以 Micro MT29F2G08AABWP 為例,erase/program的時間分別為(2ms/300us)
|
比較檔案相關指令
1 2
| hexdump -C A.bin | head -n 10
|
建立 UBI images
流程: 1.使用 mkfs.ubifs 製作 ubifs 格式 2.將第一步的檔案做成可燒錄的 image
1.進入 Linux 使用 mtdinfo 看資訊
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| mtdinfo /dev/mtd-open -u mtd6 Name: mtd-name Type: nand Eraseblock size: 1048576 bytes, 1024.0 KiB Amount of eraseblocks: 4018 (4213178368 bytes, 3.9 GiB) Minimum input/output unit size: 8192 bytes Sub-page size: 8192 bytes OOB size: 256 bytes Character device major/minor: 90:12 Bad blocks are allowed: true Device is writable: true Default UBI VID header offset: 8192 Default UBI data offset: 16384 Default UBI LEB size: 1032192 bytes, 1008.0 KiB Maximum UBI volumes count: 128
|
2.由 mtdinfo 得知 mkfs.ubifs 資訊
1 2 3 4 5 6
| mkfs.ubifs -v -r ubifs -m 8192 -e 1032192 -c 4018 -o ubifs.img
|
- UBI generieren
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ubinize -vv -o output/ubi.img -m 8192 -p 1024KiB config.ini
[ubifs_volume] mode=ubi image=ubifs.img vol_id=1 vol_size=4071MiB vol_type=dynamic vol_name=fs vol_alignment=1 vol_flags=autoresize
|
ubinize 會讀 2 個檔案進去,config.ini , ubifs.img
Linux
1 2 3 4 5 6
| tftp -gr ubi-4g.img 192.168.1.2 ubidetach -d 0 /dev/ubi_ctrl ubiformat /dev/mtd6 -f ubifs.img ubiattach /dev/ubi_ctrl -m 6 mkdir userfs mount -t ubifs /dev/ubi0_0 ./userfs/
|
Uboot
1 2 3 4
| tftpboot ubi.img nand write 0x68000000 0x4e00000 $filesize ubi part nand0,6 0 ubifsmount open
|
Error
1 2 3 4 5
| Q:UBI error: vtbl_check: too large reserved_pebs 4064, good PEBs 4010 A:vol_size 太大,要調小
Q:ubi_read_volume_table A:把 config.ini 裡面的 vol_alignment=1 & vol_flags=autoresize 移除
|
Read / Write
Read
1 2 3 4 5 6 7
| 先用 mtdinfo /dev/mtd7 找出要讀的 part (看 mtd name) 或是 cat /proc/mtd dev: size erasesize name mtd0: 000a0000 00010000 "boot" mtd1: 00060000 00010000 "env" ... 再用 nanddump -p -f nandinfo.txt /dev/mtd7 將內容讀到 nandinfo.txt 檔案
|
Write
1 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
| #include <stdio.h> #include <fcntl.h> #include <sys/ioctl.h> #include <mtd/mtd-user.h>
#define MTD_NAME "mtd7" #define TMP_NAME "tmp.txt" int main() { FILE *fp; int rv = 0; char sys_cmd[80]; char data[80] = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB}; // Erase nand flash sprintf(sys_cmd, "flash_erase /dev/%s 0 0", MTD_NAME); rv = system(sys_cmd); if (rv) { printf("ERROR : Flash erase !\n"); } // Open file and write data fp = fopen(TMP_NAME, "wb"); fwrite(data, sizeof(data[0]), sizeof(data)/sizeof(data[0]), fp); fclose(fp);
// Write to nand sprintf(sys_cmd, "nandwrite -p -s 0 /dev/%s %s", MTD_NAME,TMP_NAME); system(sys_cmd); return 0; }
|
參考網站
Reference 1
Reference 2
Reference 3
Reference 4
Reference 5
Reference 6