FreeCalypso > hg > freecalypso-sw
comparison doc/TIFFS @ 227:1852900ce9ea
doc/TIFFS write-up
| author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
|---|---|
| date | Tue, 14 Jan 2014 02:31:09 +0000 |
| parents | 2900fe603f8a |
| children |
comparison
equal
deleted
inserted
replaced
| 226:4d706a4134b0 | 227:1852900ce9ea |
|---|---|
| 46 | 46 |
| 47 I am now making a naming transition from MPFFS to TIFFS: there is really no | 47 I am now making a naming transition from MPFFS to TIFFS: there is really no |
| 48 link between this FFS format and the Openmoko+Pirelli duo, other than the | 48 link between this FFS format and the Openmoko+Pirelli duo, other than the |
| 49 happenstance of me having first encountered this FFS on these two GSM device | 49 happenstance of me having first encountered this FFS on these two GSM device |
| 50 brands, and the name TIFFS is more neutrally-descriptive. | 50 brands, and the name TIFFS is more neutrally-descriptive. |
| 51 | |
| 52 What it is | |
| 53 ========== | |
| 54 | |
| 55 In a rare departure from TI's norm (most of TI's GSM firmware and associated | |
| 56 development tools suffer from heavy Windows poisoning), what I call TIFFS is | |
| 57 very Unixy. It is a file system with a hierarchical directory tree structure | |
| 58 and with Unixy forward-slash-separated, case-sensitive pathnames; the semantics | |
| 59 of "what is a file" and "what is a directory" are exactly the same as in UNIX; | |
| 60 and TIFFS even supports symlinks, although that support is a little under- | |
| 61 developed, and apparently no FFS symlinks were ever used in any production GSM | |
| 62 device. Thus the FFS implemented in TI-based GSM devices (modems and | |
| 63 "dumbphones") is really no different from, for example, JFFS2 in embedded Linux | |
| 64 systems. | |
| 65 | |
| 66 (The only traditional UNIX file system features which are missing in TIFFS are | |
| 67 the creation/modification/access timestamps and the ownership/permission | |
| 68 fields.) | |
| 69 | |
| 70 The FFS in a GSM device typically stores two kinds of content: | |
| 71 | |
| 72 * Factory data: IMEI, RF calibration values, device make/model/revision | |
| 73 ID strings etc. These files are expected to be programmed on the factory | |
| 74 production line and not changed afterward. | |
| 75 | |
| 76 * Dynamic data written into the FFS in normal device operation: when you use a | |
| 77 "dumbphone" running TI-based firmware, every time you store something "on the | |
| 78 phone" or in "non-volatile memory", that item is actually stored in the FFS. | |
| 79 (Where else, if you think of it?) That includes contacts and received SMS | |
| 80 stored "on the phone" instead of the SIM, any selections you make in the | |
| 81 settings/preferences menus which persist across reboots (power cycles), call | |
| 82 history etc. | |
| 83 | |
| 84 It needs to be noted that the "dynamic data" aspect of FFS usage applies not | |
| 85 only to complete phones, but also to modems like the one used in the GTA01/02. | |
| 86 One would naively think that non-volatile storage of data in flash outside of | |
| 87 factory programming would be needed only in a device with its own UI, and that | |
| 88 a modem subservient to external AT commands would be completely stateless | |
| 89 across reboot/power cycles; but that is not the case in actuality. TI's GSM | |
| 90 firmwares, including the Openmoko ones (the "standard" mokoN), are designed to | |
| 91 always "mount" their FFS with read/write access; TI's FFS implementation in the | |
| 92 firmware has no concept of a "read-only mount". | |
| 93 | |
| 94 I am still investigating just what kinds of data are routinely written into the | |
| 95 non-volatile FFS by the firmware in normal operation on devices like the GTA0x | |
| 96 modem, but there most definitely are some. | |
| 97 | |
| 98 There is no hard separation between "static" and "dynamic" data in the file | |
| 99 system structure; TIFFS is thus akin to an embedded Linux system with just a | |
| 100 single root file system containing both "static" files like userland binaries | |
| 101 and "dynamic" ones like configuration files under /etc which the user is | |
| 102 expected to edit with vi after logging into the box, or log and similar files | |
| 103 created by the system itself under /var, for example. | |
| 104 | |
| 105 Where it lives | |
| 106 ============== | |
| 107 | |
| 108 The type of flash memory used in Calypso GSM modems and "dumbphones" is called | |
| 109 NOR flash. This NOR flash memory is physically divided (by the design of the | |
| 110 flash chip itself) into units called "sectors" or more descriptively, erase | |
| 111 blocks. The typical NOR flash sector size (in Calypso GSM devices) ranges from | |
| 112 64 KiB in the GTA02 modem's NOR flash (4 MiB total) to 256 KiB in the | |
| 113 S71PL129NC0 flash+RAM chip used in the Pirelli DP-L10 (16 MiB of flash total). | |
| 114 The key physical property is that any bit may be changed from a '1' to a '0' at | |
| 115 any time, in any combination, but resetting of '0' bits back to ones can be | |
| 116 done only on the granularity of these largish sectors, in an operation called | |
| 117 "sector erase". | |
| 118 | |
| 119 The location of TIFFS within the flash memory of a given GSM device is defined | |
| 120 by the firmware design of that device, but is always some integral number of | |
| 121 contiguous flash sectors. Some examples: | |
| 122 | |
| 123 * On the GTA01/02 GSM modem, FFS occupies 7 sectors of 64 KiB each, starting at | |
| 124 flash offset 0x380000. | |
| 125 | |
| 126 * On the Pirelli DP-L10, the FFS used by the original proprietary fw occupies | |
| 127 18 sectors of 256 KiB each (for 4.5 MiB in total), starting at the beginning | |
| 128 of the 2nd flash chip select (0x02000000 in the ARM7 address space). | |
| 129 | |
| 130 * The smallest real FFS configuration called for by the table in dev.c in TI's | |
| 131 original Leonardo fw source is 3 sectors of 64 KiB each; the same table also | |
| 132 sports a 4 KiB x 4 configuration for RAM-based testing (emulation of FFS in | |
| 133 RAM without real flash). | |
| 134 | |
| 135 * The largest FFS configuration that has been envisioned by the original | |
| 136 designers seems to be somewhere around 128 sectors. | |
| 137 | |
| 138 Each flash sector used for TIFFS begins with this 6-byte signature: | |
| 139 | |
| 140 46 66 73 23 10 02 | |
| 141 | |
| 142 The first 4 bytes are 'Ffs#' in ASCII, and the following two bytes are the | |
| 143 format version number of 0x0210 in little-endian byte order. The following two | |
| 144 bytes give a count of how many times that sector has been erased and rewritten | |
| 145 (FF FF in "fresh" or "virgin" FFS images), and the following byte indicates | |
| 146 that block's role and status in the FFS life cycle. | |
| 147 | |
| 148 How it works | |
| 149 ============ | |
| 150 | |
| 151 Just like JFFS2 and other high-quality flash file systems, TIFFS is designed to | |
| 152 recover gracefully from any possible power failure or crash: one can yank the | |
| 153 battery from the GSM device (or induce a firmware crash) at the most mis- | |
| 154 opportune moment in the middle of an FFS write operation, and the FFS is | |
| 155 expected to recover on the next boot cycle. I won't be able to document here | |
| 156 all gory details of exactly how this goal is achieved, partly because I haven't | |
| 157 studied the code to the requisite level of depth myself yet, but all of the | |
| 158 responsible code lives under gsm-fw/services/ffs in this freecalypso-sw source | |
| 159 tree; feel free to study it. | |
| 160 | |
| 161 In its "normal" or "clean" state (i.e., when not in the middle of a write | |
| 162 operation or recovery from an ungracefully interrupted one), a TIFFS instance | |
| 163 consists of the following 3 types of blocks: | |
| 164 | |
| 165 * One block containing inode records, indicated by AB in its type/flags/status | |
| 166 byte in the block header; | |
| 167 * N-2 blocks (where N is the total number of flash sectors allocated for the | |
| 168 FFS) containing (or waiting to be filled with) data chunks - indicated by BD | |
| 169 in the type/flags/status byte; | |
| 170 * One "free" block, indicated by BF - destined to become a new AB or a new BD | |
| 171 at some point. | |
| 172 | |
| 173 Each object written into the FFS (file, directory or symlink) consists of a | |
| 174 16-byte inode record written into the AB block and a data chunk written into | |
| 175 one of the BD blocks. The data chunk includes the name of the object, hence | |
| 176 one is required even for directories. Data chunks are contiguous, uncompressed, | |
| 177 and subject to an upper size limit of 2048 or 8192 bytes, depending on the FFS | |
| 178 configuration. Files larger than this limit are stored in a "segmented" form, | |
| 179 giving rise to a 4th inode or object type (after file, directory and symlink): | |
| 180 segment. Each segment of a segmented file consists of not only a data chunk, | |
| 181 but also an inode record for the segment, which gives the location of the data | |
| 182 chunk and ties the segment object into the overall FFS structure, making it | |
| 183 accessible. | |
| 184 | |
| 185 Because aside from complete sector erasure, flash memory bits can only | |
| 186 transition from '1' to '0' but not the other way around, overwriting an existing | |
| 187 file with some new content (an operation which any reasonable file system must | |
| 188 implement in some way) cannot be done in place. Instead like most flash file | |
| 189 systems, TIFFS implements this common operation by writing the new version of | |
| 190 the file to a new location (previously blank flash) and then invalidating the | |
| 191 old version - and doing all that while keeping in mind the possibility of an | |
| 192 ungraceful crash or powerdown at any moment, and the requirement of recovering | |
| 193 gracefully from any such event. | |
| 194 | |
| 195 Of course as an FFS receives more write activity, even if one keeps overwriting | |
| 196 some existing files with new content of the same size, without adding to the | |
| 197 visible total content size (think du(1) command), eventually all remaining blank | |
| 198 flash space will fill up. At that point (or at some earlier point, depending | |
| 199 on the FFS design and/or configuration) the FFS has to invoke a compaction or | |
| 200 reclamation or garbage collection procedure: any "mixed" blocks containing both | |
| 201 valid and stale data are transitioned into a "stale-only" state by having the | |
| 202 active data moved to a new block, and then the "all stale" blocks are subjected | |
| 203 to sector erasure, becoming new blank sectors. The logic responsible for these | |
| 204 operations once again needs to be resilient to the possibility of a crash or | |
| 205 powerdown occurring at the most mis-opportune moment, and it also needs to | |
| 206 implement flash wear leveling: there is a physical limit to how many times a | |
| 207 given flash sector can be erased and rewritten before it goes bad. | |
| 208 | |
| 209 All of the above are common and well-known principles, successfully implemented | |
| 210 in well-known flash file systems such as JFFS2 in Linux. TIFFS is absolutely | |
| 211 no different in this regard; for the implementation details, read the source | |
| 212 code. | |
| 213 | |
| 214 How this FFS comes into being | |
| 215 ============================= | |
| 216 | |
| 217 (This section is only relevant to you if you plan on physically producing your | |
| 218 own GSM phones or modems on your own factory production line, like this author | |
| 219 fancies doing in the not-too-distant future, or if you simply enjoy knowing | |
| 220 how it is done.) | |
| 221 | |
| 222 To my knowledge, TI never used or produced a tool akin to mkfs.jffs2 in the | |
| 223 embedded Linux world, which would produce a TIFFS image complete with some | |
| 224 initial directory and file content "in vitro". Instead it appears that the FFS | |
| 225 instances found in shipped products such as Openmoko phones have been created | |
| 226 "in vivo" by TI's firmware running on the device itself during the "production | |
| 227 test" phase. | |
| 228 | |
| 229 The process seems to go like this: | |
| 230 | |
| 231 * When the printed circuit board is physically populated with components such | |
| 232 as the Calypso chip and the flash chip, the latter can be blank - if the | |
| 233 board design has the nIBOOT pin pulled low, enabling the Calypso boot ROM | |
| 234 (Openmoko and Pirelli both good on this one, but shame on Compal!), there is | |
| 235 no need to preprogram the flash chip with anything prior to populating it on | |
| 236 the board, and the device remains fully unbrickable at all times afterward. | |
| 237 | |
| 238 * When the assembled board is powered up for the first time, with completely | |
| 239 blank flash, the Calypso boot ROM will sit there and patiently wait for a | |
| 240 code download on either of its two UARTs. | |
| 241 | |
| 242 * Using TI's FLUID (Flash Loader Utility Independent of Device) or FreeCalypso's | |
| 243 fc-loadtool free replacement, the factory production station loads the main | |
| 244 firmware image into the flash. Note, it is just the firmware image at this | |
| 245 step, and the FFS sectors remain blank. | |
| 246 | |
| 247 * The board is commanded to reboot (or power-cycled), and the firmware image | |
| 248 boots for the first time. | |
| 249 | |
| 250 * TI's FFS implementation code in their standard firmware reacts to all blank | |
| 251 flash in the FFS sectors as follows: it performs what they call the preformat | |
| 252 operation, writing the TIFFS signature and a BF state byte into every FFS | |
| 253 sector, but the main "format" operation, which sets up the AB/BD block roles, | |
| 254 creates the root inode and makes the FFS ready to accept the creation of its | |
| 255 first directories and files, is not done automatically. | |
| 256 | |
| 257 In order to perform the FFS format operation and then fill the new FFS with | |
| 258 whatever directories and files are deemed needed to be present in "fresh" | |
| 259 shipping products, the factory production station connects to the just-booted | |
| 260 firmware running on the target via the RVT/ETM protocol (see the RVTMUX | |
| 261 write-up), and sends "test mode" commands to this running firmware. These | |
| 262 "FFS test mode" (or TMFFS) commands include the format operation, an mkdir | |
| 263 operation to create directories, and a "file write" operation akin to doing | |
| 264 'cat > /dir/whatever/file', creating files in FFS and storing any desired data | |
| 265 in them. | |
| 266 | |
| 267 The IMEI is assigned and written into FFS in this process, but it is not the | |
| 268 only data item that will be unique for each individual device made. Much more | |
| 269 important are the RF calibration values: I have yet to learn exactly what is | |
| 270 being (or needs to be) measured, how these measurements are performed (under | |
| 271 what conditions; what external test equipment is needed), and how these measured | |
| 272 and recorded RF calibration values affect GSM device operation, but this TI | |
| 273 presentation gives some clues: | |
| 274 | |
| 275 ftp://ftp.ifctf.org/pub/GSM/Calypso/rf_calibration.pdf | |
| 276 | |
| 277 All of these calibration values are stored in a bunch of files under the | |
| 278 /gsm/rf subtree, and these files seem to be "owned" by the L1 code. The latter | |
| 279 has RAM data structures which correspond to these files; upon normal boot the | |
| 280 initialization code looks in FFS, and if it finds any of the RF calibration | |
| 281 files, it reads each present file into the corresponding RAM data structure, | |
| 282 overwriting the compiled-in defaults. It appears (slightly uncertain because I | |
| 283 have not yet reintegrated the code in question into our own gsm-fw) that the RF | |
| 284 calibration files in FFS come into being as follows: | |
| 285 | |
| 286 * The RF calibration code in L1 (i.e., part of the main GSM fw) performs the | |
| 287 measurements and stores results in its RAM data structures as commanded by | |
| 288 the production test station through the "test mode" interface; | |
| 289 | |
| 290 * A final test mode command directs the above L1 code to write its RAM data | |
| 291 structures into FFS. | |
| 292 | |
| 293 Once I actually learn this RF calibration process properly in connection with | |
| 294 building my own Calypso-based GSM "dumbphone", I'll be able to say exactly what | |
| 295 it would take to recreate these RF calibration values if they are lost. But | |
| 296 until then the only advice I can give is to make a backup copy of your modem | |
| 297 FFS with fc-loadtool, and to save it securely. | |
| 298 | |
| 299 FreeCalypso support for TIFFS | |
| 300 ============================= | |
| 301 | |
| 302 Aside from implementing and using it in our own gsm-fw, FreeCalypso will offer | |
| 303 the following support for TIFFS: | |
| 304 | |
| 305 1. A tiffs host utility is being written which will allow a user to list and | |
| 306 extract content from saved FFS images (read out of flash with fc-loadtool) | |
| 307 "in vitro". It will be a restructured and (hopefully) improved version of | |
| 308 the mpffs-* tools released back in the summer of SE52 (A.D. 2013); the latter | |
| 309 already perform the advertised function, but I seek to integrate some other | |
| 310 functionality which I developed in an ad hoc side project ("pirollback"), | |
| 311 and I'm taking the opportunity to make the MPFFS->TIFFS renaming. | |
| 312 | |
| 313 (The mpffs-* tools mentioned above have been written based on reverse eng only, | |
| 314 before I found any source code for TI's FFS firmware implementation! Now that | |
| 315 we have the source, some terminological and other inevitable misunderstandings | |
| 316 can be corrected.) | |
| 317 | |
| 318 2. A number of FC tools may be strung together into a kit for editing the FFS | |
| 319 content of a GSM device, e.g., for changing the IMEI. The following pieces | |
| 320 will be involved: | |
| 321 | |
| 322 * What is destined to eventually become our totally free GSM fw (the gsm-fw | |
| 323 source subtree at the top of freecalypso-sw) does not contain any of the | |
| 324 actual GSM protocol stack (or even L1) functionality yet, but it already | |
| 325 contains both the FFS code and those components (ETM and TMFFS[12]) which | |
| 326 are needed for interfacing an external "test mode shell" to this FFS | |
| 327 implementation through the RVTMUX interface. And when our gsm-fw does gain | |
| 328 the actual GSM functionality, the ability to build a minimal FFS+ETM-only | |
| 329 configuration will still be retained. | |
| 330 | |
| 331 * The minimal FFS+ETM subset of gsm-fw can be built into a ramImage (runs | |
| 332 entirely from RAM via fc-xram, no flashing), and run on a physical device | |
| 333 such as the GTA0x GSM modem via the fc-xram host utility; | |
| 334 | |
| 335 * After loading the ramImage, fc-xram will immediately exec our rvinterf host | |
| 336 utility described in the RVTMUX write-up; | |
| 337 | |
| 338 * Once the GSM device is running what is effectively an FFS editing agent out | |
| 339 of RAM, accessed via rvinterf over the serial channel, the user will be able | |
| 340 to run fc-tmsh (or perhaps the FFS operations will be implemented in some | |
| 341 other utility, we'll see), and that "test mode shell" will provide commands | |
| 342 for writing things to FFS exactly like one would do in the factory production | |
| 343 line environment for which TI taylored their tools. | |
| 344 | |
| 345 The "in vivo" method of editing the FFS content of a GSM device described above | |
| 346 will probably sound very convoluted, and you may find yourself asking for a way | |
| 347 to do it "in vitro" instead: read the FFS out of flash with fc-loadtool, edit | |
| 348 that image "in vitro" with some utility on your PC, and then use fc-loadtool | |
| 349 again to program it back into your device. But consider that an "in vitro" FFS | |
| 350 modification would involve erasing and rewriting all sectors of your FFS, | |
| 351 whereas an "in vivo" modification of some small file like the IMEI would be | |
| 352 just a short flash write operation without any erasures at all, i.e., kinder | |
| 353 on the flash. | |
| 354 | |
| 355 In any case, the "in vivo" method will definitely be available soon because all | |
| 356 of the components involved therein are also needed for other development uses | |
| 357 in the FreeCalypso project, whereas developing a fully-functional "in vitro" | |
| 358 alternative (one that can create an FFS image "de novo" from a tree of files | |
| 359 and directories a la mkfs.jffs2, or add new files to an existing TIFFS image | |
| 360 etc) would be a good amount of extra work which we otherwise don't need - hence | |
| 361 the latter is not very likely to be written any time soon. | |
| 362 | |
| 363 However, if the "in vitro" modification you seek is something trivial like | |
| 364 changing the byte content of a file such as /pcm/IMEI or /gsm/com/rfcap without | |
| 365 changing its length, you will be able to use the "in vitro, read-only" tiffs | |
| 366 host utility to find the exact byte location of the file data within the TIFFS | |
| 367 image, and use your favourite hex editor to whack whatever new byte content you | |
| 368 like at that offset. |
