comparison mpffs/Description @ 28:c9f7a4afccc9

Mokopir-FFS: verbal description finished
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 30 Jun 2013 04:15:00 +0000
parents 343b6b2f178b
children 86a494a5f2b0
comparison
equal deleted inserted replaced
27:343b6b2f178b 28:c9f7a4afccc9
58 and the exact binary byte content of all files contained therein. 58 and the exact binary byte content of all files contained therein.
59 59
60 However, the knowledge possessed by the present hacker (and conveyed in this 60 However, the knowledge possessed by the present hacker (and conveyed in this
61 document and the accompanying source code) is NOT sufficient for constructing a 61 document and the accompanying source code) is NOT sufficient for constructing a
62 valid Mokopir-FFS image "in vitro" given a tree of directories and files, or 62 valid Mokopir-FFS image "in vitro" given a tree of directories and files, or
63 for making modifications to the file or directory content on an existing image 63 for making modifications to the file or directory content of an existing image
64 and producing a content-modified image that is also valid; valid as in suitable 64 and producing a content-modified image that is also valid; valid as in suitable
65 for the original proprietary firmware to make its normal read and write 65 for the original proprietary firmware to make its normal read and write
66 operations without noticing anything amiss. 66 operations without noticing anything amiss.
67 67
68 Constructing "de novo" Mokopir-FFS images or modifying existing images in such 68 Constructing "de novo" Mokopir-FFS images or modifying existing images in such
69 a way that they remain 100% valid for all read and write operations of the 69 a way that they remain 100% valid for all read and write operations of the
70 original proprietary firmware would, at the very minimum, require an 70 original proprietary firmware would, at the very minimum, require an
71 understanding of the meaning of *all* fields on the on-media FFS format. Some 71 understanding of the meaning of *all* fields of the on-media FFS format. Some
72 of these fields are still left as "non-understood" for now though: a read-only 72 of these fields are still left as "non-understood" for now though: a read-only
73 implementation can get away with simply ignoring them, but a writer/generator 73 implementation can get away with simply ignoring them, but a writer/generator
74 would have to put *something* in those fields. 74 would have to put *something* in those fields.
75 75
76 As you read the "read-only" description of the Mokopir-FFS on-media format in 76 As you read the "read-only" description of the Mokopir-FFS on-media format in
228 name of the directory itself, padded with FFs to a 16-byte boundary. For 228 name of the directory itself, padded with FFs to a 16-byte boundary. For
229 example, an FFS directory named /gsm would be represented by an object 229 example, an FFS directory named /gsm would be represented by an object
230 consisting of two flash writes: a 16-byte entry in the active index block, with 230 consisting of two flash writes: a 16-byte entry in the active index block, with
231 the object type byte set to F2, and a corresponding 16-byte chunk in one of the 231 the object type byte set to F2, and a corresponding 16-byte chunk in one of the
232 data sectors, with the 16 bytes containing "gsm", a terminating NUL byte, and 232 data sectors, with the 16 bytes containing "gsm", a terminating NUL byte, and
233 12 FF bytes to pad up to 16. In the case of files, this name may be following 233 12 FF bytes to pad up to 16. In the case of files, this name may be followed
234 by the first chunk of file data content, as explained further down. 234 by the first chunk of file data content, as explained further down.
235 235
236 In order to parse the FFS directory tree (whether the objective is to dump the 236 In order to parse the FFS directory tree (whether the objective is to dump the
237 whole thing recursively or to find a specific file given a pathname), one needs 237 whole thing recursively or to find a specific file given a pathname), one needs
238 to first (well, after finding the active AB block) find the root directory node. 238 to first (well, after finding the active AB block) find the root directory node.
276 chunks to a new flash sector, invalidating the old copies - turning the latter 276 chunks to a new flash sector, invalidating the old copies - turning the latter
277 into deleted objects. The root node will be among them. Then at some point 277 into deleted objects. The root node will be among them. Then at some point
278 the active index block is going to fill up too, and will need to be rewritten 278 the active index block is going to fill up too, and will need to be rewritten
279 into a new sector - at which point the previously-deleted index entries are 279 into a new sector - at which point the previously-deleted index entries are
280 omitted and the root node becomes #1 again...] 280 omitted and the root node becomes #1 again...]
281
282 Tree structure
283
284 Once the root node has been found, the descendant and sibling pointers are used
285 to traverse the tree structure. For each directory object, including the root
286 node, the descendant pointer points to the first child object of this directory:
287 the first file or subdirectory contained therein. (Descendant and sibling
288 pointers take the form of index numbers in the active index block. A "nil"
289 pointer is indicated by all 1s (FFFF) - the usual all-0s NULL pointer convention
290 couldn't be used because it's flash, where the blank state is all 1s.) If the
291 descendant pointer of a directory object is nil, that means an empty directory.
292 The sibling pointer of each file or directory points to its next sibling, i.e.,
293 the next member of the same parent directory. The sibling pointer of the root
294 node is nil.
295
296 Data content of files
297
298 Objects of type F1 are the head chunks of files. Each file has a head chunk,
299 and may or may not have continuation chunks. More precisely, the head chunk
300 may contain only the name (or viewed alternatively, 0 bytes of data), or it may
301 contain a nonzero number of payload bytes; orthogonally to this variability,
302 there may or may not be continuation chunk(s) present.
303
304 Continuation chunks
305
306 The descendant pointer of each file head object (the object of type F1, the one
307 reached by traversing the directory tree) indicates whether or not there are
308 any continuation chunks present. If this descendant pointer is nil, there are
309 no continuation chunks; otherwise it points to the first continuation chunk
310 object. File continuation objects have type F4, don't have any siblings (the
311 sibling pointer is nil), and the descendant pointer of each continuation object
312 points to the next continuation object, if there is one - nil otherwise.
313
314 Payload data delineation
315
316 Each chunk, whether head or continuation, always has a length that is a nonzero
317 multiple of 16 bytes. The length of the chunk here means the amount of flash
318 space it occupies in its data sector - which is NOT equal to the payload data
319 length.
320
321 The head chunk of each file begins with the filename, terminated by a NUL byte.
322 If there are any payload data bytes present in this head chunk (I'll explain
323 momentarily how you would tell), the byte immediately after the NUL that
324 terminates the filename is the first byte of the payload. In the case of a
325 continuation chunk, there is no filename and the first byte of the chunk is the
326 first byte of that chunk's portion of the user data payload.
327
328 Each data-containing chunk (head or continuation) has the following termination
329 after the last byte of that chunk's payload data: one byte of 00, followed by
330 however many bytes are needed ([0,15] range) of FFs to pad to a 16-byte
331 boundary. A file head chunk that has no payload data has the same format as a
332 directory name chunk: filename followed by its terminating NUL followed by
333 [0,15] bytes of FFs to pad to the next 16-byte boundary.
334
335 When working with a head chunk, find the beginning of possible payload data (1
336 byte after the filename terminating NUL) and find the end per the standard
337 termination logic: scanning from the end of the chunk, skip FFs until 00 is
338 found (encountering anything else is an error). If the head chunk has no data,
339 the effective data length (end_pointer - start_pointer) will be 0 or -1. (The
340 latter possibility is the most likely, as there will normally be a "shared" 00
341 byte, serving as both the filename terminator and the 00 before the padding
342 FF bytes.)
343
344 -------------------------------------------------------------------------------
345
346 That's all I can think of right now. If anything is unclear, see the
347 accompanying source code for the listing/extraction utilities: with the general
348 explanation given by this document, it should be clear what my code does and
349 why. And if a given piece of knowledge is found neither in this document nor
350 in my source code, then I don't know it myself either, and my read-only
351 Mokopir-FFS implementation makes do without it.
352
353 All knowledge contained herein has been recovered by reverse engineering.
354 Believe it or not, I have figured it out by staring at the hex dump of FFS
355 sectors, reasoning about how one could possibly implement an FFS given the
356 requirement of dynamic writability and the physical constraints of flash memory,
357 and writing listing/extraction test code iteratively until I got something that
358 appears to correctly parse all FFS images available to me - the result is the
359 code in this package.
360
361 I never got as far as attempting to locate the FFS implementation routines
362 within the proprietary firmware binary code images, and I most certainly don't
363 have anything from TI that would help in this case. (The TSM30 code doesn't
364 seem to be of any use as its FFS appears to be totally different, and I haven't
365 looked at the FFS code in the more recently found LoCosto code leak because I
366 assumed from the documentation in the latter that the FFS implemented there is
367 different as well.)
368
369 Michael Spacefalcon
370 SE 52 Mes 11