1. 程式人生 > >UBI映象的程式設計燒寫注意事項

UBI映象的程式設計燒寫注意事項

通過程式設計的方式往mtd裝置中燒寫ubifs的映象,需要注意兩點:1,擦除整個分割槽。注意:是擦除整個分割槽,而不是擦除要燒寫的資料位元組數!否則會導致ubiattach出錯!2,要忽略本block尾部的所有空頁(0xff的page),計算方法就是對每個要燒寫的block資料,從尾部開始計算0xFF位元組的數量,然後進行page對齊。/*min_io_size: page size.length: usually block sizereturn: actually real size to write, smaller than block size.*/static int ubi_calc_data_len(const int min_io_size, const void *buf, int length){ int i = 0; for (i = length - 1; i >= 0; i--) if (((const uint8_t *)buf)[i] != 0xFF) break; /* The resulting length must be aligned to the minimum flash I/O size */ length = ALIGNMENT(i + 1, min_io_size); return length;}=======================================================================================================參考:How UBI flasher should workThe following is a list of what the UBI flasher program has to do when erasing the flash or when flashing UBI images. First of all, scan the flash and collect the erase counters. Namely, it read the EC header from each PEB, check the CRC-32 checksum of the header, and save the erase counter in a RAM. It is not necessary to read VID headers. Bad PEBs should be skipped. Calculate average erase counter. It should be used for PEBs with corrupted or missing EC headers. Such PEBs may be there because of unclean reboots, but there shouldn't be too many of them. If the intention is to just erase the flash, then each PEB has to be erased and proper EC header has to be written at the beginning of the PEB. The EC header should contain incremented erase counter. Bad PEBs should be just skipped. For NAND flashes, in case of I/O errors while erasing or writing, the PEB should be marked as bad (see here for more information how UBI marks PEBs as bad). If the intention is to flash an UBI image, then the flasher should do the following for each non-bad PEB. Read the contents of this PEB from the UBI image (PEB size bytes) into a buffer. Stripe min. I/O units full of 0xFF bytes from the end of the buffer (the details are given below in this section). Erase the PEB. Change the EC header in the buffer - put the new erase counter value there and re-calculate the CRC-32 checksum. Write the buffer to the physical eraseblock. As usually, bad PEBs should be just skipped. And for NAND flashes, in case I/O errors while erasing or writing, the PEB should be marked as bad.In practice the input UBI image is usually shorter than the flash, so the flasher has to flash the used PEBs properly, and erase the unused PEBs properly.Note, when writing an UBI image, it does not matter where eraseblocks from the input UBI image will be written. For example, the first input eraseblock may be written to the first PEB, or to the second one, or to the last one.Also note, if you implement a flasher which writes UBI images at the production line, i.e., only once, then the flasher does not have to change EC headers of the input UBI image, because this is new flash and each PEB has zero erase counter anyway. This means the production line flasher may be simpler.If your UBI image contains UBIFS file system, and your flash is NAND, you may have to drop 0xFF bytes the end of input PEB data. This is very important, although not required for all NAND flashes. Sometimes a failure to do this may result in very unpleasant problems which might be difficult to debug later. So we recommend to always do this.The reason for this is that UBIFS treats NAND pages which contain only 0xFF bytes (let's refer them to as empty NAND pages) as free. For example, suppose the first NAND page of a PEB has some data, the second one is empty, the third one also has some data, the fourth one and the rest of NAND pages are empty as well. In this case UBIFS will treat all NAND pages starting from the fourth one as free, and will write data there. If the flasher program has already written 0xFF's to these pages, then any new UBIFS data will cause a second write. However, many NAND flashes require NAND pages to be written only once, even if the data contains only 0xFF bytes.To put it differently, writing 0xFF bytes may have side-effects. What the flasher has to do is to drop all empty NAND pages from the end of the PEB buffer before writing it. It is not necessary to drop all empty NAND pages, just the last ones. This means that the flasher does not have to scan whole buffer for 0xFF's. It is enough to scan the buffer from the end and stop on the first non-0xFF byte. This is much faster. Here is the code from UBI which does the right thing./** * calc_data_len - calculate how much real data are stored in a buffer. * @ubi: UBI device description object * @buf: a buffer with the contents of the physical eraseblock * @length: the buffer length * * This function calculates how much "real data" is stored in @buf and returns * the length. Continuous 0xFF bytes at the end of the buffer are not * considered as "real data". */int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf, int length){ int i; for (i = length - 1; i >= 0; i--) if (((const uint8_t *)buf)[i] != 0xFF) break; /* The resulting length must be aligned to the minimum flash I/O size */ length = ALIGN(i + 1, ubi->min_io_size); return length;}This function is called before writing the buf buffer to the PEB. The purpose of this function is to drop 0xFF's from the end and prevent the situation described above. The ubi->min_io_size is the minimal input/output unit size which is equivalent to NAND page size.