mtd_info->size again (lengthy)
Bruce_Leonard at selinc.com
Bruce_Leonard at selinc.com
Sun Jun 8 01:38:21 EDT 2008
There's been some chatter on the list in the last couple of months (mostly
by me) about the limit on MTD devices of no more than 2GiB because struct
mtd_info->size is a 32-bit value. A few weeks ago I asked for ideas on
how to get around this limit, the most popular on being that I should
change the meaning of mtd_info->size from "the size of the device in
bytes" to "the size of the device in kilobytes". I took the suggestion to
heart and when I started working on this last week, that was the direction
I took. Now I'm in deep trouble. I'm having multiple problems with this
solution.
A quick grep of mtd->info turns up on the order of 225 hits in various and
assorted drivers and core code, not counting other structures that have an
mtd_info buried inside them. A lot of those hits are simple things like
"if(off + len > mtd->info)". So if I change the meaning of mtd_info->size
to KiB, then I have to change everyplace that touches/checkes/uses
mtd_info->size to use KiB. A duanting task, especially as there are other
places where the value of mtd_info->size is used to initialize other
structures (JFFS2 leeps to mind). Would I then have to go through those
other places and ripple the change in meaning there as well? This idea
was getting out of hand in a hurry.
So I stepped back and rethought this. Maybe just leaving the meaning as
bytes and changing the type to 64-bits wasn't such a bad idea after all.
As I said, a sizable percentage of the 225 hits are simple compares, the
compiler would take care of my problem by promotion. Plus places like the
NAND layer that does calculations by shifting mtd_info->size could safely
be left alone. However, I'm still left with the problem of ripple effect
into other layers like JFFS2 and some of the MTD map files.
Plus I run into this problem with making it a 64-bit value: there are a
few places (add_mtd_device() for example) where mtd_info->size is passed
as a parameter of type size_t, which in my case on an mpc8347 is a 32-bit
value. This is where I really start to get bogged down. size_t (please
correct me if I'm wrong because I probably am) is defined to be a type
that will tell you the largest item (in bytes) that can be accessed by
that particular processor. In other words, the biggest structure you
could access in the RAM on the local bus of an mpc8347 would be 4GiB, or
0x0 - 0xffffffff, a 32-bit value, and thus size_t on an 8347 is defined to
be an unsigned long. That makes my poor little HW engineer brain hurt,
though I think I get it. But wait....now I have 8GiB of NAND flash,
connected to a PCI controller, handled by a single PCI driver and thus
presented to the kernel as a single item, 8GiB in size which doesn't fit
in size_t. So now, my call to mtd->unlock() in the function
add_mtd_device() passes a length of 0 because mtd->size gets truncated to
32-bits! Ouch, my poor little HW engineer brain just had an aneurysm :(.
We then thought, why don't we just break the NAND controller up into four
controllers (we can do that becuase we rolled our own in an FPGA) with
2GiB of flash on each controller. Then we can just concatenate the four
together in the MTD layer. Great idea. Not! Same problem. When you
concatenate devices together in MTD, each devices size gets added to
mtd_info->size, and again I've overflowed my 32-bit size.
Then we thought, okay just have four 2GiB devices on /dev/mtd0-3. After
all, we can mount as much stuff on the root directory as we want. Except
my SW folks are telling me that, due to archiving requirements we will
probably end up with sub-directories in excess of 2GiB which will make
file management a real nightmare. Well, fine, so I'm back to trying to
get the MTD layer to support >2GiB devices. And to be honest, I really
believe it's the best solution for all. As flash densities continue to
grow, I think there are going to be more and more embedded designs where
using Compact Flash or some other SSD hidden behind an IDE interface is
not going to be acceptible. This is a good thing to change and now is a
good time.
But folks, I'm stuck. I'm just a dumb HW engineer trying to get my box
running. I'm willing to make the change and I want to make the change,
but I need help. I hate asking, I know that the etiquette on the lists
frowns on asking for specific help. And usually after a few days of
poking I can come up with my own solution. It's not pretty but it works
:). But right now I'm totally lost in the subtle complexeties and the
shear size of MTD. It's way beyond me. What I need is a concrete code
example from someone on what and how to go about expanding MTD to support
large sizes. Can someone please help me out? If I can get a good solid
idea of how to fix it, I'm more than happy to do the work of making all
the code changes and putting together a patch. The open source community
has been good to me and I'd love nothing more than being able to
contribute something back.
Thanks for listening.
Bruce
More information about the linux-mtd
mailing list