{"id":445,"date":"2021-10-13T01:38:59","date_gmt":"2021-10-13T05:38:59","guid":{"rendered":"https:\/\/www.fitzsim.org\/blog\/?p=445"},"modified":"2021-10-13T01:40:13","modified_gmt":"2021-10-13T05:40:13","slug":"mezzano-on-librebooted-thinkpads","status":"publish","type":"post","link":"https:\/\/www.fitzsim.org\/blog\/?p=445","title":{"rendered":"Mezzano on Librebooted ThinkPads"},"content":{"rendered":"\n<p>I decided to try running <a href=\"https:\/\/github.com\/froggey\/Mezzano\">Mezzano<\/a> on real hardware.  I figured my <a href=\"https:\/\/libreboot.org\/\">Librebooted<\/a> ThinkPads would be good targets, since, thanks to Coreboot and the Linux kernel, I have reference source code for all the hardware.<\/p>\n<p>On boot, these machines load Libreboot from SPI flash; included in this Libreboot image is GRUB, as a Coreboot payload.<\/p>\n<p>Mezzano, on the other hand, uses the KBoot bootloader.  I considered chainloading KBoot from GRUB, but I wondered if I could have GRUB load the Mezzano image directly, primarily to save a video mode switch.<\/p>\n<p>I didn&#8217;t want to have to reflash the Libreboot payload on each modification (writing to SPI flash is slow and annoying to recover from if something goes wrong), so I tried building a GRUB module &#8220;out-of-tree&#8221; and loading it in the existing GRUB.  Eventually I got this working, at which point I could load the module from a USB drive, allowing fast development iteration.  (I realize out-of-tree modules are non-ideal so if there&#8217;s interest I may try to contribute this work to GRUB.)<\/p>\n<p>The resulting GRUB module, <code>mezzano.mod<\/code>, is largely the KBoot Mezzano loader code, ported to use GRUB facilities for memory allocation, disk access, etc.  It&#8217;s feature-complete, so I released it to <a href=\"https:\/\/git.sr.ht\/~fitzsim\/grub\">Sourcehut<\/a>.  (I&#8217;ve only tested it on Libreboot GRUB, not GRUB loaded by other firmware implementations.)<\/p>\n<p>Here&#8217;s a demo of loading Mezzano on two similar ThinkPads:<\/p><p>\n<video controls=\"\" width=\"832\" height=\"540\">\n<source src=\"https:\/\/www.fitzsim.org\/screenshots\/grub-mezzano-module-1.webm\"\/>\n<a href=\"https:\/\/www.fitzsim.org\/screenshots\/grub-mezzano-module-1.webm\">GRUB Mezzano module demo<\/a>\n<\/video><\/p>\n<p>For ease of use, <code>mezzano.mod<\/code> supports directly loading the <code>mezzano.image<\/code> file generated by <a href=\"https:\/\/github.com\/froggey\/MBuild\">MBuild<\/a> &#8212; instead of requiring that <code>mezzano.image<\/code> be <code>dd<\/code>&#8216;d to a disk.  It does so by skipping the KBoot partitions to find the Mezzano disk image.  The T500 in the video is booted this way.  Alternatively, <code>mezzano.mod<\/code> can load the Mezzano disk image from a device, as is done for the W500 in the video.  Both methods look for the Mezzano image magic &#8212; first at byte 0 and, failing that, just after the KBoot partitions.<\/p>\n<p>I added the <code>set-i8042-bits<\/code> argument because Coreboot does not set these legacy bits, yet Mezzano&#8217;s PS\/2 keyboard and mouse drivers expect them; at this point Mezzano does not have a full ACPI device tree implementation.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I decided to try running Mezzano on real hardware. I figured my Librebooted ThinkPads would be good targets, since, thanks to Coreboot and the Linux kernel, I have reference source code for all the hardware. On boot, these machines load Libreboot from SPI flash; included in this Libreboot image is GRUB, as a Coreboot payload. &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.fitzsim.org\/blog\/?p=445\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Mezzano on Librebooted ThinkPads&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-445","post","type-post","status-publish","format-standard","hentry","category-lisp","entry"],"_links":{"self":[{"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/445","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=445"}],"version-history":[{"count":8,"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/445\/revisions"}],"predecessor-version":[{"id":453,"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/445\/revisions\/453"}],"wp:attachment":[{"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=445"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=445"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fitzsim.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}