Hi all,
I had a go at hacking up a tool to copy sparse images to cards less wastefully (and hopefully faster) by only coping to the important data: See the src/fibcp.c here:
git://git.linaro.org/people/dmart/tools.git
It's used like this:
# fibcp image.bin /dev/<sdcard>
There are some caveats, most notably:
* You have to be root, since the tool relies on the FIBMAP ioctl. * The filesystem the image file is generated on must not "optmise" explicit writing of blocks of zeros by generating a sparse file. ext[2-4] should work; not sure about btrfs. * The image must be freshly generated via a loop mount (e.g., linaro-media-create --image_file ... copied, tar'd or gzip'd images won't work).
It works well enough that e2fsck passes after a writing an image to a card which was previously full of random data.
Anyway, it's there if anyone wants to play with it -- comments welcome.
Cheers ---Dave
On Wednesday 19 January 2011, Dave Martin wrote:
It works well enough that e2fsck passes after a writing an image to a card which was previously full of random data.
Anyway, it's there if anyone wants to play with it -- comments welcome.
* You write with a block size of just 4kb here, which is really suboptimal when talking to SD cards. The performance should be best if you write only aligned 64kb blocks or larger. In particular, it's faster to fill 64kb with zeros when writing just one non-zero byte than it is to skip the remaining space.
* At least for the output, I'd do O_DIRECT, since you don't care if the block device ends up in your page cage or not. For the input, you might want to mmap the image file into memory and do madvise(MADV_DONTNEED) on the data you have already written out, to evict it from your page cache.
* In the cases where we have an actual SD card reader, it would be really cool to use ioctl(BLKDISCARD) on the medium to erase it before writing to it. This has two effects: 1. For data you want to write immediately, the following write is faster, especially if you don't write 4MB at a time. 2. The card's wear levelling works much better if some of the space has been marked as erased. You know which parts are zero, so erasing them would be a signficant speedup for the life-time of the system. Note that some cards fill erased space with 0xff bytes, while others fill the card with 0x00. Erase does not work if you are dealing with a USB card reader.
* I'd like to see this program do a ioctl(HDIO_GETGEO) to verify that the partition is aligned. You should probably print a warning if the alignment of the ext3 partition is less than 4MB, and bail out if it is less than 64kb, as that is the point where it gets really slow.
Arnd
Hi,
On Wed, Jan 19, 2011 at 3:57 PM, Arnd Bergmann arnd@arndb.de wrote:
On Wednesday 19 January 2011, Dave Martin wrote:
It works well enough that e2fsck passes after a writing an image to a card which was previously full of random data.
Anyway, it's there if anyone wants to play with it -- comments welcome.
- You write with a block size of just 4kb here, which is really suboptimal
when talking to SD cards. The performance should be best if you write only aligned 64kb blocks or larger. In particular, it's faster to fill 64kb with zeros when writing just one non-zero byte than it is to skip the remaining space.
Good points -- initially I kept things very simple just to see if I got valid cards out. And it wasn't initially SD specific.
I guess it might wake sense to wait until your investigations are concluded and roll the results into a really good utiliy for writing images ... how close do you reckon you are to the end?
- At least for the output, I'd do O_DIRECT, since you don't care if the
block device ends up in your page cage or not. For the input, you might want to mmap the image file into memory and do madvise(MADV_DONTNEED) on the data you have already written out, to evict it from your page cache.
Both good ideas :)
- In the cases where we have an actual SD card reader, it would be really
cool to use ioctl(BLKDISCARD) on the medium to erase it before writing to it. This has two effects: 1. For data you want to write immediately, the following write is faster, especially if you don't write 4MB at a time. 2. The card's wear levelling works much better if some of the space has been marked as erased. You know which parts are zero, so erasing them would be a signficant speedup for the life-time of the system. Note that some cards fill erased space with 0xff bytes, while others fill the card with 0x00. Erase does not work if you are dealing with a USB card reader.
Sounds interesting ... does that only apply to SD cards, or does it work for other media? Does this work for card readers and flash storage on USB?
- I'd like to see this program do a ioctl(HDIO_GETGEO) to verify that the
partition is aligned. You should probably print a warning if the alignment of the ext3 partition is less than 4MB, and bail out if it is less than 64kb, as that is the point where it gets really slow.
Well, currently this just copies a whole image, with no knowledge of what partition layout (if any) is inside.
I may experiment with some changes, but patches are definitely welcome if you feel energetic :)
Cheers ---Dave
On Wednesday 19 January 2011, Dave Martin wrote:
Hi,
On Wed, Jan 19, 2011 at 3:57 PM, Arnd Bergmann arnd@arndb.de wrote:
On Wednesday 19 January 2011, Dave Martin wrote:
It works well enough that e2fsck passes after a writing an image to a card which was previously full of random data.
Anyway, it's there if anyone wants to play with it -- comments welcome.
- You write with a block size of just 4kb here, which is really suboptimal
when talking to SD cards. The performance should be best if you write only aligned 64kb blocks or larger. In particular, it's faster to fill 64kb with zeros when writing just one non-zero byte than it is to skip the remaining space.
Good points -- initially I kept things very simple just to see if I got valid cards out. And it wasn't initially SD specific.
I guess it might wake sense to wait until your investigations are concluded and roll the results into a really good utiliy for writing images ... how close do you reckon you are to the end?
My conclusions are pretty much complete now. There are a few things that I want to do to get a tool that anybody can run to find out the specific properties of a given card, in order to optimize for that. E.g. if you have one of the few cards that use a different AU size than 4 MB, you might want to do the erases on 4 MB boundary.
- In the cases where we have an actual SD card reader, it would be really
cool to use ioctl(BLKDISCARD) on the medium to erase it before writing to it. This has two effects:
- For data you want to write immediately, the following write is faster, especially if you don't write 4MB at a time.
- The card's wear levelling works much better if some of the space has been marked as erased. You know which parts are zero, so erasing them would be a signficant speedup for the life-time of the system.
Note that some cards fill erased space with 0xff bytes, while others fill the card with 0x00. Erase does not work if you are dealing with a USB card reader.
Sounds interesting ... does that only apply to SD cards, or does it work for other media? Does this work for card readers and flash storage on USB?
It will work for SDHC, eMMC version 4.41 or higher, and certain new ATA devices that support TRIM. There is currently no support for erase or trim in the USB mass storage spec, so it won't work there yet, although that may change in the future.
- I'd like to see this program do a ioctl(HDIO_GETGEO) to verify that the
partition is aligned. You should probably print a warning if the alignment of the ext3 partition is less than 4MB, and bail out if it is less than 64kb, as that is the point where it gets really slow.
Well, currently this just copies a whole image, with no knowledge of what partition layout (if any) is inside.
Ah, I see. You could run 'fdisk -l -u' on the image and parse that, but that would probably be a bit too much effort. You could however run ioctl(BLKRRPART) on the device after writing to it and then use HDIO_GETGEO to figure out if the partitions are aligned or not.
I may experiment with some changes, but patches are definitely welcome if you feel energetic :)
Ok, I'll think about it, I might at least do the erase and the partition alignment parts, since I've already spent time doing that for the code I was working on.
Arnd