This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Previous revision
ru:doc:techref:flash.layout [2012/11/13 20:55]
ru:doc:techref:flash.layout [2015/09/12 17:12] (current)
krapiva для поисковиков
Line 1: Line 1:
 +====== Структура памяти OpenWrt ======
 +Есть жесткие диски, которые являются блочными устройствами,​ а есть флэш-память. Флэш память имеет множество типов: NOR Flash, SLC NAND flash и MLC NAND flash.
 +Если чип флэш памяти (не важно какого типа) соединен непосредственно с процессором и процессор может ее использовать обращаясь непосредственно к ее адресам то это называется ​ ** "​сырой флэш"​ ** (raw flash). Для примера подобной флеш памяти являются микросхемы BIOS в старых PC совместимых компьютерах. ​
 +Если ли же между микросхемой флэш памяти и находится какой либо контроллер,​ через который происходит обращение к памяти,​ то это называется **  FTL (Flash Translation Layer) флэш ​ **. 
 +Встроенные системы почти всегда используют "raw flash",​ в то время как любые USB-устройства хранения это FTL flash! ​
 +Или другими словами при доступе к raw flash процессор оперирует адресами флеш памяти,​ а при FTL flash адресами контроллера. Есть небольшое исключение так называемая трансляция/​отображение SPI в память процессора. При которой контроллер SPI отлавливает все обращения к блоку памяти и транслирует их в протокол SPI. Т.е. процессор не замечает подмены,​ но это довольно специфическое и редкое аппаратное решение.
 +===== Устройство образа SquashFS =====
 +Микросхема флэш памяти встроенных систем ​
 +The flash chip on embedded systems is not accompanied by a controller chip, and thus are not //"​FTL"//​-devices but //"raw flash"//​-devices. Storage space is treated and addressed as an [[doc:​techref:​MTD| MTD (Memory Technology Device)]] and special [[doc:​techref:​Filesystems]] are used. The available storage is not partitioned in the traditional way, where you store the data about the partitions in the [[wp>​Master boot record|MBR]] and [[wp>​Volume boot record|PBR]]s,​ but it is done in the Linux Kernel (and sometimes independently in the [[doc:​techref:​bootloader]] as well!). You simply define, that "​partition **//​kernel//​** starts at offset x and ends at offset y". The advantage is, that later we can address these partitions by name, rather then specifying the precise start point of the data.
 +:!: Ниже приведен пример разбиение флеш памяти ​ [[toh:​tp-link:​TL-WR1043ND]] другой пример разбиения вы можете найти на соответствующих страницах устройств данной wiki, для примера ​ смотри [[toh:​d-link:​DIR-300#​flash.layout|DIR-300]]. Варианты разбиений могут существенно различаться от устройства к устройству,​ в том числе и для одноименных устройств,​ но с разными версия.
 +^   ​Разбиение флеш памяти TP-Link WR1043ND ​          ​^^^^^^
 +^ Уровень-0 ​      ​| ​                      ​m25p80 [[wp>​Serial Peripheral Interface Bus|spi]]0.0:​ m25p64 ​     8192 КБ                                                                      |||||
 +^ Уровень-1 ​      ​| ​ mtd0 **//​u-boot//​** 128 КБ  |  mtd5 **//​firmware//​** 8000 КБ                                      |||    mtd4 **//art//** 64 КБ  |
 +^ Уровень-2 ​      ​| ​                             |  mtd1 **//​kernel//​** 1280 КБ  |  mtd2 **//​rootfs//​** 6720 КБ                           ​|| ​         |
 +^ <color magenta>​точка монтирования</​color> ​  ​| ​                             |                               ​| ​ <color magenta>''/''</​color> ​                         ||          |
 +^ файловая система ​  ​| ​                             |                               ​| ​ [[doc:​techref:​filesystems#​mini_fo|mini_fo]]/​[[doc:​techref:​filesystems#​overlayfs|overlayfs]] ​          ​|| ​         |
 +^ Уровень-3 ​      ​| ​                             |                               ​| ​                ​| ​ mtd3 **//​rootfs_data//​** 5184 КБ     ​| ​         |
 +^ Размер в КБайтах ​ |  128 КБ                      |  1280 КБ                    |  1536 КБ        |  5184 КБ                              |   64 КБ  |
 +^ Наименование ​        ​| ​ **//​u-boot//​** ​             |  **//​kernel//​** ​              ​| ​                ​| ​ **//​rootfs_data//​** ​            ​| ​ **//​art//​** ​ |
 +^ <color magenta>​точка монтирования</​color> ​  ​| ​ //​none// ​                   |  //​none// ​                    ​| ​ <color magenta>''/​rom''</​color> ​ |  <color magenta>''/​overlay''</​color> ​  ​| ​ //​none// ​ |
 +^ файловая система ​  ​| ​ //​none// ​                   |  //​none// ​                    ​| ​ [[doc:​techref:​filesystems#​SquashFS]] ​ |  [[doc:​techref:​filesystems#​JFFS2]] ​ |  //​none// ​ |
 +==== Разбиение ====
 +Разбиение легче всего продемонстрировать на примера уровней(слоев):​
 +Since the partitions are nested we look at this whole thing in layers:
 +  - Уровень-0:​ Представляет из себя микросхему флэш памяти установленную на плате, в примере она имеет емкость,​ 8192 КБ и аппаратно подключена к [[doc:​hardware:​SoC]] через [[wp>​Serial Peripheral Interface Bus|SPI (Serial Peripheral Interface Bus)]].
 +  - Уровень-1:​ We "​partition"​ the space into mtd0 for the bootloader, mtd5 for the firmware and, in this case, mtd4 for the ART (Atheros Radio Test) - it contains mac addresses and calibration data for the wifi (EEPROM). If it is missing or corrupt, ''​ath9k''​ (wireless driver) won't come up anymore.
 +  - Уровень-2:​ we subdivide mtd5 (firmware) into mtd1 (kernel) and mtd2 (rootfs); In the generation process of the firmware (see [[doc:​howto:​obtain.firmware.generate]]) the Kernel binary file is first packed with [[wp>​Lempel–Ziv–Markov chain algorithm|LZMA]],​ then the obtained file is packed with [[wp>​gzip]] and then this file will be written onto the raw flash (mtd1) without being part of any filesystem!
 +  - Уровень-3:​ we subdivide rootfs even further into mtd3 for rootfs_data and the rest for an unnamed partition which will accommodate the SquashFS-partition.
 +==== Filesystems ====
 +-> [[doc:​techref:​filesystems]]
 +==== Mount Points ====
 +  * <color magenta>''/''</​color>​ this is your entire root filesystem, it comprises ''/​rom''​ and ''/​overlay''​. Please ignore ''/​rom''​ and ''/​overlay''​ and use exclusively ''/''​ for your daily routines!
 +  * <color magenta>''/​rom''</​color> ​ contains all the basic files, like ''​busybox'',​ ''​dropbear''​ or ''​iptables''​ including default configuration files. Does not contain the kernel. Files in this directory are on the SqashFS partition, and thus cannot be deleted. But, because we use mini_fo filesystem, so called //​overlay-whiteout//​-symlinks can be created on the JFFS2 partition.
 +  * <color magenta>''/​overlay''</​color> ​ is the writable part of the file system that gets merged with ''/​rom''​ to create a uniform ''/''​-tree. It contains anything that was written to the router after [[doc:​howto:​generic.flashing|installation]],​ e.g. changed configuration files, additional packages installed with ''​[[doc:​techref:​opkg]]'',​ etc. It is formated with JFFS2.
 +Rather than deleting the files, insert a whiteout, a special high-priority entry that marks the file as deleted. File system code that sees a whiteout entry for file F behaves as if F does not exist.
 +<code bash>
 +# shows all overlay-whiteout symlinks
 +find /overlay -type l | while read FILE
 +  do
 +    [ -z "​$FILE"​ ] && break
 +    if ls -la "​$FILE"​ 2>&- | grep -q '​(overlay-whiteout)';​ then
 +    echo "​$FILE"​
 +    fi
 +  done
 +==== Directories ====
 +**//''​NOTE1''//:​** If the Kernel was part of the SquashFS, we could not control where exactly on the flash it is written to (on which blocks its data is contained). Thus we could not tell the bootloader to simply load and execute certain blocks on the flash storage, but would have to address it with path and filename. Now this would not be bad, but in order to that the bootloader would have to understand the SquashFS filesystem, which it does not. The embedded bootloaders we utilize with OpenWrt generally have no concept of filesystems,​ thus they cannot address files by path and filename. They pretty much assume that the start of the trx data section is executable code.\\
 +**//''​NOTE2''//:​** The denomination ''"​firmware"''​ usually is used for the entire data on the flash comprising the boot loader and any other data necessary to operate the device, such as ART, NVRAM, FIS, etc, but we also use it to name only the parts that are being rewritten. Don't let this confuse you ;-)\\
 +===== Partitioning of JFFS2-Images =====
 +===== Discovery (How to find out) =====
 +cat /proc/mtd
 +dev:    size   ​erasesize ​ name
 +mtd0: 00020000 00010000 "​u-boot"​
 +mtd1: 00140000 00010000 "​kernel"​
 +mtd2: 00690000 00010000 "​rootfs"​
 +mtd3: 00530000 00010000 "​rootfs_data"​
 +mtd4: 00010000 00010000 "​art"​
 +mtd5: 007d0000 00010000 "​firmware"​
 +The //​erasesize//​ is the [[wp>​Block (data storage)|block size]] of the flash, in this case 64KiB. The //size// is little or big [[wp>​Endianess|endian]] hex value in Bytes. In case of little endian, you switch to hex-mode and enter 02 0000 into the calculator for example and convert to decimal (by switching back to decimal mode again). Then guess how they are nested into each other. Or execute ''​dmesg''​ after a fresh boot and look for something like:
 +Creating 5 MTD partitions on "​spi0.0":​
 +0x000000000000-0x000000020000 : "​u-boot"​
 +0x000000020000-0x000000160000 : "​kernel"​
 +0x000000160000-0x0000007f0000 : "​rootfs"​
 +mtd: partition "​rootfs"​ set to be root filesystem
 +mtd: partition "​rootfs_data"​ created automatically,​ ofs=2C0000, len=530000
 +0x0000002c0000-0x0000007f0000 : "​rootfs_data"​
 +0x0000007f0000-0x000000800000 : "​art"​
 +0x000000020000-0x0000007f0000 : "​firmware"​
 +These are the start and end offsets of the partitions as hex values in Bytes. Now you don't have to guess which is nested in which. E.g. 02 0000 = 131.072 Bytes = 128KiB.
 +===== Details =====
 +==== generic ====
 +The flash chip can be represented as a large block of continuous space:
 +| start of flash ................. end of flash  |
 +There is no ROM to boot from; at power up the CPU begins executing the code at the very start of the flash. Luckily this isn't the firmware or we'd be in real danger every time we reflashed. Boot is actually handled by a section of code we tend to refer to as the [[bootloader]] (the BIOS of your PC //is// a bootloader).
 +| ^ Boot Loader Partition ^ Firmware Partition ^ ''​Special Configuration Data''​ ^^^
 +^ Atheros ​ |  [[doc:​techref:​bootloader:​uboot|U-Boot]] ​  ​| ​ firmware ​ |  ''​ART'' ​        |||
 +^ Broadcom |  CFE      |  firmware ​ |  ''​NVRAM'' ​      |||
 +^ Atheros ​ |  RedBoot ​ |  firmware ​ |  ''​FIS recovery'' ​ |  ''​RedBoot config'' ​ |  ''​boardconfig'' ​ |
 +The partition or partitions containing so called //Special Configuration Data// differ very much from each other. Example: The ''​ART''​-partition you will meet in conjunction with Atheros-Wireless and U-Boot, contains only data regarding the wireless driver, while the ''​NVRAM''​-partition of broadcom devices is used for much more then only that.
 +==== broadcom with CFE ====
 +If you dig into the "​firmware"​ section you'll find a trx. A trx is just an encapsulation,​ which looks something like this:
 +^ trx-header ^^^^^^^
 +| HDR0  |  length ​ |  crc32  |  flags  |  pointers ​ |  data  |
 +"​HDR0"​ is a magic value to indicate a trx header, rest is 4 byte unsigned values followed by the actual contents. In short, it's a block of data with a length and a checksum. So, our flash usage actually looks something like this:
 +|  CFE  |  trx containing firmware ​ |  NVRAM  |
 +Except that the firmware is generally pretty small and doesn'​t use the entire space between CFE and NVRAM:
 +|  CFE  |  trx firmware ​ |  unused ​ |  NVRAM  |
 +(**//''​NOTE''//:​** The <​model>​.bin files are nothing more than the generic *.trx file with an additional header appended to the start to identify the model. The model information gets verified by the vendor'​s upgrade utilities and only the remaining data -- the trx -- gets written to the flash. When upgrading from within OpenWrt remember to use the *.trx file.)
 +So what exactly is the firmware?
 +The boot loader really has no concept of filesystems,​ it pretty much assumes that the start of the trx data section is executable code. So, at the very start of our firmware is the kernel. But just putting a kernel directly onto flash is quite boring and consumes a lot of space, so we compress the kernel with a heavy compression known as [[wp>​Lempel–Ziv–Markov chain algorithm|LZMA]]. Now the start of firmware is code for an LZMA decompress:
 +|  lzma decompress ​ |  lzma compreszsed kernel ​ |
 +Now, the boot loader boots into an LZMA program which decompresses the kernel into memory and executes it. It adds one second to the bootup time, but it saves a large chunk of flash space. (And if that wasn't amusing enough, it turns out the boot loader does know gzip compression,​ so we gzip compressed the LZMA decompression program)
 +Immediately following the kernel is the filesystem. We use SquashFS for this because it's a highly compressed readonly filesystem -- remember that altering the contents of the trx in any way would invalidate the crc, so we put our writable data in a JFFS2 partition, which is outside the trx. This means that our firmware looks like this:
 +|  trx  | gzip'd lzma decompress ​ |  lzma'd kernel ​ |  (SquashFS filesystem) ​ |
 +And the entire flash usage looks like this -
 +|  CFE  |  trx  |  gz'd lzma  |  lzma'd kernel ​ |  SquashFS ​ |  JFFS2 filesystem ​ |  NVRAM  |
 +That's about as tight as we can possibly pack things into flash.
 +===== Explanations =====
 +==== What is an Image File? ====
 +An image file is byte by byte copy of data contained in a file system. If you installed a Debian or a Windows in the usual way onto one or two harddisc partitions and would afterwards copy the whole content byte by byte from the hard disc into one file:
 +<code bash>
 +dd if=/dev/sda of=/​media/​sdb3/​backup.dd
 +the obtained backup file ''/​media/​sdb3/​backup.dd'',​ could be used in the exact same manner like an OpenWrt-Image-File.
 +The difference is, that OpenWrt-Image-File are not created that way ;-) They are being generated with the **Image Generator** (former called Image Builder). You can read about the:
 +  * [[doc/​techref/​flash.layout]]
 +  * [[doc/​techref/​header]]
 +  * [[doc/​howto/​obtain.firmware.generate]] If you want to read about the **Image Generator**,​ go back to [[doc:​howto:​obtain.firmware]] and choose the second way.
 +  * About [[http://​​wiki/​FirmwareFormat|Broadcom Firware Format]]