{"id":77,"date":"2017-04-20T23:55:12","date_gmt":"2017-04-21T03:55:12","guid":{"rendered":"http:\/\/www.hackspot.net\/StuartCam\/?p=77"},"modified":"2017-04-20T23:55:12","modified_gmt":"2017-04-21T03:55:12","slug":"firmware-images-and-firmware-updates","status":"publish","type":"post","link":"http:\/\/www.hackspot.net\/StuartCam\/2017\/04\/20\/firmware-images-and-firmware-updates\/","title":{"rendered":"Firmware images and firmware updates"},"content":{"rendered":"<h3>Firmware update images<\/h3>\n<p>A firmware update image is nothing more than a standard U-boot uImage file with a kernel and an embedded root filesystem. \u00a0An example of a firmware update image can be found <a href=\"https:\/\/app.isecurityplus.com\/seedonk\/firmware\/minions\/A356_upgrade_00.10.008_20161107.img\">here<\/a>.<\/p>\n<p>There is nothing additional in a firmware update image &#8211; no signature, encryption, etc. \u00a0Just a simple uImage file.<\/p>\n<p>The mkimage utility (from the uboot-tools package) shows the following for the firmware image (U-boot uImage) referenced above:<\/p>\n<pre>$ mkimage -l A356_upgrade_00.10.011_20170221.img \r\nImage Name: Imogen-X860-I\r\nCreated: Tue Feb 21 00:42:01 2017\r\nImage Type: ARM Linux Kernel Image (uncompressed)\r\nData Size: 6712048 Bytes = 6554.73 kB = 6.40 MB\r\nLoad Address: 80008000\r\nEntry Point: 80008000\r\n$<\/pre>\n<p>The U-boot uImage file has a 64-byte header, which looks like the following:<\/p>\n<pre>$ hexdump -Cv -n 64 A356_upgrade_00.10.011_20170221.img|cut -c-58\r\n00000000 27 05 19 56 9e 83 37 37 58 ab d3 29 00 66 6a f0\r\n00000010 80 00 80 00 80 00 80 00 a1 48 48 d8 05 02 02 00\r\n00000020 49 6d 6f 67 65 6e 2d 58 38 36 30 2d 49 00 00 00\r\n00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<\/pre>\n<p>Immediately after the 64-byte uImage header is the kernel. \u00a0The kernel itself is XZ-compressed, so has a small program prepended to it which can decompress the kernel image and start the kernel.<\/p>\n<p>The kernel has an embedded root filesystem (initramfs) which was linked-into the kernel at build time. \u00a0The initramfs is a cpio archive, which itself has also been XZ compressed and stored inside the kernel.<\/p>\n<h3>Two copies of the firmware (kernel)<\/h3>\n<p>As I mentioned in my previous post, there are two separate mtd partitions in the SPI flash used for firmware\/kernel images &#8211; one is called &#8220;kernel0&#8221; (in mtd3), the other is &#8220;kernel1&#8221; (in mtd4).<\/p>\n<p>One of the kernel partitions is &#8220;active&#8221; (the one that is running), and the other is &#8220;inactive&#8221;. \u00a0When a new firmware update image is installed, it is copied to the &#8220;inactive&#8221; mtd partition, then it is marked as the &#8220;active&#8221; image. \u00a0On the next boot, u-boot will load the new &#8220;active&#8221; image and run it.<\/p>\n<h3>Identifying active vs inactive kernel images<\/h3>\n<p>The last 4-bytes of the 64-byte uImage header are used as a &#8216;counter\/version&#8217;. \u00a0The kernel image with the largest counter value is the &#8216;active&#8217; partition.<\/p>\n<p>As an example, here are hexdumps showing the first 64-bytes of my StuartCam&#8217;s current &#8220;kernel0&#8221; (mtd3) and &#8220;kernel1&#8221; (mtd4) partitions.<\/p>\n<pre># dump kernel0\/mtd3 header\r\n$ hexdump -Cv -n 64 \/dev\/mtd3|cut -c-58\r\n00000000 27 05 19 56 07 8a 66 8d 58 ab d3 29 00 66 6a f0\r\n00000010 80 00 80 00 80 00 80 00 a1 48 48 d8 05 02 02 00\r\n00000020 49 6d 6f 67 65 6e 2d 58 38 36 30 2d 49 00 00 00\r\n00000030 00 00 00 00 00 00 00 00 00 00 00 00 <strong>00 00 00 03<\/strong>\r\n\r\n# dump kernel1\/mtd4 header\r\n$ hexdump -Cv -n 64 \/dev\/mtd4|cut -c-58\r\n00000000 27 05 19 56 28 8b 40 5b 58 f7 ff 6b 00 66 6a f0\r\n00000010 80 00 80 00 80 00 80 00 e1 59 88 12 05 02 02 00\r\n00000020 49 6d 6f 67 65 6e 2d 58 38 36 30 2d 49 00 00 00\r\n00000030 00 00 00 00 00 00 00 00 00 00 00 00 <strong>00 00 00 04<\/strong><\/pre>\n<p>Note that the last 4 bytes of &#8220;kernel0&#8221; are &#8220;00 00 00 03&#8221; (counter = 0x00000003) and the last 4 bytes of &#8220;kernel1&#8221; are &#8220;00 00 00 04&#8221; (counter = 0x00000004). \u00a0Since &#8220;kernel1&#8221; has a larger counter than &#8220;kernel0&#8221;, &#8220;kernel1&#8221; is the &#8216;active&#8217; partition.<\/p>\n<p>When U-boot starts up (on power-cycle or reboot), it looks at both headers. \u00a0In the above example, U-boot will choose to load\/run &#8220;kernel1&#8221;, since it is the &#8216;active&#8217; parition.<\/p>\n<p>When a new firmware update image is installed, using the above example, it will choose to write the new firmware to the &#8220;kernel0&#8221; partition (since it is &#8216;inactive&#8217;). \u00a0Once the firmware is fully written, the firmware update process will write a new &#8220;counter&#8221; value to the last 4 bytes of the 64-byte header. \u00a0This counter value will be one larger than the currently active partition&#8217;s counter value.<\/p>\n<p>So, the next update on this StuartCam will be written to &#8220;kernel0&#8221;, and the new counter value will be &#8220;00 00 00 05&#8221; (counter = 0x00000005). On next boot, U-boot will see this as the largest counter, and will boot it instead.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Firmware update images A firmware update image is nothing more than a standard U-boot uImage file with a kernel and an embedded root filesystem. \u00a0An example of a firmware update image can be found here. There is nothing additional in a firmware update image &#8211; no signature, encryption, etc. \u00a0Just a simple uImage file. The &hellip; <a href=\"http:\/\/www.hackspot.net\/StuartCam\/2017\/04\/20\/firmware-images-and-firmware-updates\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Firmware images and firmware updates&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-77","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/posts\/77","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/comments?post=77"}],"version-history":[{"count":10,"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/posts\/77\/revisions"}],"predecessor-version":[{"id":91,"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/posts\/77\/revisions\/91"}],"wp:attachment":[{"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/media?parent=77"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/categories?post=77"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.hackspot.net\/StuartCam\/wp-json\/wp\/v2\/tags?post=77"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}