Ubifs is successfully transplanted to dm368.

Source: Internet
Author: User

I am using TI's dm368 Development Board. The kernel is 2.6.32.17, and the default FLASH file system is jffs2. However, jffs2 is in a large partition, and the Mount speed is very slow and occupies a large amount of Ram. Therefore, I want to use ubifs to see if the performance is better.

The principles and configuration process of ubifs are introduced on many web pages. I will provide a link for you to see. I will not repost it, I will focus on the problems I encountered and solved during the transplantation process.

Http://bbs.chinaunix.net/thread-1954881-1-1.html

 

The configuration of kerne is very simple. It is available in 2.6.32 and can be selected and re-compiled.

Ubiattach, ubimkvol, and other tools are provided by TI's dvsdk. If they can be used, I am a lazy user and have not re-compiled.

 

It's easy to follow the instructions on the webpage. The Mount partition is successful, and the file is copied. I'm glad to know that :)

Ubiattach/dev/ubi_ctrl-M 3

Ubimkvol/dev/ubi0-N rootfs-s 480mib

Mount-T ubifs ubi0_0/mnt/NAND/-O sync

But soon I got into trouble. After the Development Board was shut down and restarted, I encountered an error in the mout ubi file system, prompting a bunch of errors and the partition was empty, the copied file is missing.

The problem is as follows:

Ubiattach/dev/ubi_ctrl-M 3

UBI error: ubi_io_read: Error-74 while reading 64 bytes from peb 1662: 0, read 64 bytes

UBI error: ubi_io_read: Error-74 while reading 64 bytes from peb 1663: 0, read 64 bytes

 

To analyze the problem, I opened both MTD and ubifs's debug log and saw some information;

# Define ebadmsg 74/* not a data message */

/* NAND returns-ebadmsg on ECC errors, but it returns

* The data. For our userspace tools it isimportant

* To dump areas with ECC errors!

* For kernel internal usage it also mightreturn-euclean

* To signal the caller that a bitflip hasoccured and has

* Been corrected by the ECC algorithm.

* Userspace software which accesses NAND thisway

* Must be aware of the fact that it deals withnand

*/

Nand_do_read_ops

Stats = MTD-> ecc_stats;

If (MTD-> ecc_stats.failed-stats. Failed)

Return-ebadmsg;

Nand_read_page_hwecc

Stat = chip-> ECC. Correct (MTD, P, & ecc_code [I], & ecc_calc [I]);

If (STAT <0)

MTD-> ecc_stats.failed ++;

Else

MTD-> ecc_stats.corrected + = Stat;

It seems that an ECC error has occurred, but I use hardware ECC verification. How can I see an ECC verification error in almost all pages?

 

Root @ dm368-evm :~ # Flash_eraseall/dev/mtd3

Root @ dm368-evm :~ # Ubiattach/dev/ubi_ctrl-M 3

UBI: attaching mtd3 to ubi0

UBI: Physical eraseblock size: 131072 bytes (128 kib)

UBI: Logical eraseblock size: 129024 bytes

UBI: smallest flash I/O unit: 2048

UBI: Sub-page size: 512

UBI: vid header offset: 512 (aligned 512)

UBI: Data offset: 2048

 

Analyze the ubi Data Writing Process,

UBI dbg (PID 1484): ubi_io_write: Write 512 bytes to peb 57: 0

Int ubi_io_write (struct ubi_device * ubi, const void * Buf, int pnum, int offset,

Int Len)

ADDR = (loff_t) pnum * ubi-> peb_size + offset;

Err = ubi-> MTD-> write (UBI-> MTD, ADDR, Len, & written, Buf );

In the io_init function, you can see the values of several variables;

UBI-> peb_size = ubi-> MTD-> erasesize;

UBI-> peb_count = mtd_div_by_eb (UBI-> MTD-> size, ubi-> MTD );

UBI-> flash_size = ubi-> MTD-> size;

From the debug log, 512 bytes are written here, starting from the starting page of a block, and the offset is 0;

Then the underlying driver of the nand mtd performs the following actions;

Nand_write-> nand_do_write_ops:

Subpage = column | (writelen & (MTD-> writesize-1 ));

Here, the subpage is writelen, 512;

We can also know that ubifs does not use OOB, which is different from jffs2 and yaffs2;

/* Partial page write? */

If (unlikely (column | writelen <(MTD-> writesize-1 ))){

Cached = 0;

Bytes = min_t (INT, bytes-column, (INT) writelen );

Chip-> pagebuf =-1;

Memset (chip-> buffers-> databuf, 0xff, MTD-> writesize );

Memcpy (& Chip-> buffers-> databuf [column], Buf, bytes );

Wbuf = chip-> buffers-> databuf;

}

Ret = chip-> write_page (MTD, Chip, wbuf, page, cached,

(OPS-> mode = mtd_oob_raw ));

The code for the write_page function is as follows;

Static int nand_write_page (structmtd_info * MTD, struct nand_chip * chip,

Const uint8_t * Buf, int page, int cached, int raw)

{

Intstatus;

 

Chip-> sort func (MTD, nand_sort _seqin, 0x00, page );

 

If (unlikely (raw ))

Chip-> ECC. write_page_raw (MTD, Chip, Buf );

Else

Chip-> ECC. write_page (MTD, Chip, Buf );

 

/*

* Cached progamming disabled for now, not sureif its worth

* Trouble. The speed gain is not veryimpressive. (2.3-> 2.6mib/s)

*/

Cached = 0;

Note that raw is used. If mtd_oob_raw is used, ECC verification is not performed and the ECC code is not written to OOB;

In this case, you must specify mtd_oob_raw during read without ECC verification. Otherwise, the error we first saw will appear;

If (MTD-> ecc_stats.failed-stats. Failed)

Return-ebadmsg;

 

In this case, we may have found the cause of the Error. ubi uses subpage write, while the underlying NAND Flash driver does not actually support subpage write, although ubi only writes 512 bytes at a time, other parts of the page cannot write new data again.

 

From the perspective of nand_base.c (Drivers \ MTD \ NAND), large page's NAND Flash does not fully support subpage write and has many restrictions. For example, it cannot be the NAND flash of MLC or the hardware ECC;

The more serious problem is that the Code has a defect. When writing some data, fill the data in other parts with 0xff, write the entire page, and write all the ECC codes to OOB, maybe this is the cause of an error in the ECC verification.

Nand_do_write_ops ()

/* Partial page write? */

Memset (chip-> buffers-> databuf, 0xff, MTD-> writesize );

Memcpy (& Chip-> buffers-> databuf [column], Buf, bytes );

Therefore, the solution I came up with is to disable subpage write in the NAND driver.

Step 1: Add nand_no_subpage_write in chip options;

Static struct davinci_nand_pdatadavinci_nand_data = {

. Options = nand_use_flash_bbt | nand_no_subpage_write,

Then re-compile and download the kernel, but the problem persists;

Root @ dm368-evm :~ # Ubiattach/dev/ubi_ctrl-M 3

UBI: attaching mtd3 to ubi0

UBI: Physical eraseblock size: 131072 bytes (128 kib)

UBI: Logical eraseblock size: 129024 bytes

UBI: smallest flash I/O unit: 2048

UBI: Sub-page size: 512

UBI: vid header offset: 512 (aligned 512)

I wonder why the Sub-page size is still 512?

Check the code to see how the sub page size is calculated,

If (! (Chip-> options & nand_no_subpage_write )&&
! (Chip-> cellinfo & nand_ci_celltype_msk )){
Switch (chip-> ECC. Steps ){
Case 2:
MTD-> subpage_sft = 1;
Break;
Case 4:
Case 8:
Case 16:
MTD-> subpage_sft = 2;
Break;
}
}
Chip-> subpagesize = MTD-> writesize> MTD-> subpage_sft;

But I have added nand_no_subpage_write to options? I have some doubts. I have added a print log here. It is indeed a problem here,

Chip-> Options = 0x10101.

MTD-> subpage_sft = 0.

Chip-> subpagesize = 512.

 

# Define nand_no_subpage_write 0x00000200

However, the options here is obviously incorrect! So where is the nand_no_subpage_write I set lost?

 

The following function changes the value of chip-> options;

Nand_get_flash_type ()

Printk (kern_info "nand_get_flash_type 1, chip-> Options = 0x % x. \ n", chip-> options );

 

/* Get chip options, preserve non-Chip Based Options */

Chip-> options & = ~ Nand_chipoptions_msk;

Printk (kern_info "nand_get_flash_type 2, chip-> Options = 0x % x. \ n", chip-> options );

Chip-> options | = type-> options & nand_chipoptions_msk;

Printk (kern_info "nand_get_flash_type 3, chip-> Options = 0x % x. \ n", chip-> options );

 

/*

* Set chip as a default. Board drivers canoverride it, if necessary

*/

Chip-> options | = nand_no_autoincr;

 

/* Check if chip is a not a Samsung device. Do not clear

* Options for chips which are not having anextended ID.

*/

If (* maf_id! = Nand_mfr_samsung &&! Type-> pagesize)

Chip-> options & = ~ Nand_samsung_lp_options;

Printk (kern_info "nand_get_flash_type 4, chip-> Options = 0x % x. \ n", chip-> options );

 

Nand_get_flash_type 1, chip-> Options = 0x10200.

Nand_get_flash_type 2, chip-> Options = 0x10000.

Nand_get_flash_type 3, chip-> Options = 0x1011c.

Nand_get_flash_type 4, chip-> Options = 0x10101.

 

The problem is here, the red code!

/* Mask to zero out thechip options, which come from the ID table */

# Definenand_chipoptions_msk (0x0000ffff &~ Nand_no_autoincr)

/* Chip can not autoincrement pages */

# Define nand_no_autoincr 0x00000001

 

After finding the problem, the solution will be available. comment out the red line of code, that is, it will discard nand_no_subpage_write.

// Chip-> options & = ~ Nand_chipoptions_msk;

Re-compile and download the kernel. The problem is fixed!

Start the Development Board again and load ubi. Everything is normal.

Root @ dm368-evm:/# ubiattach/dev/ubi_ctrl-M 3

UBI: attaching mtd3 to ubi0

UBI: Physical eraseblock size: 131072 bytes (128 kib)

UBI: Logical eraseblock size: 126976 bytes

UBI: smallest flash I/O unit: 2048

UBI: vid header offset: 2048 (aligned 2048)

UBI: Data offset: 4096

UBI: attached mtd3 to ubi0

UBI: MTD device name: "filesystem1"

UBI: MTD device size: 512 MIB

UBI: Number of good pebs: 4096

UBI: Number of bad pebs: 0

UBI: Max. allowed volume: 128

UBI: Wear-leveling threshold: 4096

UBI: number of internal volumes: 1

UBI: number of user volumes: 1

UBI: available pebs: 3639

UBI: Total number of FIG: 457

UBI: Number of pebs reserved for badpeb handling: 40

UBI: Max/mean erase counter: 2/1

UBI: Image Sequence Number: 0

UBI: Background thread "ubi_bgt0d" started, PID 1483

UBI device number 0, total 4096 lebs (520093696 bytes, 496.0 MIB), available 3639 lebs (462065664 bytes, 440.7 MIB), Leb size 126976 bytes (124.0 kib)

 

Root @ dm368-evm:/# Mount-tubifs Ubian 0_0/mnt/NAND/-O sync

Ubifs: mounted ubi device 0, volume0, name "rootfs"

Ubifs: file system size: 51171328 bytes (49972 kib, 48 MiB, 403 lebs)

Ubifs: Journal size: 2539520 bytes (2480 kib, 2 MiB, 20 lebs)

Ubifs: Media Format: W4/R0 (latest is W4/R0)

Ubifs: Default Compressor: lzo

Ubifs: reserved for root: 2416947 bytes (2360 kib)

Root @ dm368-evm:/# DF

Filesystem 1k-blocks used available use % mounted on

/Dev/root 39544232 16239820 21295632 43%/

None 1024 24 1000 2%/dev

Tmpfs 16384 20 16364 0%/var/volatile

Tmpfs 21760 0 21760 0%/dev/SHM

Tmpfs 16384 0 16384 0%/Media/Ram

Ubi0_0 45528 1528 41640 4%/mnt/Nand

 

Finally, we need to disable the subpage write in the NAND Flash Driver so that chip-> subpagesize = MTD-> writesize can be used.

This is my solution. If you want to use subpage write, make sure that your read/write logic is correct. Either you do not need ECC or the ECC of each subpage should be correct.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.