<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Youness Alaoui &#8211; Purism</title>
	<atom:link href="https://puri.sm/posts/author/_kakaroto/feed/" rel="self" type="application/rss+xml" />
	<link>https://puri.sm/</link>
	<description>High-quality laptops that protect your freedom and privacy</description>
	<lastBuildDate>Mon, 09 Nov 2020 16:41:35 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.16</generator>

<image>
	<url>https://puri.sm/wp-content/uploads/2020/04/cropped-purism-logo-rectangle-1-32x32.png</url>
	<title>Youness Alaoui &#8211; Purism</title>
	<link>https://puri.sm/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Adventures with coreboot and NVM Express storage</title>
		<link>https://puri.sm/posts/adventures-with-coreboot-and-nvm-express-storage/</link>
		<pubDate>Thu, 11 Oct 2018 23:11:21 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Laptops]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=17164</guid>
		<description><![CDATA[<p>Let me tell you how I made NVMe SSD support work on the first generation Librem laptops. This story is pretty old, from before the Librem 13 version 2 was even released, so it has been simplified and brought back to the current state of things as much as possible. The solutions presented here have [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/adventures-with-coreboot-and-nvm-express-storage/">Adventures with coreboot and NVM Express storage</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Let me tell you how I made <a href="https://en.wikipedia.org/wiki/NVM_Express" target="_blank" rel="noopener">NVMe</a> SSD support work on the first generation Librem laptops. This story is pretty old, from before the Librem 13 version 2 was even released, so it has been simplified and brought back to the current state of things as much as possible. The solutions presented here have been implemented a long time ago in our coreboot ports, but the technical insights you may derive from this post today should prove interesting nonetheless.<span id="more-17164"></span></p>
<p>During internal beta testing of the install script a while ago, we realized that coreboot didn&#8217;t work with our NVMe SSDs, as all my testing had been done with a SATA M.2 SSD. I spent some time fixing coreboot so that it would initialize the NVMe SSD, and SeaBIOS so it can boot from the NVMe drive, and then I&#8217;ve figured out how to fix the NVMe issues I&#8217;ve been having after linux boots.</p>
<p>The story began with my blog post about the <a href="https://puri.sm/posts/preventing-interference-from-the-old-bios-while-flashing-coreboot/">interference of the AMI BIOS</a> with coreboot. What I didn&#8217;t mention back then is that after I figured out the issue and managed to unbrick Francois&#8217; Librem, he wasn&#8217;t able to boot into his SSD from coreboot because it wasn&#8217;t getting detected. I then realized that he had an NVMe SSD and not a SATA SSD.</p>
<ul>
<li>A SATA drive is controlled using the SATA controller on the motherboard which talks to the SATA drive using 4 data lines.</li>
<li>A NVMe drive is actually a PCIe device all on its own, which could use up to 16 data lines (4 per lane and the <a href="https://en.wikipedia.org/wiki/M.2">M.2 specification</a> defines up to 4 lanes per device).</li>
</ul>
<p>If a SATA device is detected, then the integrated SATA controller will talk to the drive using the SATA protocol, if a PCIe device is detected, then the device will be initialized as any other PCIe device (like the Wifi module for example) and in the case of NVMe drives, the NVMe protocol will be used directly (without passing through an onboard controller) to communicate with the device.</p>
<p>With that knowledge, I figured out my simple mistake then: the PCIe port used for the M.2 connector is Port #6, which is a &#8220;Flexible I/O&#8221; which can be used for either SATA or PCIe according to the <a href="https://www-ssl.intel.com/content/dam/www/public/us/en/documents/datasheets/5th-gen-core-family-platform-i-o-datasheet.pdf">Intel Broadwell datasheet</a>. Unfortunately, in the Librem 13 coreboot configuration, the PCIe Port #6 was disabled (since it was never used, but that was only because I only ever tried a SATA drive). So <a href="https://review.coreboot.org/#/c/19446/4/src/mainboard/purism/librem13/devicetree.cb@a57">the fix </a>was simple: enable the PCIe port #6, and once coreboot initializes that PCIe port, the NVMe drive is initialized and working.</p>
<p>Francois tested this for me and confirmed he could boot on his drive. I needed to do my own tests however, so I ordered an NVMe drive (The Intel 600p Series SSD) and before I received it, someone (a regular Librem user) found and decided to test my script. With a lot of courage and determination, he was the first non-purism-employee beta tester of the coreboot install script and unfortunately, it didn&#8217;t work for him. While the coreboot install was fine, SeaBIOS wasn&#8217;t detecting his NVMe drive (he could boot into a live USB and flash back his Factory BIOS, so nothing to be alarmed about). I didn&#8217;t know why it worked for Francois but not for jsparber (our volunteer beta tester). I then realized that SeaBIOS itself didn&#8217;t have NVMe support, or more precisely, the NVMe support that was added to SeaBIOS was never tested outside of the qemu emulator, and was actually disabled for real hardware, so I enabled NVMe support for non-qemu hardware and sent the updated image to our beta tester who confirmed it to be working.</p>
<p>Why was it working for Francois if SeaBIOS didn&#8217;t have NVMe support, though? That&#8217;s a bit mysterious, but I think that his specific NVMe drive had some sort of SATA-compatibility mode in order to allow booting from older BIOS that don&#8217;t support NVMe devices.</p>
<p>Once I received my own NVMe SSD, I thought that it would just be a formality to get it to work, and indeed, it was detected by SeaBIOS but I couldn&#8217;t boot on it because it was still blank, so I tried to install PureOS on it. Unfortunately, that failed. I was getting an error halfway through the installation and the NVMe device was disappearing completely. My dmesg output had (among a flood of I/O errors) :</p>
<pre>nvme 0000:04:00.0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0xffff
nvme 0000:04:00.0: Refused to change power state, currently in D3
nvme nvme0: Removing after probe failure status: -19
nvme0n1: detected capacity change from 256060514304 to 0
</pre>
<p>After searching for a long time, I&#8217;ve found a few mentions of this error. At first, I thought that this <a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1626894">lauchpad bug</a> was the one affecting me, but it was saying that it was fixed in kernel 4.4.0, and 4.8. The PureOS live USB was sporting kernel 4.7 back then, so I thought that maybe I needed a higher kernel version still. I tried to install Ubuntu 17.04, but it wouldn&#8217;t even boot, and then the Fedora 25 live USB would have the same issue, even though it had kernel 4.9.6. I decided to try the Archlinux installer, which had the 4.10.6 kernel, and I had the same problems, then I found this <a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1678184">other bug</a> which says it might happen since kernel 4.10.0 had support for APST and some drives had quirks which made them fail when APST was enabled, but the fix here was simple, a kernel option at boot and the bug should disappear, so I tried it but no luck.</p>
<p>At that point, in order to remove coreboot from the equation, I had flashed back an AMI BIOS on my Librem, but I was still getting all these issues.</p>
<p>I gave up after a while, and I figured out that if it&#8217;s not a kernel issue, maybe it&#8217;s not a Linux issue at all, so I tried installing Windows on the NVMe, and the same issue happened again! &#8220;Well, if the problem happens with Windows and the factory BIOS, then there&#8217;s nothing I can do, the problem is with the drive itself, it&#8217;s defective! Right?&#8221;</p>
<p>While I was trying to find the original packaging to ship it back for a replacement, I had an idea: I put the NVMe drive in the Librem 13 v2 prototype that I had, and it worked! So I figured that the problem was with my own Librem 13 v1 which might have had defective hardware (maybe a scratch on the motherboard or something?)</p>
<p>However, for a week, while working on other things, I kept thinking that there <em>must</em> be something else I can do, that the issue can&#8217;t be as simple as &#8220;it&#8217;s a hardware issue&#8221;, but I didn&#8217;t know what more I could do if Windows+AMI Bios were failing, and the SSD itself was fine.</p>
<p>Then Francois told me that he was having issues with his Librem, where the NVMe device would &#8220;disappear&#8221;. This looked a lot like the problem I&#8217;ve been having, but for him, it wouldn&#8217;t happen within the first 5 minutes of use like me, it would happen after 48 hours instead, sometimes after putting the laptop to sleep, sometimes not—very unpredictable. Unfortunately, he had also reinstalled his system at the same time when he flashed coreboot, so this new problem could be coming from coreboot or from the new OS he installed—but lo and behold, after he flashed his original BIOS back, he was still having the same issue of his NVMe disappearing.</p>
<p>Since I don&#8217;t believe in coincidences, I decided to start my research again from scratch—forget all the various links and explanations and datasheets I found—and just looked at the problem from a blank slate. After I searched for the error I was getting again, I found <a href="https://forums.lenovo.com/t5/forums/v3_1/forumtopicpage/board-id/tp02_en/thread-id/75451/page/1" class="broken_link">a post</a> on the Lenovo forums where someone was complaining about the same issue on their ThinkPad X270 and the thread was marked as &#8220;<em>SOLVED</em>&#8220;, so that was very promising. After reading through it, I found that the solution was a new <a href="http://support.lenovo.com/ca/en/downloads/ds120442">BIOS update</a> for the Lenovo X270 that fixed the problem. And when I looked at the <a href="https://download.lenovo.com/pccbbs/mobiles/r0iuj06ww.txt">changelog</a> of that update, this is what it said about NVMe support:</p>
<blockquote>
<pre>- (New) Disable NVMe L1.2
- (New) Disable NVMe CLKREQ</pre>
</blockquote>
<p>Now <em>that</em> was interesting… what was this &#8220;L1.2&#8221; and &#8220;CLKREQ&#8221;? I did some more research and I found <a href="https://www.plda.com/conquering-challenges-pcie-nvme-order-deliver-highly-competitive-enterprise-pcie-ssd">an article</a> that explained that L1.2 is simply a lower-power mode of operation for a PCIe device. Going back to the original dmesg output, I then realized that it said something very interesting about the drive and its power state:</p>
<pre>Refused to change power state, currently in D3</pre>
<p>According to this <a href="https://msdn.microsoft.com/en-us/library/windows/hardware/ff543186(v=vs.85).aspx">MSDN article</a>, the &#8220;D3&#8221; there refers to a device power state, and more precisely, D3 is the lowest power state of the device. That seems to coincide with the L1.2 PCIe state which is also the lowest power state. I&#8217;ve decided to do what Lenovo did and disable CLKREQ and L1.2 in the PCIe device. The CLKREQ seems to be used by the CPU or by the device to request activation of the clock and to allow exit of the L1.2. According to the PCI specification, I&#8217;ve found a <a href="https://pcisig.com/sites/default/files/specification_documents/MiniEx_M2_ECR_PERST_CLKREQ_Power-up-Reqts_20140918_Final.pdf" class="broken_link">document</a> that states :</p>
<blockquote><p>&#8220;The CLKREQ# signal is also used by the L1 PM Substates mechanism. In this case, CLKREQ# can be asserted by either the system or the device to initiate an L1 exit&#8221;</p></blockquote>
<p>The &#8220;L1 PM substates&#8221; is referring to that L1.2 (L1.1 and L1.2 are referred to as L1 substates, and &#8220;PM&#8221; here means &#8220;Power Management&#8221;), so my theory was that the drive goes into low power mode, and when it needs to get out of it, the CLKREQ should be used, but wasn&#8217;t working, causing the drive to never know that it needs to wake up. Disabling CLKREQ would fix it because some other mechanism would be used to wake the drive, or disabling L1.2 would also fix it because the drive would never go into that D3 low power mode.</p>
<p>I looked extensively at the <a href="https://www-ssl.intel.com/content/dam/www/public/us/en/documents/datasheets/5th-gen-core-family-platform-i-o-datasheet.pdf">Broadwell LP datasheet</a> and I saw that the CLKREQ for PCIe port #6 is multiplexed with GPIO 23, and looking at the gpio.h in coreboot for the Librem 13, I see GPIO 23 set as &#8220;INPUT&#8221;, while GPIO 18 and 19 (which are for PCIe ports #1 and #2) are set as &#8220;NATIVE&#8221;. So I&#8217;ve set GPIO 23 to NATIVE and tried it, but this made NVMe undetectable; coreboot was simply unable to detect anything on port #6, and I have no idea why. Not only do I not know what a &#8220;native&#8221; gpio means, but I also don&#8217;t know why changing it from input to native would cause the PCI bus scan to fail.</p>
<p>Either way, I&#8217;ve set it back to &#8220;INPUT&#8221; and tried to see how to disable CLKREQ from some PCI configuration. Unfortunately, the code in soc/intel/broadwell/pcie.c—which mentions &#8220;CLKREQ&#8221;—does things that I can&#8217;t understand, it modifies/sets PCI configuration values on offsets that don&#8217;t match anything in the datasheet and I have no idea if I&#8217;ve been reading the datasheet incorrectly or if the code is wrong somehow.</p>
<p>One simple example is this code snippet:</p>
<pre>/* Per-Port CLKREQ# handling. */
if (gpio_is_native(18 + rp - 1))
/*
* In addition to D28Fx PCICFG 420h[30:29] = 11b,
* set 420h[17] = 0b and 420[0] = 1b for L1 SubState.
*/
pci_update_config32(dev, 0x420, ~0x20000, (3 &lt;&lt; 29) | 1);</pre>
<p>First of all, it&#8217;s checking for the gpio to be native (which is what I did before without success), but it&#8217;s setting the PCI configuration at offset 0x420, but the only offset 0x420 I see in the <a href="https://www-ssl.intel.com/content/dam/www/public/us/en/documents/datasheets/5th-gen-core-family-platform-i-o-datasheet.pdf">datasheet</a> (page 736) is the &#8220;PCI Express* Configuration Register 3&#8221;:</p>
<blockquote>
<pre>Bit    Description

31:1   Reserved 
0      PEC3 Field 1—R/W. BIOS may set this bit to 1b</pre>
</blockquote>
<p>Possibly these 31 &#8220;Reserved&#8221; bits are only described in a confidential Intel document, but in any case I didn&#8217;t know what that code was doing and I wouldn&#8217;t know what to change to make it behave the way I want it to.</p>
<p>I eventually found that this low power mechanism is called &#8220;<a href="https://en.wikipedia.org/wiki/Active_State_Power_Management">ASPM</a>&#8221; and the cbmem output from coreboot had a line that said &#8220;ASPM: enabled L1&#8221; which didn&#8217;t match any string in that soc/intel/broadwell/pcie.c file, so after I searched for the &#8220;ASPM:&#8221; string, I found that there is code in device/pciexp_device.c which is what actually configures the ASPM on the device!</p>
<p>The code in pciexp_device is rather straightforward since it does this:</p>
<blockquote>
<pre>/* Check for and enable Common Clock */
if (IS_ENABLED(CONFIG_PCIEXP_COMMON_CLOCK))
    pciexp_enable_common_clock(root, root_cap, dev, cap);

/* Check if per port CLK req is supported by endpoint*/
if (IS_ENABLED(CONFIG_PCIEXP_CLK_PM))
    pciexp_enable_clock_power_pm(dev, cap);

/* Enable L1 Sub-State when both root port and endpoint support */
if (IS_ENABLED(CONFIG_PCIEXP_L1_SUB_STATE))
    pciexp_config_L1_sub_state(root, dev);

/* Check for and enable ASPM */
if (IS_ENABLED(CONFIG_PCIEXP_ASPM))
    pciexp_enable_aspm(root, root_cap, dev, cap);</pre>
</blockquote>
<p>Unfortunately, those configs for L1_SUB_STATE and CLK_PM are forced-enabled in the menuconfig of coreboot, so I couldn&#8217;t disable it (I had already noticed them before but couldn&#8217;t disable them), so I just changed the code to remove the line that calls the<br />
<em>pciexp_enable_clock_power_pm </em>function, and tested it. I could then see in the cbmem log that coreboot didn&#8217;t enable CLKREQ anymore, but the install was still failing, so I also removed the code that calls  pciexp_config_L1_sub_state, and tried again, and my installation was successful!</p>
<p>I had previously done around 50 installation attempts on that NVMe and the drive would always crash between 50% and 80% through the installation. With my new changes, I had now done 3 successive installs that went all the way to 100% without crashing a single time. This demonstrated that my changes worked, that disabling the CLKREQ+L1.2 substate on the NVMe drive fixed the issue. My &#8220;fix&#8221; was obviously not the most elegant way of solving the issue, but I was now happy to report that we would be able to use the NVMe drives.</p>
<p>Some users might be wondering whether not being able to put their NVMe drives into low power mode would affect battery life, and the answer is, &#8220;In theory yes&#8221;, but in practice the difference would be a very small percentage. Back then, I doubted anyone would actually notice it, and so far it seems nobody did, so it looks like the issue is fairly minor in the grand scheme of things.</p>
<p>Purism customers now had working NVMe support for their Librem laptops running coreboot, and this solved a big headache for our operations &amp; support team (who had temporarily put on hold all NVMe-based orders because of the bug, favouring the SATA-based laptop configurations as they were more reliable at that time).</p>
<p>Interestingly, this also meant that we had a superior user experience to similar laptops with a proprietary BIOS: users now had NVMe drives working with coreboot, NVMe drives that had never worked on the AMI BIOS we compared to!</p>
<p>During my testing of the install script, I had also tweaked some of the coreboot options and we had coreboot booting in about 350 miliseconds, which is a lot faster than the few seconds it took for the AMI BIOS to boot.</p>
<p>My fix was merged into coreboot in July 2017, via these <a href="https://review.coreboot.org/c/coreboot/+/19899">two</a> <a href="https://review.coreboot.org/c/coreboot/+/19900">patches</a> and <a href="https://review.coreboot.org/c/seabios/+/19443">this</a> patch to SeaBIOS.</p>
<h1>Some additional notes…</h1>
<p>One might wonder if a possible reason behind the problem could have been an error in the design of the motherboard on the first-generation librems where the CLKREQ signal wouldn&#8217;t be properly routed, though it doesn&#8217;t <em>look</em> that way according to the schematics, so I&#8217;m not entirely sure why it was happening after all. At least, the fix was &#8220;simple&#8221; enough, and it worked on the Librem 13 v1 I had available to test.</p>
<p>Interestingly enough, François&#8217; NVMe drive kept failing on his Librem 13 v1 after 2 to 3 days of use, even with my final fix. I was unable to figure out why that was still happening back then; why would his NVMe drive go into D3 power state if coreboot wasn&#8217;t enabling the L1.2 substate anymore? We eventually tabled the matter for a while as François switched to the newly released Librem 13 &#8220;version 2&#8221; a few weeks later. The answer came to me completely by chance, a year or so later, as I was looking through some PCIe code and saw that the PCIe device itself could have &#8220;L1.2 support&#8221; set even if it&#8217;s not enabled, so maybe his Linux kernel was enabling L1.2 if it saw that the device &#8220;supported&#8221; it. Unfortunately, by then, Francois wasn&#8217;t able to reproduce the issue on his NVMe drive anymore even with his old laptop, so it was impossible to test our hypothesis. The question of why he had started having those issues &#8220;all of a sudden&#8221; back then (when he didn&#8217;t encounter such issues before) shall remain a mystery!</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/adventures-with-coreboot-and-nvm-express-storage/">Adventures with coreboot and NVM Express storage</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Intel FSP reverse engineering: finding the real entry point!</title>
		<link>https://puri.sm/posts/intel-fsp-reverse-engineering-finding-the-real-entry-point/</link>
		<pubDate>Mon, 02 Apr 2018 13:37:27 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>
		<category><![CDATA[Reverse engineering]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=48306</guid>
		<description><![CDATA[<p>2018-05-10 UPDATE: Intel politely asked Purism to remove this document which Intel believes may conflict with a licensing term. Since this post was informational only and has no impact on the future goals of Purism, we have complied. If you would like the repository link of the Intel FSP provided from Intel, please visit their [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/intel-fsp-reverse-engineering-finding-the-real-entry-point/">Intel FSP reverse engineering: finding the real entry point!</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><i><strong>2018-05-10 UPDATE:</strong> Intel politely asked Purism to remove this document which Intel believes may conflict with a licensing term. Since this post was informational only and has no impact on the future goals of Purism, we have complied. If you would like the repository link of the Intel FSP provided from Intel, please visit their <a href="https://github.com/IntelFsp/FSP/tree/d88078a708e768c7b6ee5cbc996299d303c3c702" target="_blank" rel="noopener">publicly available code</a> on the subject.</i></p>
<p><i><strong>2018-04-23 UPDATE:</strong> after receiving a courtesy request from Intel&#8217;s Director of Software Infrastructure, we have decided to remove this post&#8217;s technical contents while we investigate our options. You are still welcome to learn about reverse engineering in general with my introductory post on the matter, <a href="https://puri.sm/posts/primer-to-reverse-engineering/">Introduction to Reverse Engineering: A Primer Guide</a>.</i></p>
<hr />
<p>Hi everyone, it&#8217;s time for another blog post from your favorite Purism Reverse Engineer (that&#8217;s me! &#8217;cause I&#8217;m the only one&#8230;)!</p>
<p>After attending 34C3 in Leipzig at the end of December, in which we (Zlatan and me) met with some of you, and had a lot of fun, I took some time off to travel Europe and fall victim to the horrible Influenza virus that so many people caught this year. After a couple more weeks of bed rest, I continued my saga in trying to find the <strong>real</strong> entry point of the Intel FSP-S module.<br />
<!-- new summary portion --><br />
Here&#8217;s the non-technical summary of the current situation: I made some good progress in reverse engineering both the FSP-S and FSP-M and I&#8217;m very happy with it so far. Unfortunately, all the code I&#8217;ve seen so far has been about setting up the FSP itself, so I haven&#8217;t actually been able to start reverse engineering the actual Silicon initialization code.</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/intel-fsp-reverse-engineering-finding-the-real-entry-point/">Intel FSP reverse engineering: finding the real entry point!</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>February 2018 coreboot update now available</title>
		<link>https://puri.sm/posts/february-2018-coreboot-update/</link>
		<pubDate>Thu, 22 Feb 2018 22:48:45 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=49020</guid>
		<description><![CDATA[<p>Hey everyone, I&#8217;m happy to announce the release of an update to our coreboot images for Librem 13 v2 and Librem 15 v3 machines. All new laptops will come pre-loaded with this new update, and everyone else can update their machines using our existing build script which was updated to build the newest image. Some [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/february-2018-coreboot-update/">February 2018 coreboot update now available</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Hey everyone, I&#8217;m happy to announce the release of an update to our coreboot images for <strong>Librem 13 v2</strong> and <strong>Librem 15 v3</strong> machines.</p>
<p>All new laptops will come pre-loaded with this new update, and everyone else can update their machines using our existing <a href="https://source.puri.sm/kakaroto/coreboot-files/raw/master/build_coreboot.sh">build script</a> which was updated to build the newest image. Some important remarks:</p>
<ul>
<li>Please read the instructions below to make sure the image gets built properly and <strong>make sure to select the correct machine type</strong> in the menu for the build script.</li>
<li>The build script was initially written as a tool for internal use, and therefore isn&#8217;t as polished as it could be, so if you want something that just quickly applies updates without building/compiling the whole thing, we hope to provide such a (simpler) script in the future.</li>
</ul>
<h1>What&#8217;s new?</h1>
<p>This is a follow up from Kyle&#8217;s previous <a href="https://puri.sm/posts/qubes4-fully-working-on-librem-laptops/">blog post</a>, and now that the image has been fully tested, you can all enjoy it and get one of our most requested feature : VT-d support for Qubes 4.0 to work.</p>
<p>The new version is &#8220;4.7-Purism-1&#8221; and here is the ChangeLog:</p>
<blockquote>
<ul>
<li>​Update to coreboot 4.7</li>
<li>Update to FSP 2.0</li>
<li>Add IOMMU support</li>
<li>Enable TPM support</li>
<li>Fixed ATA errors at 6Gbps</li>
</ul>
</blockquote>
<p>While coreboot 4.7 has not been officially released, it was &#8220;tagged&#8221; on October 31st in coreboot&#8217;s git repository, and this release is based on that tag with the IOMMU (VT-d) and TPM support added on top of it.</p>
<p>If your laptop came with the TPM chip installed, you <strong>need to update your coreboot image</strong> to this version in order to use the TPM hardware.</p>
<h1>How to build it?</h1>
<p>To build the latest coreboot image :</p>
<ol>
<li>Download the <a href="https://source.puri.sm/kakaroto/coreboot-files/raw/master/build_coreboot.sh">build script</a><br />
<code>mkdir building-coreboot &amp;&amp; cd building-coreboot &amp;&amp; wget https://code.wp.puri.sm/kakaroto/coreboot-files/raw/master/build_coreboot.sh</code></li>
<li>Install the required dependencies:<br />
<code>sudo apt-get install git build-essential bison flex m4 zlib1g-dev gnat libpci-dev libusb-dev libusb-1.0-0-dev dmidecode bsdiff python2.7</code></li>
<li>Run the script on your Librem machine:<br />
<code>chmod +x build_coreboot.sh &amp;&amp; ./build_coreboot.sh</code></li>
<li>Follow the instructions on the screen, be sure to select your correct Librem laptop revision (Librem 13v2 or Librem 15v3), and give it time to build the image.</li>
<li>Once done, if everything went according to plan, it will ask you if you want to flash the newly built image</li>
<li>Make sure you are not running on low battery and select Yes</li>
<li>Reboot your machine once the flashing process is done.</li>
</ol>
<p>For matters specifically related to this build script (not related to how to use a TPM per se), you may also want to check out the <a href="https://forums.puri.sm/t/building-coreboot-from-source-official-script/1264" target="_blank" rel="noopener">main forum thread about our coreboot build script</a>, where discussion and testing has been going on over the past few months.</p>
<h1>Verifying the presence of a TPM</h1>
<p>If you are unsure whether or not you have a TPM installed on your system, install the <code>tpm-tools</code> package and then run <code>sudo tpm_version</code> to confirm that a TPM is detected on your system.</p>
<p><code>$ sudo tpm_version<br />
TPM 1.2 Version Info:<br />
Chip Version:        1.2.4.40<br />
Spec Level:          2<br />
Errata Revision:     3<br />
TPM Vendor ID:       IFX<br />
Vendor Specific data: 04280077 0074706d 3631ffff ff<br />
TPM Version:         01010000<br />
Manufacturer Info:   49465800</code></p>
<p>If your machine came with a TPM, you can now take advantage of its capabilities, if you already have particular uses planned for it. Enjoy!</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/february-2018-coreboot-update/">February 2018 coreboot update now available</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>A Primer Guide to Reverse Engineering</title>
		<link>https://puri.sm/posts/primer-to-reverse-engineering/</link>
		<pubDate>Fri, 17 Nov 2017 20:00:15 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>
		<category><![CDATA[Reverse engineering]]></category>
		<category><![CDATA[Software freedom]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=43843</guid>
		<description><![CDATA[<p>Over the years, many people asked me to teach them what I do, or to explain to them how to reverse engineer assembly code in general. Sometimes I hear the infamous &#8220;How hard can it be?&#8221; catchphrase. Last week someone I was discussing with thought that the assembly language is just like a regular programming [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/primer-to-reverse-engineering/">A Primer Guide to Reverse Engineering</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><!--Recently, I've finished <strong>reverse engineering the Intel FSP-S "entry" code,</strong> that is from the entry point (FspSiliconInit) all the way to the end of the function and all the subfunctions that it calls. This is only some initial foray into reverse engineering the FSP as a whole, but reverse engineering is something that takes a lot of time and effort. Today's blog post is here to illustrate that, and to lay the foundations for understanding what I've done with the FSP code (in a future blog post).

-->Over the years, many people asked me to teach them what I do, or to explain to them how to reverse engineer assembly code in general. Sometimes I hear the infamous &#8220;How hard can it be?&#8221; catchphrase. Last week someone I was discussing with thought that the assembly language is just like a regular programming language, but in binary form—it&#8217;s easy to make that mistake if you&#8217;ve never seen what assembly is or looks like. Historically, I&#8217;ve always said that reverse engineering and ASM is &#8220;too complicated to explain&#8221; or that &#8220;If you need help to get started, then you won&#8217;t be able to finish it on your own&#8221; and various other vague responses—I often wanted to explain to others why I said things like that but I never found a way to do it. You see, when something is complex, it&#8217;s easy to say that it&#8217;s complex, but it&#8217;s much harder to explain to people <em>why</em> it&#8217;s complex.</p>
<p>I was lucky to recently stumble onto a little function while reverse engineering<!-- the Intel FSP,--> a function that was both simple and complex, where figuring out what it does was an interesting challenge that I can easily walk you through. This function wasn&#8217;t a difficult thing to understand, and by far, it&#8217;s not one of the hard or complex things to reverse engineer, but this one is &#8220;small and complex enough&#8221; that it&#8217;s a perfect example to explain, without writing an entire book or getting into the more complex aspects of reverse engineering. So <strong>today&#8217;s post serves as a &#8220;primer&#8221; guide to reverse engineering</strong> for all of those interested in the subject. <strong>It is a required read in order to understand the next blog posts I would be writing about reverse engineering.</strong> </p>
<p><strong>Note:</strong> some function and component names in this blog post have been scrambled, with names such as &#8220;BOB&#8221;, &#8220;ALICE&#8221; and &#8220;QUEEN&#8221;.</p>
<p>Ready? Strap on your geek helmet and let&#8217;s get started!</p>
<hr class="ttfmake-hr" style="border-style: dashed; border-top-width: 2px;" />
<p><strong>DISCLAIMER</strong>: I might make false statements in the blog post below, some by mistake, some intentionally for the purpose of vulgarizing the explanations. For example, when I say below that there are 9 registers in X86, I know there are more (SSE, FPU, or even just the DS or EFLAGS registers, or purposefully not mentioning EAX instead of RAX, etc.), but I just don&#8217;t want to complicate matters by going too wide in my explanations.</p>
<hr class="ttfmake-hr" style="border-style: dashed; border-top-width: 2px;" />
<h1>A prelude</h1>
<p>First things first, you need to understand some basic concepts, such as &#8220;what is ASM exactly&#8221;. I will explain some basic concepts but not <em>all</em> the basic concepts you might need. I will assume that you know at least what a programming language is and know how to write a simple &#8220;hello world&#8221; in at least one language, otherwise you&#8217;ll be completely lost.</p>
<p>So, ASM is the Assembly language, but it&#8217;s not the actual binary code that executes on the machine. It is however, very similar to it. To be more exact, the assembly language is a textual representation of the binary instructions given to the microprocessor. You see, when you compile your regular C program into an executable, the compiler will transform all your code into some very, very, very basic instructions. Those instructions are what the CPU will understand and execute. By combining a lot of small, simple and specific instructions, you can do more complex things. That&#8217;s the basis of any programming language, of course, but with assembly, the building blocks that you get are very limited. Before I&#8217;ll talk about instructions, I want to explain two concepts first which you&#8217;ll need to follow the rest of the story.</p>
<h2>The stack</h2>
<p>First I&#8217;ll explain what &#8220;the stack&#8221; is.  You may have heard of it before, or maybe you didn&#8217;t, but the important thing to know is that when you write code, you have two types of memory:</p>
<ul>
<li>The first one is your &#8220;dynamic memory&#8221;, that&#8217;s when you call &#8216;malloc&#8217; or &#8216;new&#8217; to allocate new memory, this goes from your RAM upward (or left-to-right), in the sense that if you allocate 10 bytes, you&#8217;ll first get address 0x1000 for example, then when you allocate another 30 bytes, you&#8217;ll get address 0x100A, then if you allocate another 16 bytes, you&#8217;ll get 0x1028, etc.</li>
<li>The second type of memory that you have access to is the <em>stack,</em> which is different, instead it grows downward (or right-to-left), and it&#8217;s used to store local variables in a function. So if you start with the stack at address 0x8000, then when you enter a function with 16 bytes worth of local variables, your stack now points to address 0x7FF0, then you enter another function with 64 bytes worth of local variables, and your stack now points to address 0x7FB0, etc. The way the stack works is by &#8220;stacking&#8221; data into it, you &#8220;push&#8221; data in the stack, which puts the variable/data into the stack and moves the stack pointer down, you can&#8217;t remove an item from anywhere in the stack, you can always only remove (pop) the last item you added (pushed). A stack is actually an abstract type of data, like a list, an array, a dictionary, etc. You can read more about what a stack is on <a href="https://en.wikipedia.org/wiki/Stack_(abstract_data_type)">wikipedia</a> and it shows you how you can add and remove items on a stack with this image:</li>
</ul>
<p><img class="alignnone size-medium" src="https://upload.wikimedia.org/wikipedia/commons/b/b4/Lifo_stack.png" width="773" height="540" /></p>
<p>The image shows you what we call a LIFO (Last-In-First-Out) and that&#8217;s what a stack is. In the case of the computer&#8217;s stack, it grows downward in the RAM (as opposed to upward in the above image) and is used to store local variables as well as the return address for your function (the instruction that comes after the call to your function in the parent function). So when you look at a stack, you will see multiple &#8220;frames&#8221;, you&#8217;ll see your current function&#8217;s stack with all its variables, then the return address of the function that called it, and above it, you&#8217;ll see the previous function&#8217;s frame with its own variables and the address of the function that called it, and above, etc. all the way to the main function which resides at the top of the stack.</p>
<p>Here is another image that exemplifies this:</p>
<p><img class="alignnone size-medium" src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/ProgramCallStack2_en.png/350px-ProgramCallStack2_en.png" width="350" height="416" /></p>
<h2>The registers</h2>
<p>The second thing I want you to understand is that the processor has multiple &#8220;registers&#8221;. You can think of a register as a variable, but there are only 9 total registers on x86, with only 7 of them usable. So, on the x86 processor, the various registers are: EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP, EIP.</p>
<p>There are two registers in there that are special:</p>
<ul>
<li>The EIP (Instruction Pointer) contains the address of the current instruction being executed.</li>
<li>The ESP (Stack Pointer) contains the address of the stack.</li>
</ul>
<p>Access to the registers is extremely fast when compared to accessing the data in the RAM (the stack also resides on the RAM, but towards the end of it) and most operations (instructions) have to happen on registers. You&#8217;ll understand more when you read below about instructions, but basically, you can&#8217;t use an instruction to say &#8220;add value A to value B and store it into address C&#8221;, you&#8217;d need to say &#8220;move value A into register EAX, then move value B into register EBX, then add register EAX to register EBX and store the result in register ECX, then store the value of register ECX into the address C&#8221;.</p>
<h2>The instructions</h2>
<p>Let&#8217;s go back to explaining instructions now. As I explained before, the instructions are the basic building blocks of the programs, and they are very simple, they take the form of:</p>
<pre>INS OP1, OP2, OP3</pre>
<p>Where &#8220;INS&#8221; is the instruction&#8221;, and OP1, OP2, OP3 is what we call the &#8220;operand&#8221;, most instructions will only take 2 operands, some will take no operands, some will take one operand and others will take 3 operands. The operands are usually registers. Sometimes, the operand can be an actual value (what we call an &#8220;immediate value&#8221;) like &#8220;1&#8221;, &#8220;2&#8221; or &#8220;3&#8221;, etc. and sometimes, the operand is a relative position from a register, like for example &#8220;[%eax + 4]&#8221; meaning the address pointed to by the %eax register + 4 bytes. We&#8217;ll see more of that shortly. For now, let&#8217;s give you the list of the most common and used instructions:</p>
<ul>
<li>&#8220;<a href="https://x86.puri.sm/html/file_module_x86_id_176.html">MOV</a>&#8220;: move data from one operand into another</li>
<li>&#8220;<a href="https://x86.puri.sm/html/file_module_x86_id_5.html">ADD</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_308.html">SUB</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_210.html">MUL</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_72.html">DIV</a>&#8220;: Add, Substract, Multiply, Divide one operand with another and store the result in a register</li>
<li>&#8220;<a href="https://x86.puri.sm/html/file_module_x86_id_12.html">AND</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_219.html">OR</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_330.html">XOR</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_218.html">NOT</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_216.html">NEG</a>&#8220;: Perform logical and/or/xor/not/negate operations on the operand</li>
<li>&#8220;<a href="https://x86.puri.sm/html/file_module_x86_id_285.html">SHL</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_285.html">SHR</a>&#8220;: Shift Left/Shift Right the bits in the operand</li>
<li>&#8220;<a href="https://x86.puri.sm/html/file_module_x86_id_35.html">CMP</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_315.html">TEST</a>&#8220;: Compare one register with an operand</li>
<li>&#8220;<a href="https://x86.puri.sm/html/file_module_x86_id_147.html">JMP</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_146.html">JZ</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_146.html">JNZ</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_146.html">JB</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_146.html">JS</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_146.html">etc</a>.&#8221;: Jump to another instruction (Jump unconditionally, Jump if Zero, Jump if Not Zero, Jump if Below, Jump if Sign, etc.)</li>
<li>&#8220;<a href="https://x86.puri.sm/html/file_module_x86_id_269.html">PUSH</a>/<a href="https://x86.puri.sm/html/file_module_x86_id_248.html">POP</a>&#8220;: Push an operand into the stack, or pop a value from the stack into a register</li>
<li>&#8220;<a href="https://x86.puri.sm/html/file_module_x86_id_26.html">CALL</a>&#8220;: Call a function. This is the equivalent of doing a &#8220;PUSH %EIP+4&#8221; + &#8220;JMP&#8221;. I&#8217;ll get into calling conventions later..</li>
<li>&#8220;<a href="https://x86.puri.sm/html/file_module_x86_id_280.html">RET</a>&#8220;: Return from a function. This is the equivalent of doing a &#8220;POP %EIP&#8221;</li>
</ul>
<p>That&#8217;s about it, that&#8217;s what most programs are doing. Of course, there&#8217;s a lot more instructions, you can see a full list <a href="https://x86.puri.sm/">here</a>, but you&#8217;ll see that most of the other instructions are very obscure or very specific or variations on the above instructions, so really, this represents most of the instructions you&#8217;ll ever encounter.</p>
<p>I want to explain one thing before we go further down: there is an additional register I didn&#8217;t mention before called the <a href="https://en.wikipedia.org/wiki/FLAGS_register">FLAGS register</a>, which is basically just a status register that contains &#8220;flags&#8221; that indicate when some arithmetic condition happened on the last arithmetic operation. For example, if you add 1 to 0xFFFFFFFF, it will give you &#8216;0&#8217; but the &#8220;<a href="https://en.wikipedia.org/wiki/Overflow_flag">Overflow flag</a>&#8221; will be set in the FLAGS register. If you substract 5 from 0, it will give you 0xFFFFFFFB and the &#8220;<a href="https://en.wikipedia.org/wiki/Sign_flag">Sign flag</a>&#8221; will be set because the result is negative, and if you substract 3 from 3, the result will be zero and the &#8220;<a href="https://en.wikipedia.org/wiki/Zero_flag">Zero flag</a>&#8221; will be set.</p>
<p>I&#8217;ve shown you the &#8220;CMP&#8221; instruction which is used to compare a register with an operand, but you might be wondering, &#8220;What does it mean exactly to &#8216;compare&#8217;?&#8221; Well, it&#8217;s simple, the CMP instruction is the same thing as the SUB instruction, in that, it substracts one operand from another, but the difference is that it doesn&#8217;t store the result anywhere. However, it does get your flags updated in the FLAGS register. For example, if I wanted to compare %EAX register with the value &#8216;2&#8217;, and %EAX contains the value 3, this is what&#8217;s going to happen: you will substract 2 from the value, the result will be 1, but you don&#8217;t care about that, what you care about is that the ZF (Zero flag) is not set, and the SF (Sign flag is not set), which means that %eax and &#8216;2&#8217; are not equal (otherwise, ZF would be set), and that the value in %eax is superior to 2 (because SF is not set), so you know that &#8220;%eax &gt; 2&#8221; and that&#8217;s what the CMP does.</p>
<p>The TEST instruction is very similar but it does a logical AND on the two operands for testing, so it&#8217;s used for comparing logical values instead of arithmetic values (&#8220;TEST %eax, 1&#8221; can be used to check if %eax contains an odd or even number for example).</p>
<p>This is useful because the next bunch of instructions I explained in the list above is conditional Jump instructions, like &#8220;JZ&#8221; (jump if zero) or &#8220;JB&#8221; (jump if below), or &#8220;JS&#8221; (jump if sign), etc. This is what is used to implement &#8220;if, for, while, switch/case, etc.&#8221; it&#8217;s as simple as doing a &#8220;CMP&#8221; followed by a &#8220;JZ&#8221; or &#8220;JNZ&#8221; or &#8220;JB&#8221;, &#8220;JA&#8221;, &#8220;JS&#8221;, etc.</p>
<p>And if you&#8217;re wondering what&#8217;s the difference between a &#8220;Jump if below&#8221; and &#8220;Jump if sign&#8221; and &#8220;Jump if lower&#8221;, since they all mean that the comparison gave a negative result, right? Well, the &#8220;jump if below&#8221; is used for unsigned integers, while &#8220;jump if lower&#8221; is used for signed integers, while &#8220;jump if sign&#8221; can be misleading. An unsigned 3 &#8211; 4 would give us a very high positive result&#8230;  something like that, in practice, JB checks the <a href="https://en.wikipedia.org/wiki/Carry_flag">Carry Flag</a>, while JS checks the <a href="https://en.wikipedia.org/wiki/Sign_flag">Sign Flag</a> and JL checks if the Sign Flag is equal to the <a href="https://en.wikipedia.org/wiki/Overflow_flag">Overflow flag</a>. See the <a href="https://x86.puri.sm/html/file_module_x86_id_146.html">Conditional Jump</a> page for more details.</p>
<h2>A practical example</h2>
<p>Here&#8217;s a very small and simple practical example, if you have a simple C program like this:</p>
<pre>int main() {
   return add_a_and_b(2, 3);
}

int add_a_and_b(int a, int b) {
   return a + b;
}</pre>
<p>It would compile into something like this:</p>
<pre>_main:
   push   3                ; Push the second argument '3' into the stack
   push   2                ; Push the first argument '2' into the stack
   call   _add_a_and_b     ; Call the _add_a_and_b function. This will put the address of the next
                           ; instruction (add) into the stack, then it will jump into the _add_a_and_b
                           ; function by putting the address of the first instruction in the _add_a_and_b
                           ; label (push %ebx) into the EIP register
   add    %esp, 8          ; Add 8 to the esp, which effectively pops out the two values we just pushed into it
   ret                     ; Return to the parent function.... 

_add_a_and_b:
   push   %ebx             ; We're going to modify %ebx, so we need to push it to the stack
                           ; so we can restore its value when we're done
   mov    %eax, [%esp+8]   ; Move the first argument (8 bytes above the stack pointer) into EAX
   mov    %ebx, [%esp+12]  ; Move the second argument (12 bytes above the stack pointer) into EBX
   add    %eax, %ebx       ; Add EAX and EBX and store the result into EAX
   pop    %ebx             ; Pop EBX to restore its previous value
   ret                     ; Return back into the main. This will pop the value on the stack (which was
                           ; the address of the next instruction in the main function that was pushed into
                           ; the stack when the 'call' instruction was executed) into the EIP register</pre>
<p>Yep, something as simple as that, can be quite complicated in assembly. Well, it&#8217;s not really that complicated actually, but a couple of things can be confusing.</p>
<p>You have only 7 usable registers, and one stack. Every function gets its arguments passed through the stack, and can return its return value through the %eax register. If every function modified every register, then your code will break, so every function has to ensure that the other registers are unmodified when it returns (other than %eax). You pass the arguments on the stack and your return value through %eax, so what should you do if need to use a register in your function? Easy: you keep a copy on the stack of any registers you&#8217;re going to modify so you can restore them at the end of your function. In the _<em>add_a_and_b </em>function, I did that for the %ebx register as you can see. For more complex function, it can get a lot more complicated than that, but let&#8217;s not get into that for now (for the curious: compilers will create what we call a &#8220;prologue&#8221; and an &#8220;epilogue&#8221; in each function. In the prologue, you store the registers you&#8217;re going to modify, set up the %ebp (base pointer) register to point to the base of the stack when your function was entered, which allows you to access things without keeping track of the pushes/pops you do throughout the function, then in the epilogue, you pop the registers back, restore %esp to the value that was saved in %ebp, before you return).</p>
<p>The second thing you might be wondering about is with these lines:</p>
<pre>mov %eax, [%esp+8]
mov %ebx, [%esp+12]</pre>
<p>And to explain it, I will simply show you this drawing of the stack&#8217;s contents when we call those two instructions above:</p>
<p><img class="alignnone size-medium wp-image-43904" src="https://puri.sm/wp-content/uploads/2017/11/stack-300x259.png" alt="" width="300" height="259" srcset="https://puri.sm/wp-content/uploads/2017/11/stack-300x259.png 300w, https://puri.sm/wp-content/uploads/2017/11/stack-768x664.png 768w, https://puri.sm/wp-content/uploads/2017/11/stack.png 898w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<p>For the purposes of this exercise, we&#8217;re going to assume that the _main function is located in memory at the address 0xFFFF0000, and that each instructoin is 4 bytes long (the size of each instruction can vary depending on the instruction and on its operands). So you can see, we first pushed 3 into the stack, %esp was lowered, then we pushed 2 into the stack, %esp was lowered, then we did a &#8216;call _add_a_and_b&#8217;, which stored the address of the next instruction (4 instructions into the main, so &#8216;_main+16&#8217;) into the stack and esp was lowered, then we pushed %ebx, which I assumed here contained a value of 0, and the %esp was lowered again. If we now wanted to access the first argument to the function (2), we need to access %esp+8, which will let us skip the saved %ebx and the &#8216;Return address&#8217; that are in the stack (since we&#8217;re working with 32 bits, each value is 4 bytes). And in order to access the second argument (3), we need to access %esp+12.</p>
<h2>Binary or assembly?</h2>
<p>One question that may (or may not) be popping into your mind now is &#8220;wait, isn&#8217;t this supposed to be the &#8216;computer language&#8217;, so why isn&#8217;t this binary?&#8221; Well, it is&#8230; in a way. As I explained earlier, &#8220;the assembly language is a textual representation of the binary instructions given to the microprocessor&#8221;, what it means is that those instructions are given to the processor as is, there is no transformation of the instructions or operands or anything like that. However, the instructions are given to the microprocessor in binary form, and the text you see above is just the textual representation of it.. kind of like how &#8220;68 65 6c 6c 6f&#8221; is the hexadecimal representation of the ASCII text &#8220;hello&#8221;. What this means is that each instruction in assembly language, which we call a &#8216;mnemonic&#8217; represents a binary instruction, which we call an &#8216;opcode&#8217;, and you can see the opcodes and mnemonics in the <a href="https://x86.puri.sm/">list</a> of x86 instructions I gave you above. Let&#8217;s take the <a href="https://x86.puri.sm/html/file_module_x86_id_26.html">CALL</a> instruction for example. The opcode/mnemonic list is shown as:</p>
<table class="box">
<tbody>
<tr>
<th>Opcode</th>
<th>Mnemonic</th>
<th>Description</th>
</tr>
<tr>
<td class="grid"><code>E8 cw</code></td>
<td class="grid"><code>CALL rel16</code></td>
<td class="grid">Call near, relative, displacement relative to next instruction</td>
</tr>
<tr>
<td class="grid"><code>E8 cd</code></td>
<td class="grid"><code>CALL rel32</code></td>
<td class="grid">Call near, relative, displacement relative to next instruction</td>
</tr>
<tr>
<td class="grid"><code>FF /2</code></td>
<td class="grid"><code>CALL r/m16</code></td>
<td class="grid">Call near, absolute indirect, address given in r/m16</td>
</tr>
<tr>
<td class="grid"><code>FF /2</code></td>
<td class="grid"><code>CALL r/m32</code></td>
<td class="grid">Call near, absolute indirect, address given in r/m32</td>
</tr>
<tr>
<td class="grid"><code>9A cd</code></td>
<td class="grid"><code>CALL ptr16:16</code></td>
<td class="grid">Call far, absolute, address given in operand</td>
</tr>
<tr>
<td class="grid"><code>9A cp</code></td>
<td class="grid"><code>CALL ptr16:32</code></td>
<td class="grid">Call far, absolute, address given in operand</td>
</tr>
<tr>
<td class="grid"><code>FF /3</code></td>
<td class="grid"><code>CALL m16:16</code></td>
<td class="grid">Call far, absolute indirect, address given in m16:16</td>
</tr>
<tr>
<td class="grid"><code>FF /3</code></td>
<td class="grid"><code>CALL m16:32</code></td>
<td class="grid">Call far, absolute indirect, address given in m16:32</td>
</tr>
</tbody>
</table>
<p>This means that this same &#8220;CALL&#8221; mnemonic can have multiple addresses to call. Actually, there are four different possitiblities, each having a 16 bits and a 32 bits variant. The first possibility is to call a function with a relative displacement (Call the function 100 bytes below this current position), or an absolute address given in a register (Call the function whose address is stored in %eax) or an absolute address given as a pointer (Call the function at address 0xFFFF0100), or an absolute address given as an offset to a segment (I won&#8217;t explain segments now). In our example above, the &#8220;call _add_a_and_b&#8221; was probably stored as a call relative to the current position with 12 bytes below the current instruction (4 bytes per instruction, and we have the CALL, ADD, RET instructions to skip). This means that the instruction in the binary file was encoded as &#8220;E8 00 00 00 0C&#8221; (The E8 opcode to mean a &#8220;CALL near, relative&#8221;, and the &#8220;00 00 00 0C&#8221; to mean 12 bytes relative to the current instruction). Now, the most observant of you have probably noticed that this CALL instruction takes 5 bytes total, not 4, but as I said above, we will assume it&#8217;s 4 bytes per instruction just for the sake of keeping things simple, but yes, the CALL (in this case) is 5 bytes, and other instructions will sometimes have more or less bytes as well.</p>
<p>I chose the CALL function above for example, because I think it&#8217;s the least complicated to explain.. other instructions have even more complicated opcodes and operands (See the <a href="https://x86.puri.sm/html/file_module_x86_id_5.html">ADD</a> and <a href="https://x86.puri.sm/html/file_module_x86_id_4.html">ADC</a> (Add with Cary) instructions for example, you&#8217;ll notice the same opcodes shared between them even, so they are the same instruction, but it&#8217;s easy to give them separate mnemonics to differentiate their behaviors).</p>
<p>Here&#8217;s a screenshot showing a side by side view of the Assembly of a function with the hexadecimal view of the binary:</p>
<p><img class="alignnone size-large wp-image-44228" src="https://puri.sm/wp-content/uploads/2017/11/ida_hex-1024x475.png" alt="" width="960" height="445" srcset="https://puri.sm/wp-content/uploads/2017/11/ida_hex-1024x475.png 1024w, https://puri.sm/wp-content/uploads/2017/11/ida_hex-300x139.png 300w, https://puri.sm/wp-content/uploads/2017/11/ida_hex-768x357.png 768w, https://puri.sm/wp-content/uploads/2017/11/ida_hex.png 1385w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p>As you can see, I have my cursor on address 0xFFF6E1D6 on the assembly view on the left, which is also highlighted on the hex view on the right. That address is a CALL instruction, and you can see the equivalent hex of &#8220;E8 B4 00 00 00&#8221;, which means it&#8217;s a CALL near, relative (E8 being the opcode for it) and the function is 0xB4 (180) bytes below our current position of 0xFFF6E1D6.</p>
<p>If you open the file with a hexadecimal editor, you&#8217;ll only see the hex view on the right, but you need to put the file into a Disassembler (such as the IDA disassembler which I&#8217;m using here, but there are cheaper alternatives as well, <a href="https://en.wikibooks.org/wiki/X86_Disassembly/Disassemblers_and_Decompilers">the list</a> can be long), and the disassembler will interpret those binary opcodes to show you the textual assembly representation which is much much easier to read.</p>
<h1>Some actual reverse engineering</h1>
<p>Now that you have the basics, let&#8217;s do a quick reverse engineering exercise&#8230; This is a very simple function that I&#8217;ve reversed recently, it comes from the SiliconInit<!-- part of the FSP-->, and it&#8217;s used to validate the UPD configuration structure (used to tell it what to do).</p>
<p>Here is the Assembly code for that function:</p>
<p><img class="alignnone size-full wp-image-43908" src="https://puri.sm/wp-content/uploads/2017/11/validate_upd_config.png" alt="" width="854" height="660" srcset="https://puri.sm/wp-content/uploads/2017/11/validate_upd_config.png 854w, https://puri.sm/wp-content/uploads/2017/11/validate_upd_config-300x232.png 300w, https://puri.sm/wp-content/uploads/2017/11/validate_upd_config-768x594.png 768w" sizes="(max-width: 854px) 100vw, 854px" /></p>
<p>This was disassembled using <a href="https://www.hex-rays.com/products/ida/">IDA</a> 7.0 (The Interactive DisAssembler) which is an incredible (but expensive) piece of software. There are other disassemblers which can do similar jobs, but I prefer IDA personally. Let&#8217;s first explain what you see on the screen.</p>
<p>On the left side, you see &#8220;seg000:FFF40xxx&#8221; this means that we are in the segment &#8220;seg000&#8221; at the address 0xFFF40xxx. I won&#8217;t explain what a segment is, because you don&#8217;t need to know it. The <em>validate_upd_config</em> function starts at address 0xFFF40311 in the RAM, and there&#8217;s not much else to understand. You can see how the address increases from one instruction to the next, it can help you calculate the size in bytes that each instruction takes in RAM for example, if you&#8217;re curious of course&#8230; (the XOR is 2 bytes, the CMP is 2 bytes, etc.).</p>
<p>As you&#8217;ve seen in my previous example, anything after a semicolon (&#8220;;&#8221;) is considered a comment and can be ignored. The &#8220;CODE XREF&#8221; comments are added by IDA to tell us that this code has a cross-references (is being called by) some other code. So when you see &#8220;CODE XREF: validate_upd_config+9&#8221; (at 0xFF40363, the RETN instruction), it means this instruction is being called (referenced by) from the function validate_upd_config and the &#8220;+9&#8221; means 9 bytes into the function (so since the function starts at 0xFFF40311, it means it&#8217;s being called from the instruction at offset 0xFFF4031A. The little &#8220;up&#8221; arrow next to it means that it comes from above the current position in the code, and if you follow the grey lines on the left side of the screen, you can follow that call up to the address 0xFFF4031A which contains the instruction &#8220;jnz short locret_FFF40363&#8221;. I assume the &#8220;j&#8221; letter right after the up arrow is to tell us that the reference comes from a &#8220;jump&#8221; instruction.</p>
<p>As you can see in the left side of the screen, there are a lot of arrows, that means that there&#8217;s a lot of jumping around in the code, even though it&#8217;s not immediatly obvious. The awesome IDA software has a &#8220;layout view&#8221; which gives us a much nicer view of the code, and it looks like this:</p>
<p><img class="alignnone size-full wp-image-43911" src="https://puri.sm/wp-content/uploads/2017/11/validate_upd_config_graph.png" alt="" width="867" height="778" srcset="https://puri.sm/wp-content/uploads/2017/11/validate_upd_config_graph.png 867w, https://puri.sm/wp-content/uploads/2017/11/validate_upd_config_graph-300x269.png 300w, https://puri.sm/wp-content/uploads/2017/11/validate_upd_config_graph-768x689.png 768w" sizes="(max-width: 867px) 100vw, 867px" /></p>
<p>Now you can see each block of code separately in their own little boxes, with arrows linking all of the boxes together whenever a jump happens. The green arrows mean that it&#8217;s a conditional jump when the condition is successful, while the red arrows means the condition was not successful. This means that a &#8220;JZ&#8221; will show a green arrow towards the code it would jump to if the result is indeed zero, and a red arrow towards the block where the result is not zero. A blue arrow means that it&#8217;s an unconditional jump.</p>
<p>I usually always do my reverse engineering using the layout view, I find it much easier to read/follow, but for the purpose of this exercise, I will use the regular linear view instead, so I think it will be easier for you to follow with that instead. The reason is mostly because the layout view doesn&#8217;t display the address of each instruction, and it&#8217;s easier to have you follow along if I can point out exactly which instruction I&#8217;m looking it by mentioning its address.</p>
<p>Now that you know how to read the assembly code, you understand the various instructions, I feel you should be ready to reverse engineering this very simple assembly code (even though it might seem complex at first). I just need to give you the following hints first:</p>
<ul>
<li>Because I&#8217;ve already reversed engineering it, you get the beautiful name &#8220;validate_upd_config&#8221; for the function, but technically, it was simply called &#8220;sub_FFF40311&#8221;</li>
<li>I had already reverse engineered the function that called it so I know that this function is receiving its arguments in an unusual way. The arguments aren&#8217;t pushed to the stack, instead, the first argument is stored in %ecx, and the second argument is stored in %edx</li>
<li>The first argument (%ecx, remember?) is an enum to indicate what type of UPD structure to validate, let me help you out and say that type &#8216;3&#8217; is &#8220;ALICE&#8221; (The configuration structure for the QueenM<!--FSPM-->, the MemoryInit function), and that type &#8216;5&#8217; is &#8220;BOB&#8221; (The configuration structure for the QueenS<!--FSPS-->, the SiliconInit function).</li>
<li>Reverse engineering is really about reading one line at a time, in a sequential manner, keep track of which blocks you reversed and be patient. You can&#8217;t look at it and expect to understand the function by viewing the big picture.</li>
<li>It is very very useful in this case to have a dual monitor, so you can have one monitor for the assembly, and the other monitor for your C code editor. In my case, I actually recently bought an ultra-wide monitor and I split screen between my IDA window and my emacs window and it&#8217;s great. It&#8217;s hard otherwise to keep going back and forth between the assembly and the C code. That being said, I would suggest you do the same thing here and have a window on the side showing you the assembly image above (not the layout view) while you read the explanation on how to reverse engineer it below.</li>
</ul>
<p>Got it? All done? No? Stop sweating and hyperventilating&#8230; I&#8217;ll explain exactly how to reverse engineer this function in the next paragraph, and you will see how simple it turns out to be!</p>
<h2>Let&#8217;s get started!</h2>
<p>The first thing I do is write the function in C. Since I know the name and its arguments already, I&#8217;ll do that:</p>
<pre>void validate_upd_config (uint8_t action, void *config) {
}</pre>
<p>Yeah, there&#8217;s not much to it yet, and I set it to return &#8220;void&#8221; because I don&#8217;t know if it returns anything else, and I gave the first argument &#8220;action&#8221; as a &#8220;uint8_t&#8221; because in the parent function it&#8217;s used a single byte register (I won&#8217;t explain for now how to differentiate 1-byte, 2-bytes, 4-bytes and 8-bytes registers). The second argument is a pointer, but I don&#8217;t know it&#8217;s a pointer to what kind of structure exactly, so I just set it as a <em>void *</em>.</p>
<p>The first instruction is a &#8220;xor eax, eax&#8221;. What does this do? It XORs the eax register with the eax register and stores the result in the eax register itself, which is the same thing as &#8220;mov eax, 0&#8221;, because <em>1 XOR 1= 0</em> and <em>0 XOR 0 = 0</em>, so if every bit in the eax register is logically XORed with itself, it will give 0 for the result. If you&#8217;re asking yourself &#8220;Why did the compiler decide to do &#8216;xor eax, eax&#8217; instead of &#8216;mov eax, 0&#8217; ?&#8221; then the answer is simple: &#8220;Because it takes less CPU clock cycles to do a XOR, than to do a move&#8221;, which means it&#8217;s more optimized and it will run faster. Besides, the XOR takes 2 bytes as you can see above (the address of the instructions jumped from FFF40311 to FFF40313), while a &#8220;mov eax, 0&#8221; would have taken 5 bytes. So it also helps keep the code smaller.</p>
<p>Alright, so now we know that eax is equal to 0, let&#8217;s keep that in mind and move along (I like to keep track of things like that as comments in my C code). Next instruction does a &#8220;cmp ecx, 3&#8221;, so it&#8217;s comparing ecx, which we already know is our first argument (uint8_t action), ok, it&#8217;s a comparison, not much to do here, again let&#8217;s keep that in mind and continue&#8230; the next instruction does a &#8220;jnz short loc_FFF40344&#8221;, which is more interesting, so if the previous comparison is NOT ZERO, then jump to the label loc_FFF40344 (for now ignore the &#8220;short&#8221;, it just helps us differentiate between the various mnemonics, and it means that the jump is a relative offset that fits in a &#8220;short word&#8221; which means 2 bytes, and you can confirm that the jnz instruction does indeed take only 2 bytes of code). Great, so there&#8217;s a jump if the result is NOT ZERO, which means that if the result is zero, the code will just continue, which means if the ecx register (action variable) is EQUAL (substraction is zero) to 3, the code will continue down to the next instruction instead of jumping&#8230; let&#8217;s do that, and in the meantime we&#8217;ll update our C code:</p>
<pre>void validate_upd_config (uint8_t action, void *config) {
   // eax = 0
   if (action == 3) {
      // 0xFFF40318 
   } else {
      // loc_FFF40344
   }
}</pre>
<p>The next instruction is &#8220;test edx, edx&#8221;.  We know that the edx register is our second argument which is the pointer to the configuration structure. As I explained above, the &#8220;test&#8221; is just like a comparison, but it does an AND instead of a substraction, so basically, you AND edx with itself.. well, of course, that has no consequence, <em>1 AND 1 = 1</em>, and <em>0 AND 0 = 0</em>, so why is it useful to test a register against itself? Simply because the TEST will update our FLAGS register&#8230; so when the next instruction is &#8220;JZ&#8221; it basically means &#8220;Jump if the edx register was zero&#8221;&#8230; And yes, doing a &#8220;TEST edx, edx&#8221;  is more optimized than doing a &#8220;CMP edx, 0&#8221;, you&#8217;re starting to catch on, yeay!</p>
<p>And indeed, the next instruction is &#8220;jz locret_FFF40363&#8221;, so if the edx register is ZERO, then jump to locret_FFF40363, and if we look at that locret_FFF40363, it&#8217;s a very simple &#8220;retn&#8221; instruction. So our code becomes:</p>
<pre>void validate_upd_config (uint8_t action, void *config) {
  // eax = 0
  if (action == 3) {
    if (config == NULL)
       return; 
  } else {
    // loc_FFF40344
  }
}</pre>
<p>Next! Now it gets slightly more complicated&#8230; the instruction is: &#8220;cmp dword ptr [edx], 554C424Bh&#8221;, which means we do a comparison of a dword (4 bytes), of the data pointed to by the pointer edx, with no offset (&#8220;[edx]&#8221; is the same as saying &#8220;edx[0]&#8221; if it was a C array for example), and we compare it to the value 554C424Bh&#8230; the &#8220;h&#8221; at the end means it&#8217;s a hexadecimal value, and with experience you can quickly notice that the hexadecimal value is all within the ASCII range, so using a Hex to ASCII converter, we realize that those 4 bytes represent the ASCII letters &#8220;KBLU&#8221; (which is why I manually added them as a comment to that instruction, so I won&#8217;t forget). So basically the instruction compares the first 4 bytes of the structure (the content pointed to by the edx pointer) to the string &#8220;KBLU&#8221;. The next instruction does a &#8220;jnz loc_FFF4035E&#8221; which means that if the comparison result is NOT ZERO (so, if they are not equal) we jump to loc_FFF4035E.</p>
<p>Instead of continuing sequentially, I will see what that loc_FFF4035E contains (of course, I did the same thing in all the previous jumps, and had to decide if I wanted to continue reverse engineering the jump or the next instruction, in this case, it seems better for me to jump, you&#8217;ll see why soon). The loc_FFF4035E label contains the following instruction: &#8220;mov, eax, 80000002h&#8221;, which means it stores the value 0x80000002 into the eax register, and then it jumps to (not really, it just naturally flows to the next instruction which happens to be the label) locret_FFF40363, which is just a &#8220;retn&#8221;. This makes our code into this:</p>
<pre>uint32_t validate_upd_config (uint8_t action, void *config) {
  // eax = 0
  if (action == 3) {
    if (config == NULL)
       return 0; 
    if (((uint32_t *)config)[0] != 0x554C524B)
       return 0x80000002;
  } else {
    // loc_FFF40344
  }
}</pre>
<p>The observant here will notice that I&#8217;ve changed the function prototype to return a uint32_t instead of &#8220;void&#8221; and my previous &#8220;return&#8221; has become &#8220;return 0&#8221; and the new code has a &#8220;return 0x80000002&#8221;. That&#8217;s because I realized at this point that the &#8220;eax&#8221; register is used to return a uint32_t value. And since the first instruction was &#8220;xor eax, eax&#8221;, and we kept in the back of our mind that &#8220;eax is initialized to 0&#8221;, it means that the use case with the (config == NULL) will return 0. That&#8217;s why I made all these changes&#8230;</p>
<p>Very well, let&#8217;s go back to where we were, since we&#8217;ve exhausted this jump, we&#8217;ll jump back in reverse to go back to the address FFF40322 and continue from there to the next instruction. It&#8217;s a &#8220;cmp dword ptr [edx+4], 4D5F4450h&#8221;, which compares the dword at edx+4 to 0x4D5F4450, which I know to be the ASCII for &#8220;PD_M&#8221;; this means that the last 3 instructions are used to compare the first 8 bytes of our pointer to &#8220;KBLUPD_M&#8221;&#8230; ohhh, light bulb above our heads, it&#8217;s comparing the pointer to the Signature of the ALICE structure (don&#8217;t forget, you weren&#8217;t supposed to know that the function is called validate_upd_config, or that the argument is a config pointer&#8230; just that it&#8217;s a pointer)! OK, now it makes sense, and while we&#8217;re at it—and since we are, of course, reading the QUEEN integration guide PDF, we then also realize what the 0x80000002 actually means. At this point, our code now becomes:</p>
<pre>EFI_STATUS validate_upd_config (uint8_t action, void *config) {
  if (action == 3) {
    ALICE *upd = (ALICE *) config;
    if (upd == NULL)
       return EFI_SUCCESS; 
    if (upd-&gt;QueenUpdHeader.Signature != 0x4D5F4450554C524B /* 'KBLUPD_M'*/)
       return EFI_INVALID_PARAMETERS;
  } else {
    // loc_FFF40344
  }
}</pre>
<p>Yay, this is starting to look like something&#8230; Now you probably got the hang of it, so let&#8217;s do things a little faster now.</p>
<ul>
<li>The next line &#8220;cmp [edx+28h], eax&#8221; compares edx+0x28 to eax. Thankfully, we know now that edx points to the ALICE structure, and we can calculate that at offset 0x28 inside that structure, it&#8217;s the field StackBase within the QueenmArchUpd field&#8230;</li>
<li>and also, we still have in the back of our minds that &#8216;eax&#8217; is initialized to zero, so, we know that the next 2 instructions are just checking if upd-&gt;QueenmArchUpd.StackBase is == NULL.</li>
<li>Then we compare the StackSize with 0x26000, but the comparison is using &#8220;jb&#8221; for the jump, which is &#8220;jump if below&#8221;, so it checks if StackSize &lt; 0x26000,</li>
<li>finally it does a &#8220;test&#8221; with &#8220;edx+30h&#8221; (which is the BootloaderTolumSize field) and 0xFFF, then it does an unconditional jump to loc_FFF4035C, which itself does a &#8220;jz&#8221; to the return..</li>
<li>which means if (BootloaderTolumSize  &amp; 0xFFF  == 0) it will return whatever EAX contained (which is zero),</li>
<li>but if it doesn&#8217;t, then it will continue to the next instruction which is the &#8220;mov eax, 80000002h&#8221;.</li>
</ul>
<p>So, we end up with this code:</p>
<pre>EFI_STATUS validate_upd_config (uint8_t action, void *config) {
  // eax = 0
  if (action == 3) {
    ALICE *upd = (ALICE *) config;
    if (upd == NULL)
       return 0;
    if (upd-&gt;QueenUpdHeader.Signature != 0x4D5F4450554C524B /* 'KBLUPD_M'*/)
       return EFI_INVALID_PARAMETERS;
    if (upd-&gt;QueenmArchUpd.StackBase == NULL)
        return EFI_INVALID_PARAMETERS;
    if (upd-&gt;QueenmArchUpd.StackSize &lt; 0x2600)
        return EFI_INVALID_PARAMETERS;
    if (upd-&gt;QueenmArchUpd.BootloaderTolumSize &amp; 0xFFF)
        return EFI_INVALID_PARAMETERS;
  } else {
    // loc_FFF40344
  }
  return EFI_SUCCESS
}</pre>
<p>Great, we just solved half of our code! Don&#8217;t forget, we jumped one way instead of another at the start of the function, now we need to go back up and explore the second branch of the code (at offset 0xFFF40344). The code is very similar, but it checks for &#8220;KBLUPD_S&#8221; Signature, and nothing else. Now we can also remove any comment/notes we have (such as the note that eax is initialized to 0) and clean up, and simplify the code if there is a need.</p>
<p>So our function ends up being (this is the final version of the function):</p>
<pre>EFI_STATUS validate_upd_config (uint8_t action, void *config) {
  if (action == 3) {
    ALICE *upd = (ALICE *) config;
    if (upd == NULL)
       return EFI_SUCCESS;
    if (upd-&gt;QueenUpdHeader.Signature != 0x4D5F4450554C524B /* 'KBLUPD_M'*/)
       return EFI_INVALID_PARAMETERS;
    if (upd-&gt;QueenmArchUpd.StackBase == NULL)
        return EFI_INVALID_PARAMETERS;
    if (upd-&gt;QueenmArchUpd.StackSize &lt; 0x2600)
        return EFI_INVALID_PARAMETERS;
    if (upd-&gt;QueenmArchUpd.BootloaderTolumSize &amp; 0xFFF)
        return EFI_INVALID_PARAMETERS;
  } else {
    BOB *upd = (BOB *) config;
    if (upd == NULL)
        return EFI_SUCCESS;
    if (upd-&gt;QueenUpdHeader.Signature != 0x535F4450554C524B /* 'KBLUPD_S'*/)
        return EFI_INVALID_PARAMETERS;
  }
  return EFI_SUCCESS
}</pre>
<p>Now this wasn&#8217;t so bad, was it? I mean, it&#8217;s time consuming, sure, it can be a little disorienting if you&#8217;re not used to it, and you have to keep track of which branches (which blocks in the layout view) you&#8217;ve already gone through, etc. but the function turned out to be quite small and simple. After all, it was mostly only doing CMP/TEST and JZ/JNZ.</p>
<p>That&#8217;s pretty much all I do when I do my reverse engineering, I go line by line, I understand what it does, I try to figure out how it fits into the bigger picture, I write equivalent C code to keep track of what I&#8217;m doing and to be able to understand what happens, so that I can later figure out what the function does exactly&#8230; Now try to imagine doing that for hundreds of functions, some of them that look like this (random function taken from the QueenM module):</p>
<p><img class="alignnone size-full wp-image-44230" src="https://puri.sm/wp-content/uploads/2017/11/long_function.png" alt="" width="1147" height="770" srcset="https://puri.sm/wp-content/uploads/2017/11/long_function.png 1147w, https://puri.sm/wp-content/uploads/2017/11/long_function-300x201.png 300w, https://puri.sm/wp-content/uploads/2017/11/long_function-768x516.png 768w, https://puri.sm/wp-content/uploads/2017/11/long_function-1024x687.png 1024w" sizes="(max-width: 1147px) 100vw, 1147px" /></p>
<p>You can see on the right, the graph overview which shows the entirety of the function layout diagram. The part on the left (the assembly) is represented by the dotted square on the graph overview (near the middle). You will notice some arrows that are thicker than the others, that&#8217;s used in IDA to represent loops. On the left side, you can notice one such thick green line coming from the bottom and the arrow pointing to a block inside our view. This means that there&#8217;s a jump condition below that can jump back to a block that is above the current block and this is basically how you do a for/while loop with assembly, it&#8217;s just a normal jump that points backwards instead of forwards.</p>
<h1>Finally, the challenge!</h1>
<p>At the beginning of this post, I mentioned a challenging function to reverse engineer. It&#8217;s not extremely challenging—it&#8217;s complex enough that you can understand the kind of things I have to deal with sometimes, but it&#8217;s simple enough that anyone who was able to follow up until now should be able to understand it (and maybe even be able to reverse engineer it on their own).</p>
<p>So, without further ado, here&#8217;s this very simple function:</p>
<p><img class="alignnone size-full wp-image-43921" src="https://puri.sm/wp-content/uploads/2017/11/sub_fff4023f.png" alt="" width="417" height="172" srcset="https://puri.sm/wp-content/uploads/2017/11/sub_fff4023f.png 417w, https://puri.sm/wp-content/uploads/2017/11/sub_fff4023f-300x124.png 300w" sizes="(max-width: 417px) 100vw, 417px" /></p>
<p>Since I&#8217;m a very nice person, I renamed the function so you won&#8217;t know what it does, and I removed my comments so it&#8217;s as virgin as it was when I first saw it. Try to reverse engineer it. Take your time, I&#8217;ll wait:</p>
<p><img class="alignnone size-full wp-image-44375" src="https://puri.sm/wp-content/uploads/2017/11/sloth.jpg" alt="" width="1000" height="750" srcset="https://puri.sm/wp-content/uploads/2017/11/sloth.jpg 1000w, https://puri.sm/wp-content/uploads/2017/11/sloth-300x225.jpg 300w, https://puri.sm/wp-content/uploads/2017/11/sloth-768x576.jpg 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></p>
<p>Alright, so, the first instruction is a &#8220;call $+5&#8221;, what does that even mean?</p>
<ol>
<li>When I looked at the hex dump, the instruction was simply &#8220;E8 00 00 00 00&#8221; which according to our previous <a href="https://x86.puri.sm/html/file_module_x86_id_26.html">CALL opcode table</a> means &#8220;Call near, relative, displacement relative to next instruction&#8221;, so it wants to call the instruction 0 bytes from the next instruction. Since the call opcode itself is taking 5 bytes, that means it&#8217;s doing a call to its own function but skipping the call itself, so it&#8217;s basically jumping to the &#8220;pop eax&#8221;, right? Yes&#8230;  but it&#8217;s not actually jumping to it, it&#8217;s &#8220;calling it&#8221;, which means that it just pushed into the stack the return address of the function&#8230; which means that our stack contains the address 0xFFF40244 and our next instruction to be executed is the one at the address 0xFFF40244. That&#8217;s because, if you remember, when we do a &#8220;ret&#8221;, it will pop the return address from the stack into the EIP (instruction pointer) register, that&#8217;s how it knows where to go back when the function finishes.</li>
<li>So, then the instruction does a &#8220;pop eax&#8221; which will pop that return address into EAX, thus removing it from the stack and making the call above into a regular jump (since there is no return address in the stack anymore).</li>
<li>Then it does a &#8220;sub eax, 0FFF40244h&#8221;, which means it&#8217;s substracting 0xFFF40244 from eax (which should contain 0xFFF40244), so eax now contains the value &#8220;0&#8221;, right? You bet!</li>
<li>Then it adds to eax, the value &#8220;0xFFF4023F&#8221;, which is the address of our function itself. So, eax now contains the value 0xFFF4023F.</li>
<li>It will then substract from EAX, the value pointed to by [eax-15], which means the dword (4 bytes) value at the offset 0xFFF4023F &#8211; 0xF, so the value at 0xFFF40230, right&#8230; that value is 0x1AB (yep, I know, you didn&#8217;t have this information)&#8230; so, 0xFFF4023F &#8211; 0x1AB = 0xFFF40094!</li>
<li>And then the function returns.. with the value 0xFFF40094 in EAX, so it returns 0xFFF40094, which happens to be the pointer to the QUEEN_INFO_HEADER structure in the binary.</li>
</ol>
<p>So, the function just returns 0xFFF40094, but why did it do it in such a convoluted way? The reason is simple: because the QUEEN-S code is technically meant to be loaded in RAM at the address 0xFFF40000, but it can actually reside anywhere in the RAM when it gets executed. Coreboot for example doesn&#8217;t load it in the right memory address when it executes it, so instead of returning the wrong address for the structure and crashing (remember, most of the jumps and calls use relative addresses, so the code should work regardless of where you put it in memory, but in this case returning the wrong address for a structure in memory wouldn&#8217;t work), the code tries to dynamically verify if it has been relocated and if it is, it will calculate how far away it is from where it&#8217;s supposed to be, and calculate where in memory the QUEEN_INFO_HEADER structure ended up being.</p>
<p>Here&#8217;s the explanation why:</p>
<ul>
<li>If the Queen<!--FSP--> was loaded into a different memory address, then the &#8220;call $+5&#8221; would put the exact memory address of the next instruction into the stack, so when you pop it into eax then substract from it the expected address 0xFFF40244, this means that eax will contain the <strong>offset</strong> from where it was supposed to be.</li>
<li>Above, we said eax would be equal to zero, yes, that&#8217;s true, but <em>only</em> in the usecase where the Queen<!--FSP--> is in the right memory address, as expected, otherwise, eax would simply contain the offset. Then you add to it 0xFFFF4023F which is the address of our function, and with the offset, that means eax now contains the exact memory address of the current function, wherever it was actually placed in RAM!</li>
<li>Then when it grabs the value 0x1AB (because that value is stored in RAM 15 bytes before the start of the function, that will work just fine) and substracts it from our current position, it gives us the address in RAM of the QUEEN_INFO_HEADER (because the compiler knows that the structure is located exactly 0x1AB bytes before the current function). This just makes everything be relative.</li>
</ul>
<p>Isn&#8217;t that great!? 😉 It&#8217;s so simple, but it does require some thinking to figure out what it does and some thinking to understand why it does it that way&#8230; but then you end up with the problem of &#8220;How do I write this in C&#8221;? Honestly, I don&#8217;t know how, I just wrote this in my C file:</p>
<pre>// Use Position-independent code to make this relocatable
void *get_queen_info_header() {
    return 0xFFF40094; 
}</pre>
<p>I think the compiler takes care of doing all that magic on its own when you use the -fPIC compiler option (for gcc), which means &#8220;Position-Independent Code&#8221;.</p>
<h1>What this means for Purism</h1>
<p>On my side, <strong>I&#8217;ve finished reverse engineering the <!--FSP-S -->entry code</strong>—from the entry point <!--(FspSiliconInit) -->all the way to the end of the function and all the subfunctions that it calls.</p>
<p>This only represents 9 functions however, and about 115 lines of C code; I haven&#8217;t yet fully figured out where exactly it&#8217;s going in order to execute the rest of the code. What happens is that the last function it calls (it actually jumps into it) grabs a variable from some area in memory, and within that variable, it will copy a value into the ESP, thus replacing our stack pointer, and then it does a &#8220;RETN&#8221;&#8230; which means that it&#8217;s not actually returning to the function that called it (coreboot), it&#8217;s returning… &#8220;somewhere&#8221;, depending on what the new stack contains, but I don&#8217;t know where (or how) this new stack is created, so I need to track it down in order to find what the return address is, find where the &#8220;retn&#8221; is returning us into, so I can unlock plenty of new functions and continue reverse engineering this.</p>
<p>I&#8217;ve already made some progress on that front (I know where the new stack tells us to return into) but you will have to wait until my next blog post before I can explain it all to you. It&#8217;s long and complicated enough that it needs its own post, and this one is long enough already.</p>
<h1>Other stories from strange lands</h1>
<p>You never really know what to expect when you start reverse engineering assembly. Here are some other stories from my past experiences.</p>
<ul>
<li>I once spent a few days reverse engineering a function until about 30% of it when I finally realized that the function was… the C++ &#8220;+ operator&#8221; of the std::string class (which by the way, with the use of C++ templates made it excruciatingly hard to understand)!</li>
<li>I once had to reverse engineer over 5000 lines of assembly code that all resolved into&#8230; 7 lines of C code. The code was for creating a hash and it was doing a lot of manipulation on data with different values on every iteration. There was a LOT of xor, or, and, shifting left and right of data, etc., which took maybe a hundred or so lines of assembly and it was all inside a loop, which the compiler decided that—to optimize it—it would unravel the loop (this means that instead of doing a jmp, it will just copy-paste the same code again), so instead of having to reverse engineer the code once and then see that it&#8217;s a loop that runs 64 times, I had to reverse engineer the same code 64 times because it was basically getting copy-pasted by the compiler in a single block but the compiler was &#8220;nice&#8221; enough that it was using completely different registers for every repetition of the loop, and the data was getting shifted in a weird way and using different constants and different variables at every iteration, and—as if that wasn&#8217;t enough— every 1/4th of the loop, changing the algorithm and making it very difficult to predict the pattern, forcing me to completely reverse engineer the 5000+ assembly lines into C, then slowly refactor and optimize the C code until it became that loop with 7 lines of code inside it… If you&#8217;re curious you can see the code <a href="https://github.com/tomhennigan/amsn/blob/master/amsn/utils/webcamsn/src/kidhash.c#L39">here</a> at line 39, where there is some operation common to all iterations, then 4 different operations depending on which iteration we are doing, and the variables used for each operation changes after each iteration (P, PP, PPP and PPPP get swapped every time), and the constant values and the indices used are different for each iteration as well (see <a href="https://github.com/tomhennigan/amsn/blob/master/amsn/utils/webcamsn/src/constants.h">constants.h</a>). It was complicated and took a long while to reverse engineer.</li>
<li>Below is the calling graph of the PS3 firmware I worked on some years ago. All of these functions have been entirely reverse engineered (each black rectangle is actually an entire function, and the arrows show which function calls which other function), and the result was the <a href="https://github.com/kakaroto/ps3xport">ps3xport</a> tool. As you can see, sometimes a function can be challenging to reverse, and sometimes a single function can call so many nested functions that it can get pretty complicated to keep track of what is doing what and how everything fits together. That function at the top of the graph was probably very simple, but it brought with it so much complexity because of a single &#8220;call&#8221;:<br />
<a href="https://puri.sm/wp-content/uploads/2017/11/wingraph.png"><img class="alignnone wp-image-43928 size-large" src="https://puri.sm/wp-content/uploads/2017/11/wingraph-1024x382.png" alt="" width="960" height="358" srcset="https://puri.sm/wp-content/uploads/2017/11/wingraph-1024x382.png 1024w, https://puri.sm/wp-content/uploads/2017/11/wingraph-300x112.png 300w, https://puri.sm/wp-content/uploads/2017/11/wingraph-768x287.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></li>
</ul>
<h1>Perseverance prevails</h1>
<p>In conclusion:</p>
<ul>
<li>Reverse engineering isn&#8217;t just about learning a new language, it&#8217;s a very different experience from &#8220;learning Java/Python/Rust after you&#8217;ve mastered C&#8221;, because of the way it works; it can sometimes be very easy and boring, sometimes it will be very challenging for a very simple piece of code.</li>
<li>It&#8217;s all about perseverance, being very careful (it&#8217;s easy to get lost or make a mistake, and very hard to track down and fix a mistake/typo if you make one), and being <em>very</em> patient. We&#8217;re talking days, weeks, <em>months.</em> That&#8217;s why reverse engineering is something that very few people do (compared to the number of people who do general software development). Remember also that our first example was 82 bytes of code, and the second one was only 19 bytes long, and most of the time, when you need to reverse engineer something, it&#8217;s many hundreds of KBs of code.</li>
</ul>
<p>All that being said, the satisfaction you get when you finish reverse engineering some piece of code, when you <em>finally</em> understand how it works and can reproduce its functionality with open source software of your own, cannot be described with words. The feeling of achievement that you get makes all the efforts worth it!</p>
<p>I hope this write-up helps everyone get a fresh perspective on what it means to &#8220;reverse engineer the code&#8221;, why it takes so long, and why it&#8217;s rare to find someone with the skills, experience and patience to do this kind of stuff for months—as it can be frustrating, and we sometimes need to take a break from it and do something else in order to renew our brain cells.</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/primer-to-reverse-engineering/">A Primer Guide to Reverse Engineering</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Deep dive into Intel Management Engine disablement</title>
		<link>https://puri.sm/posts/deep-dive-into-intel-me-disablement/</link>
		<pubDate>Thu, 19 Oct 2017 15:38:48 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Additional Press Information]]></category>
		<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>
		<category><![CDATA[Privacy]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Software freedom]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=31772</guid>
		<description><![CDATA[<p>Starting today, our second generation of laptops (based on the 6th gen Intel Skylake platform) will now come with the Intel Management Engine neutralized and disabled by default. Users who already received their orders can also update their flash to disable the ME on their machines. In this post, I will dig deeper and explain [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/deep-dive-into-intel-me-disablement/">Deep dive into Intel Management Engine disablement</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Starting today, our second generation of laptops (based on the 6th gen Intel Skylake platform) will now come with the <a href="https://puri.sm/learn/intel-me/">Intel Management Engine</a> neutralized <em>and</em> disabled by default. Users who already received their orders can also update their flash to disable the ME on their machines.</p>
<p>In this post, I will dig deeper and explain in more details what this means exactly, and why it wasn&#8217;t done before today for the laptops that were shipping this spring and summer.</p>
<h1>The life and times of the ME</h1>
<p>Think of the ME as having 4 possible states:</p>
<p><img class="alignnone size-large wp-image-39684" src="https://puri.sm/wp-content/uploads/2017/10/intel-me-status-eye-1024x223.png" alt="" width="960" height="209" srcset="https://puri.sm/wp-content/uploads/2017/10/intel-me-status-eye-1024x223.png 1024w, https://puri.sm/wp-content/uploads/2017/10/intel-me-status-eye-300x65.png 300w, https://puri.sm/wp-content/uploads/2017/10/intel-me-status-eye-768x167.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<ol>
<li>Fully operational ME: the ME is running normally like it does on other manufacturers&#8217; machines (note that this could be a consumer or corporate ME image, which vary widely in the features they &#8216;provide&#8217;)</li>
<li>Neutralized ME: the ME is neutralized/neutered by removing the most &#8220;mission-critical&#8221; components from it, such as the kernel and network stack.</li>
<li>Disabled ME: the ME is officially &#8220;disabled&#8221; and is known to be completely stopped and non-functional</li>
<li>Removed ME: the ME is completely <em>removed</em> and doesn&#8217;t execute anything at any time, at all.</li>
</ol>
<p>In <a href="https://puri.sm/posts/neutralizing-intel-management-engine-on-librem-laptops/">my previous blog post about taming the ME</a>, we discussed how we neutralize the ME (note that this was on the first generation, Broadwell-based Purism laptops back then), but we&#8217;ve taken things one step further today by not only neutralizing the ME but also by <em>disabling</em> it. The difference between the two might not be immediately visible to some of you, so I&#8217;ll clarify below.</p>
<ul>
<li>A <em>neutralized</em> ME is a ME image which had most of its code removed.<img class="alignright wp-image-39688" src="https://puri.sm/wp-content/uploads/2017/10/intel-me-cleaner-1024x579.png" alt="" width="514" height="291" srcset="https://puri.sm/wp-content/uploads/2017/10/intel-me-cleaner-1024x579.png 1024w, https://puri.sm/wp-content/uploads/2017/10/intel-me-cleaner-300x170.png 300w, https://puri.sm/wp-content/uploads/2017/10/intel-me-cleaner-768x434.png 768w" sizes="(max-width: 514px) 100vw, 514px" />
<ul>
<li>The way the ME firmware is packaged on the flash, is in the form of multiple <strong>modules</strong>, and each module has a specific task, such as : Hardware initialization, Firmware updates, Kernel, Network stack, Audio/Video processing, HECI communication over PCI, Java virtual machine, etc. When the ME is neutralized using the <a href="https://github.com/corna/me_cleaner">me_cleaner</a> tool, most of the modules will be removed. As we&#8217;ve seen on Broadwell, that meant almost 93% of the code is removed and only 7% remains (that proportion is different on Skylake, see further below).</li>
<li>A neutralized ME means that the ME firmware will encounter an error during its regular boot cycle; It will not find some of its critical modules and it will throw an error and somehow fail to proceed. However, the ME remains operational, it just can&#8217;t do anything &#8220;valuable&#8221;. While it&#8217;s unable to communicate with the main CPU through the HECI commands, the PCI interface to the ME processor is still active and lets us poke at the status of the ME for example, which lets us see which error caused it to stop functioning.</li>
</ul>
</li>
<li>When the ME is <em>disabled</em> using the &#8220;HAP&#8221; method (thanks to the <a href="http://blog.ptsecurity.com/2017/08/disabling-intel-me.html"><em>Positive Technologies</em></a> for discovering this trick), however, it doesn&#8217;t throw an error &#8220;because it can&#8217;t load a module&#8221;: it actually stops itself in a graceful manner, by design.</li>
</ul>
<p>The two approaches are similar in that they both stop the execution of the ME during the hardware initialization (BUP) phase, but with the ME disabled through the HAP method, the ME stops on its own, without putting up a fight, potentially disabling things that the forceful &#8220;me_cleaner&#8221; approach, with the &#8220;unexpected error&#8221; state, wouldn&#8217;t have disabled. The PCI interface for example, is entirely unable to communicate with the ME processor, and the status of the ME is not even retrievable.</p>
<p>So the big, visible difference for us, between a neutralized and a disabled ME, is that the neutralized ME might appear &#8220;normal&#8221; when coreboot accesses its status, or it might show that it has terminated due to an error, while a disabled ME simply doesn&#8217;t give us a status at all—so coreboot will even think that the ME partition is corrupted. Another advantage, is that, from my understanding of the <em>Positive Technologies&#8217;s </em>research, a disabled ME stops its execution <em>before</em> a neutralized ME does, so there is at least a little bit of extra code that doesn&#8217;t get executed when the ME is disabled, compared to a neutralized ME.</p>
<h1>Kill it with fire! Then dump it into a volcano.</h1>
<p>In our case, we went with an ME that is both neutered <em>and</em> disabled. By doing so, we provide maximum security; even if the disablement of the ME isn&#8217;t functioning properly, the ME would still fail to load its mission-critical modules and will therefore be safe from any potential exploits or backdoors (unless one is found in the very early boot process of the ME).</p>
<p>I want to talk about the neutralizing of the Skylake ME then follow up on how the ME was disabled. However, I first want you to understand the differences between the ME on <em>Broadwell</em> systems (ME version 10.x) and the ME on <em>Skylake</em> systems (ME version 11.0.x).</p>
<ul>
<li>The Intel Management Engine can be seen as two things; first, the isolated processor core that run the Management Engine is considered &#8220;The ME&#8221;, and second, the firmware that runs on the ME Core is also considered as being &#8220;the ME&#8221;. I often used the two terms interchangeably, but to avoid confusion, I will from now on (try to) refer to them, respectively, as the<strong><em> ME Core</em></strong> and the <strong><em>ME Firmware</em></strong>, but note that if I simply say <em>the ME</em>, then I am probably referring to the ME Firmware.</li>
<li>The ME Firmware 10.x was used on Broadwell systems which had an <a href="https://en.wikipedia.org/wiki/ARC_(processor)">ARC core</a>, while the ME Firmware 11.0.x used on Skylake systems uses an <a href="https://en.wikipedia.org/wiki/X86">x86 core</a>. What this means is that the <em>architecture</em> used by the ME core is completely different (kind of like how PowerPC and Intel macs used a different architecture, or how most mobile devices use an ARM architecture, the Broadwell ME Core used an ARC architecture). This means that the difference between the 10.x and 11.0.x ME firmwares is major, and the cores themselves are also very different. It&#8217;s a bit like comparing arabic to korean!<br />
<a href="https://puri.sm/wp-content/uploads/2017/10/arab-vs-kor.png"><img class="size-large wp-image-39685 alignnone" src="https://puri.sm/wp-content/uploads/2017/10/arab-vs-kor-1024x400.png" alt="" width="960" height="375" srcset="https://puri.sm/wp-content/uploads/2017/10/arab-vs-kor-1024x400.png 1024w, https://puri.sm/wp-content/uploads/2017/10/arab-vs-kor-300x117.png 300w, https://puri.sm/wp-content/uploads/2017/10/arab-vs-kor-768x300.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></li>
<li>As the format of the ME firmware changed significantly, it took a while to figure out how to decompress the modules and understand how to remove the modules without breaking anything else. Nicola Corna, the author of the me_cleaner tool, recently was able to add support for Skylake machines by removing all the non essential modules.</li>
</ul>
<p>In my <a href="https://puri.sm/posts/neutralizing-intel-management-engine-on-librem-laptops/">last ME-related post</a>, I gave everyone a rundown of the modules that were in the ME 10.x firmware and which ones were remaining after it was neutered, so, for Skylake, here is the list of modules in a regular ME 11.0.x firmware:</p>
<pre>-rw-r--r-- 1 kakaroto kakaroto 184320 Aug 29 16:33 bup.mod
-rw-r--r-- 1 kakaroto kakaroto  36864 Aug 29 16:33 busdrv.mod
-rw-r--r-- 1 kakaroto kakaroto  32768 Aug 29 16:33 cls.mod
-rw-r--r-- 1 kakaroto kakaroto 163840 Aug 29 16:33 crypto.mod
-rw-r--r-- 1 kakaroto kakaroto 389120 Aug 29 16:33 dal_ivm.mod
-rw-r--r-- 1 kakaroto kakaroto  24576 Aug 29 16:33 dal_lnch.mod
-rw-r--r-- 1 kakaroto kakaroto  49152 Aug 29 16:33 dal_sdm.mod
-rw-r--r-- 1 kakaroto kakaroto  16384 Aug 29 16:33 evtdisp.mod
-rw-r--r-- 1 kakaroto kakaroto  16384 Aug 29 16:33 fpf.mod
-rw-r--r-- 1 kakaroto kakaroto  45056 Aug 29 16:33 fwupdate.mod
-rw-r--r-- 1 kakaroto kakaroto  16384 Aug 29 16:33 gpio.mod
-rw-r--r-- 1 kakaroto kakaroto   8192 Aug 29 16:33 hci.mod
-rw-r--r-- 1 kakaroto kakaroto  36864 Aug 29 16:33 heci.mod
-rw-r--r-- 1 kakaroto kakaroto  28672 Aug 29 16:33 hotham.mod
-rw-r--r-- 1 kakaroto kakaroto  28672 Aug 29 16:33 icc.mod
-rw-r--r-- 1 kakaroto kakaroto  16384 Aug 29 16:33 ipc_drv.mod
-rw-r--r-- 1 kakaroto kakaroto  11832 Aug 29 16:33 ish_bup.mod
-rw-r--r-- 1 kakaroto kakaroto  24576 Aug 29 16:33 ish_srv.mod
-rw-r--r-- 1 kakaroto kakaroto  73728 Aug 29 16:33 kernel.mod
-rw-r--r-- 1 kakaroto kakaroto  28672 Aug 29 16:33 loadmgr.mod
-rw-r--r-- 1 kakaroto kakaroto  28672 Aug 29 16:33 maestro.mod
-rw-r--r-- 1 kakaroto kakaroto  28672 Aug 29 16:33 mca_boot.mod
-rw-r--r-- 1 kakaroto kakaroto  24576 Aug 29 16:33 mca_srv.mod
-rw-r--r-- 1 kakaroto kakaroto  36864 Aug 29 16:33 mctp.mod
-rw-r--r-- 1 kakaroto kakaroto  32768 Aug 29 16:33 nfc.mod
-rw-r--r-- 1 kakaroto kakaroto 409600 Aug 29 16:33 pavp.mod
-rw-r--r-- 1 kakaroto kakaroto  16384 Aug 29 16:33 pmdrv.mod
-rw-r--r-- 1 kakaroto kakaroto  24576 Aug 29 16:33 pm.mod
-rw-r--r-- 1 kakaroto kakaroto  61440 Aug 29 16:33 policy.mod
-rw-r--r-- 1 kakaroto kakaroto  12288 Aug 29 16:33 prtc.mod
-rw-r--r-- 1 kakaroto kakaroto 167936 Aug 29 16:33 ptt.mod
-rw-r--r-- 1 kakaroto kakaroto  16384 Aug 29 16:33 rbe.mod
-rw-r--r-- 1 kakaroto kakaroto  12288 Aug 29 16:33 rosm.mod
-rw-r--r-- 1 kakaroto kakaroto  49152 Aug 29 16:33 sensor.mod
-rw-r--r-- 1 kakaroto kakaroto 110592 Aug 29 16:33 sigma.mod
-rw-r--r-- 1 kakaroto kakaroto  20480 Aug 29 16:33 smbus.mod
-rw-r--r-- 1 kakaroto kakaroto  36864 Aug 29 16:33 storage.mod
-rw-r--r-- 1 kakaroto kakaroto   8192 Aug 29 16:33 syncman.mod
-rw-r--r-- 1 kakaroto kakaroto  94208 Aug 29 16:33 syslib.mod
-rw-r--r-- 1 kakaroto kakaroto  16384 Aug 29 16:33 tcb.mod
-rw-r--r-- 1 kakaroto kakaroto  28672 Aug 29 16:33 touch_fw.mod
-rw-r--r-- 1 kakaroto kakaroto  12288 Aug 29 16:33 vdm.mod
-rw-r--r-- 1 kakaroto kakaroto  98304 Aug 29 16:33 vfs.mod
</pre>
<p>And here is the list of modules in a neutered ME :</p>
<pre>-rw-r--r-- 1 kakaroto kakaroto 184320 Oct  4 16:21 bup.mod
-rw-r--r-- 1 kakaroto kakaroto  73728 Oct  4 16:21 kernel.mod
-rw-r--r-- 1 kakaroto kakaroto  16384 Oct  4 16:21 rbe.mod
-rw-r--r-- 1 kakaroto kakaroto  94208 Oct  4 16:21 syslib.mod</pre>
<p>The total ME size dropped from 2.5MB to 360KB, which means that 14.42% of the code remains, while 85.58% of the code was neutralized with me_cleaner.</p>
<p>The reason the neutering on Skylake-based systems removed less code than on Broadwell-based systems is because of the code in <strong>the ME&#8217;s read-only memory</strong> (ROM). What this &#8220;ROM&#8221; means is that a small part of the ME firmware is actually burned in the silicon of the ME Core. The ROM content is the first code executed, loaded internally from the ROM, by the ME core, and it has the simple task of reading the ME firmware from the flash, verifying its signature, making sure it hasn&#8217;t been tampered with, loading it in the ME Core&#8217;s memory and executing it.</p>
<ul>
<li>On Broadwell, there is about 128KB of code burned in the ME Core&#8217;s ROM. That 128KB of code contains the bootloader as well as some system APIs that the other modules can use.</li>
<li>On Skylake, the ROM code was decreased to 17KB, leaving only the basic bootloader, and moving the system APIs to a module of their own inside the ME firmware.</li>
<li>This means that the total amount of code remaining, including the ROM is 360+17KB out of 2524+17KB = 377/2541 = 14.84% for Skylake, while on Broadwell, it&#8217;s 120 + 128KB out of 1624+128KB = 248/1752 = 14.15% of code remaining. The difference is much smaller now when we account for the code hidden in the ROM of the processor.</li>
</ul>
<p>The problem with the code in the ROM is that it cannot be removed because it&#8217;s inside of the processor itself and, well, it&#8217;s <em>Read-Only</em> Memory—it cannot be overwritten in any way, by definition. On the bright side, it is nice to see that most of the code that was previously in the ROM has now been moved to the flash in Skylake systems.</p>
<p>The ME firmware itself has multiple &#8220;partitions&#8221;, each containing something that the ME firmware needs. Some of those partitions will contain code modules, some will contain configuration files, and some will contain &#8220;other data&#8221; (I don&#8217;t really know what). Either way, the ME firmware contains about a dozen different partitions, each for a specific purpose, and two of those partitions contain the majority of the code modules.</p>
<h1>Schrödinger&#8217;s Wi-Fi</h1>
<p>I&#8217;ll now explain what has been done to get to this point in the project. When I was done with the coreboot port to the new Skylake machines, I tried to neutralize the ME, thinking it would be a breeze, since me_cleaner claimed support for Skylake. Unfortunately, it wasn&#8217;t working as it should and I spent the entire hacking day at the coreboot conference trying to fix it.</p>
<p><img class="wp-image-39687 alignright" src="https://puri.sm/wp-content/uploads/2017/10/purism-coreboot-schrodinger-wifi-1024x589.png" alt="" width="576" height="331" srcset="https://puri.sm/wp-content/uploads/2017/10/purism-coreboot-schrodinger-wifi-1024x589.png 1024w, https://puri.sm/wp-content/uploads/2017/10/purism-coreboot-schrodinger-wifi-300x173.png 300w, https://puri.sm/wp-content/uploads/2017/10/purism-coreboot-schrodinger-wifi-768x442.png 768w" sizes="(max-width: 576px) 100vw, 576px" /></p>
<p>The problem is that once the ME was neutralized with me_cleaner, the Wi-Fi module on the Librem was unpredictable: it sometimes would work and sometimes wouldn&#8217;t, which was confusing. I eventually realized that if I reboot after replacing the ME, the wifi would keep the same state as it was in before:</p>
<ul>
<li>if I neutralized the ME and reboot, it would still work, but after powering off the machine and turning it on, the wifi would stop working;</li>
<li>if I restored a full ME (instead of a neutralized one) and rebooted, the wifi would remain dead;</li>
<li>&#8230;but if I power off the machine and turn it back on, the wifi would finally be restored.</li>
</ul>
<p>I figured that it has something to do with how the PCI-Express card is initialized, and I spent quite some time trying to &#8220;enable it&#8221; from coreboot with a neutralized ME. I&#8217;ll spare you the details but I eventually realized that I couldn&#8217;t get it to work because the PCIe device completely ignored all my commands and would simply <em>refuse</em> to power up. It turns out that <strong>the ME controls the ICC</strong> (Integrated Clock Controller) so without it, it would simply not enable the clock for the PCIe device, so the wifi card wouldn&#8217;t work and there is <em>nothing</em> you can do about it because only the ME has control over the ICC registers. I tried to test a handful of different ME firmware versions, but surprisingly, the wifi module never worked on any of those images, even when the ME was not neutralized. Obviously, it meant that the ME firmware was not properly configured, so I used the Intel FIT tool (which is used to configure ME images, allowing us to set things like PCIe lanes, and which clocks to enable, and all of that). Unfortunately, even when an image was configured the exact same way as the original ME image we had, the wifi would still not work, and I couldn&#8217;t figure out why.</p>
<p>I shelved the problem to concentrate on the release of coreboot and eventually on the <a href="https://puri.sm/posts/coreboot-on-the-skylake-librems-part-2/">SATA issues</a> we were experiencing. The decision was made to release the Librem 13 v2 and Librem 15 v3 with a regular ME until more work was done on that front, because we couldn&#8217;t hold back shipments any longer (and because we can provide updates after shipment). Also note that at that time, the support for Skylake in me_cleaner was very rough—it was removing only half of the ME code because the format of the new ME 11.x firmware wasn&#8217;t fully known yet.</p>
<p>A few weeks later, I saw the release of <a href="https://github.com/ptresearch/unME11">unME11</a> from <em>Positive Technologies</em> and a week later, Nicola Corna pushed more complete support for Skylake in a testing branch of me_cleaner. I immediatly jumped on it and tested it on our machines. Unfortunately, <strong>the wifi issue was still there.</strong> I decided to debug the cause by figuring out what me_cleaner does that could be affecting the ME firmware that way.</p>
<p>As I mentioned earlier in this post, the ME firmware is made up of a dozen of <em>partitions,</em> some of those containing code modules, and me_cleaner will remove all the partitions except one, in which it will remove most of the modules and leave only the critical modules needed for the startup of the system. Therefore, I started progressively whitelisting more modules so me_cleaner wouldn&#8217;t remove them, and testing if it affected the wifi module. This was annoying to test because I&#8217;d have to change me_cleaner, neutralize the ME firmware, then copy the image from my main PC to the Librem then flash the new image, poweroff, then restart the machine, and if the Wifi wasn&#8217;t working, which was 99% of the time, I had to copy the files through a USB drive. I eventually restored all of the modules and it was <em>still</em> not working, which made me suspect the cause might be in one of the other partitions, so I gradually added one partition at a time, until the Wifi suddenly worked. I had just added the &#8220;MFS&#8221; partition, so I started removing the other partitions again one at a time, but keeping the &#8220;MFS&#8221; partition, and the Wifi was still working. I eventually removed all of the code modules (apart from the critical ones) but keeping the MFS partition, and the wifi was still working. So <strong>I had found my fix: I just need to keep the &#8220;MFS&#8221; partition in the image and the wifi would work.</strong></p>
<h1>So many firmwares, so little time</h1>
<p>So, what is this mysterious &#8220;MFS&#8221; partition? There&#8217;s not a lot of information about it anywhere online, other than one forum or mailing list user mentioning the MFS partition as &#8220;ME File System&#8221;. I decided to use a comparative approach.</p>
<p>The fun thing  when comparing ME firmware images: not only are there multiple <em>versions</em> (ex: 10.x vs 11.x), for each single ME version there are multiple &#8220;flavors&#8221; of it, such as &#8220;Consumer&#8221; or &#8220;Corporate&#8221;, and there are <em>also</em> multiple flavors for &#8220;mobile&#8221; and &#8220;desktop&#8221;.</p>
<ul>
<li>When I extracted and compared all the partitions of all the variants and flavors, the only difference between a mobile and a desktop image is in the MFS partition, as every other partition shares the same hash between two flavors of the same version.</li>
<li>I then compared the various partitions between a configured and a non configured ME firmware, and noticed that what the Intel FIT tool does when you change the system&#8217;s configuration is to simply write that configuration inside of the MFS partition.</li>
<li>This means that the MFS partition, which doesn&#8217;t contain any code modules, is used for storage of configuration files used by the ME firmware. This is somewhat confirmed by the fact that the MFS partition is marked as containing data.</li>
</ul>
<p><a href="https://puri.sm/wp-content/uploads/2017/10/intel-me-versions.png"><img class="alignnone size-large wp-image-39686" src="https://puri.sm/wp-content/uploads/2017/10/intel-me-versions-1024x446.png" alt="" width="960" height="418" srcset="https://puri.sm/wp-content/uploads/2017/10/intel-me-versions-1024x446.png 1024w, https://puri.sm/wp-content/uploads/2017/10/intel-me-versions-300x131.png 300w, https://puri.sm/wp-content/uploads/2017/10/intel-me-versions-768x335.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p>After modifying me_cleaner to add support for the Librem, which allows us to neutralize the ME while keeping the Wifi module working, I discussed with Nicola Corna how to best integrate the feature into me_cleaner. We came to the conclusion that having a new option to allow users to select which partitions to keep would be a better method, so I sent a <a href="https://github.com/corna/me_cleaner/pull/70">pull request</a> that adds such a feature.</p>
<p>Unfortunately, while the wifi module was working with this change, I also had an adverse side-effect when adding the MFS partition back into the ME firmware: my machine would refuse to power off, for example, and would have trouble rebooting.</p>
<ul>
<li>The exact behavior is that if I power off the machine, Linux would do the entire power off sequence then stop, and I would have to manually force shutdown the Librem by holding the power button for 5 seconds. As for the rebooting issue, instead of actually rebooting when Linux finishes its poweroff sequence, the system will be frozen for a few seconds before suddenly shutting itself down forcibly, then turning itself back on 5 seconds later, on its own. This isn&#8217;t the most critical of issues, but it would be very annoying to users, and unfortunately, I couldn&#8217;t find the cause of this strange behavior. All I knew was that if I remove the MFS partition, coreboot says the ME partition is corrupted, and the wifi module doesn&#8217;t work, and if I keep the MFS partition, coreboot says the ME partition is valid, the wifi module works, but the poweroff/reboot issues automatically appear.</li>
<li>The solution for these issues turned out to be unexpectedly simple. After another of our developers said he was ready to live with the poweroff/reboot issues, and I sent him a neutralized ME for his system, I was told that his machine was working fine with no side-effects at all. I didn&#8217;t know what the difference between his machine and mine was, other than the fact that my machine is a prototype and his was a &#8220;production&#8221; machine. I then tested my neutralized ME on the &#8220;production&#8221; Librem 13 unit I had on hand, and I didn&#8217;t have any side effects of the neutralizing of the ME firmware. I then updated my coreboot build script to add the neutralization option and <a href="https://forums.puri.sm/t/building-coreboot-from-source-official-script/1264/21">asked users on our forums</a> to test it, and every one who tested the neutralized ME reported back success with no side-effects. I then realized the problem is probably only caused by the prototype machine that I was using. Well, <em>I can live with that.</em></li>
</ul>
<h1>Disabling the ME</h1>
<p>The next step for me was to start reverse-engineering the ME firmware, like I had <a href="https://puri.sm/posts/reverse-engineering-the-intel-management-engine-romp-module/">done before</a>. This is of course a very long and arduous process that took a while and for which I don&#8217;t really have much progress to show. One thing I wanted to reverse-engineer was the MFS file system format so I could see which configuration files are within it and to start eliminating as much from it as possible. I started from the beginning however, by reverse engineering the entry point in the ROM. I will spare you much of the detail and the troubles in trying to understand some of the instructions, and mostly some of the memory accesses. The important thing to know is that before I got too far along, <em>Positive Technologies</em> announced the discovery of a way to <a href="http://blog.ptsecurity.com/2017/08/disabling-intel-me.html">disable the Intel ME</a>, and I needed to test it.</p>
<p>Unfortunately, enabling the HAP bit which disables the ME Core, didn&#8217;t work on the Librem: it was causing the power LED to blink very slowly, and nothing I could do would stop it until I removed the battery. I first thought the machine was stuck in a boot loop, but it was just blinking really slowly. I figured out eventually that the reason was that the &#8220;HAP&#8221; bit was not added in version 11.0.0, but rather in version 11.0.x (where  x &gt; 0). I decided to try a newer ME firmware version and the HAP bit did work on that, which confirmed that the ME disablement was a feature added to the ME <em>after</em> the version the Librem came with (11.0.0.1180). So now I have a newer ME (version 11.0.18.1002) that is disabled thanks to the HAP bit, but… no Wi-Fi again.</p>
<p>I decided to retry using the FIT tool to configure the ME with the exact same settings as the old ME firmware. I went through every setting available to make sure it matches, and when I tried booting it again, the ME Core was disabled and the Wifi module was working. <em>Great Success!</em></p>
<p><img class="wp-image-39683 size-medium alignnone" src="https://puri.sm/wp-content/uploads/2017/10/intel-me-neutdis-300x200.png" alt="" width="300" height="200" srcset="https://puri.sm/wp-content/uploads/2017/10/intel-me-neutdis-300x200.png 300w, https://puri.sm/wp-content/uploads/2017/10/intel-me-neutdis-768x512.png 768w, https://puri.sm/wp-content/uploads/2017/10/intel-me-neutdis-1024x683.png 1024w, https://puri.sm/wp-content/uploads/2017/10/intel-me-neutdis.png 1293w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<p>Obviously, I then needed to do plenty of testing, make sure it&#8217;s all working as it should, confirm that the ME Core was disabled, test the behavior of the system with a ME firmware both disabled <em>and</em> neutralized, and that it has no side effects other than what we wanted.</p>
<p>My previous coreboot <a href="https://source.puri.sm/kakaroto/coreboot-files/src/master/build_coreboot.sh">build script</a> was using the ME image from the local machine, but unfortunately, I can&#8217;t do that now for disabling the ME since it&#8217;s not supported on the ME image that most people have on their machines. So I updated my coreboot build script to make it download the new ME version from a public link (found <a href="http://www.win-raid.com/t832f39-Intel-Engine-Firmware-Repositories.html">here</a>), and I used <a href="http://www.daemonology.net/bsdiff/">bsdiff</a> to patch the ME image with the proper configuration for the WiFi to work. I made sure to check that the only changes to the ME image is in the MFS partition and is configuration data, so the binary patch does not contain any binary code and we can safely distribute it.</p>
<h1>Moving towards the FSP</h1>
<p>The next step will be to continue the reverse-engineering efforts, but for now, I&#8217;ve put that on hold because <em>Positive Technologies</em> have announced that they found an exploit in the ME Firmware allowing the executing of unsigned code. This exploit will be announced at the <a href="https://www.blackhat.com/eu-17/briefings/schedule/index.html#how-to-hack-a-turned-off-computer-or-running-unsigned-code-in-intel-management-engine-8668">BlackHat Europe 2017</a> conference in December, so we&#8217;ll have to wait and see how their exploit works and what we can achieve with it before going further. Also, once <em>Positive Technologies </em>release their information, it might be possible for us to work together and share our knowledge. I am hoping that I can get some information from them on code that they already reverse engineered, so I don&#8217;t have to duplicate all of their efforts. I&#8217;d also like to mention that, just as last time, Igor Skochinsky has generously shared his research with us, but also getting data from <em>Positive Technologies</em> would be a tremendous help, considering how much work they have already invested on this.</p>
<p>Right now, I have decided to move my focus to investigating the FSP, which is another important binary that needs to be reverse-engineered and removed from coreboot. I don&#8217;t think that anyone is currently actively working on it, so hopefully, I can achieve something without duplicating someone else&#8217;s work, and we can advance the cause much faster this way. I think I will concentrate first on the PCH initialization code, then move to the memory initialization.</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/deep-dive-into-intel-me-disablement/">Deep dive into Intel Management Engine disablement</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Coreboot and Skylake, part 2: A Beautiful Game!</title>
		<link>https://puri.sm/posts/coreboot-on-the-skylake-librems-part-2/</link>
		<pubDate>Tue, 29 Aug 2017 15:00:41 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>
		<category><![CDATA[Supply chain]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=20024</guid>
		<description><![CDATA[<p>Hi everyone, While most of you are probably excited about the possibilities of the recently announced &#8220;Librem 5&#8221; phone, today I am sharing a technical progress report about our existing laptops, particularly findings about getting coreboot to be &#8220;production-ready&#8221; on the Skylake-based Librem 13 and 15, where you will see one of the primary reasons [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/coreboot-on-the-skylake-librems-part-2/">Coreboot and Skylake, part 2: A Beautiful Game!</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Hi everyone,</p>
<p>While most of you are probably excited about the possibilities of the <a href="https://puri.sm/posts/purism-launches-librem-5-smartphone-campaign/">recently announced</a> &#8220;Librem 5&#8221; phone, today I am sharing a technical progress report about our existing laptops, particularly findings about getting coreboot to be &#8220;production-ready&#8221; on the Skylake-based Librem 13 and 15, where you will see one of the primary reasons we experienced a delay in shipping last month (and how we solved the issue).</p>
<p><strong>TL;DR:</strong> Shortly we began shipping from inventory the coreboot port was <a href="https://puri.sm/posts/coreboot-on-the-librem-13-v2-part-1/">considered done</a>, but we found some weird SATA issues at the last minute, and those needed to be fixed before shipping those orders.</p>
<ul>
<li>The bug was sometimes preventing booting any operating system, which is why it became a blocker for shipments.</li>
<li>I didn&#8217;t find the &#8220;perfect&#8221; fix yet, I simply worked around the problem; the workaround corrects the behavior without any major consequences for users, other than warnings showing up during boot with the Linux kernel, which allowed us to resume shipments.</li>
<li>Once I come up with the proper/perfect fix, an update will be made available for users to update their coreboot install post-facto. So, for now, do not worry if you see ATA errors during boot (or in dmesg) in your new Librem laptops shipped this summer: it is normal, harmless, and hopefully will be fixed soon.</li>
</ul>
<p><span id="more-20024"></span></p>
<hr />
<h1>The SATA-killer Chronicles</h1>
<p>I previously considered the coreboot port &#8220;done&#8221; for the new Skylake-based laptops, and as I went to the coreboot conference, I thought I&#8217;d be coming back home and finally be free to take care of the other stuff in my ever-increasing TODO list. But when I came back, I received an email from Zlatan (who was inside our distribution center that week), saying that some machines couldn&#8217;t boot, throwing errors such as:</p>
<pre>Read Error</pre>
<p>&#8230;in SeaBIOS, or</p>
<pre>error: failure reading sector 0x802 from 'hd0'</pre>
<p>or</p>
<pre>error: no such partition. entering rescue mode</pre>
<p>&#8230;in GRUB before dropping into the GRUB rescue shell.</p>
<p>That was odd, as I had never encountered those issues except one time very early in the development of the coreboot port, where we were seeing some ATA error messages in dmesg but that was fixed, and neither Matt nor I ever saw such errors again since. So of course, I didn&#8217;t believe Zlatan at first, thinking that maybe the OS was not installed properly… but the issue was definitely occurring on multiple machines that were being prepared to ship out. Zlatan then booted into the PureOS Live USB and re-installed the original AMI BIOS; then he had no more issues booting into his SSD, but when he&#8217;d flash coreboot back, it would fail to boot.</p>
<h1>The ever changing name of the wind</h1>
<p>Intrigued, I tested on my machine again with the &#8220;final release&#8221; coreboot image I had sent them and I couldn&#8217;t boot into my OS either. Wait—What!? It was working <em>fine</em> just before I went to the coreboot conference.</p>
<ul>
<li>Did something change recently? No, I remember specifically sending the image that I had been testing for weeks, and I hadn&#8217;t rebased coreboot because I very specifically wanted to avoid any potential new bug being introduced &#8220;at the last minute&#8221; from the latest coreboot git base.</li>
<li>Just to be sure, I went back to an even older image I had saved (which was known to work as well), and the issue occurred there as well—so not a compiling-related problem either.</li>
<li>I asked Matt to test on his machine, and when he booted the machine, it was failing for him with the same error. He hadn&#8217;t even flashed a new coreboot image! It was still the same image he had on the laptop for the past few weeks, which was was working perfectly for him… until now, as it now refused to boot.</li>
</ul>
<p>Madness? THIS—IS—<em>SATA!</em></p>
<p>After extensive testing, we finally came to the conclusion that whether or not the machine would manage to boot was entirely dependent on the following conditions:</p>
<ul>
<li>The time of day</li>
<li>The current phase of the moon</li>
<li>The alignment of the planets in some distant galaxy</li>
<li>The mood of my neighbor&#8217;s cat</li>
</ul>
<p>The most astonishing (and frustrating) thing is that during the three weeks where Matt and I have been working on the coreboot port previously, we never encountered any &#8220;can&#8217;t boot&#8221; scenario—and we were rebooting those machines probably 10 times per hour or more… but now, we were suddenly both getting those errors, pretty consistently.</p>
<p><img class="alignnone size-full wp-image-21426" src="https://puri.sm/wp-content/uploads/2017/08/coders-shrug.gif" alt="" width="500" height="284" /></p>
<p>After a day or two of debugging, it suddenly started working without any errors again for a couple of hours, then it started bugging again. On my end, the problem seemed to typically happen with SATA SSDs on the M.2 port (I didn&#8217;t get any issues when using a 2.5&#8243; HDD, and Matt was in the same situation). However, even with a 2.5&#8243; HDD, Zlatan was having the same issues we were seeing with the M.2 connector.</p>
<p>So the good news was that we were at least able to encounter the error pretty frequently now, the bad news was that Purism couldn&#8217;t ship its newest laptops until this issue was fixed—and we had promised the laptops would be shipping out in droves by that time! Y&#8217;know, just to add a bit of stress to the mix.</p>
<h2>The Eolian presents: DTLE</h2>
<p>When I was doing the v1 port, I had a more or less similar issue with the M.2 SATA port, but it was much more stable: it would always fail with &#8220;Read Error&#8221;, instead of failing with a different error on every boot and &#8220;sometimes failing, sometimes working&#8221;. Some of you may remember my explanation of how I fixed the issue on the v1 <a href="https://puri.sm/posts/librem-13-coreboot-report-february-25th-2017/">in February</a>: back then, I had to set the DTLE setting on the IOBP register of the SATA port. What this means is anyone&#8217;s guess, but I found <a href="http://blog.asset-intertech.com/test_data_out/2013/05/siv-versus-smv-part-2.html" target="_blank" rel="noopener">this article</a> explaining that &#8220;DTLE&#8221; means &#8220;Discrete Time Linear Equalization&#8221;, and that having the wrong DTLE values can cause the drives to <em>&#8220;run slower than intended, and may even be subject to intermittent link failures&#8221;.</em> Intermittent link failures! Well! Doesn&#8217;t that sound familiar?</p>
<p>Unfortunately, I don&#8217;t know how to set the DTLE setting on the Skylake platform, since coreboot doesn&#8217;t have support for it. The IOBP registers that were on the Broadwell platform do not exist in Skylake (they have been replaced by a P2SB—Primary to SideBand—controller), and the DTLE setting does not exist in the P2SB registers either, according to someone with access to the NDA&#8217;ed datasheet.</p>
<p>When the computer was booting, there were some ATA errors appearing in dmesg, and it looks something like this:</p>
<pre>ata3: exception Emask 0x0 SAct 0xf SErr 0x0 action 0x10 frozen
ata3.00: failed command: READ FPDMA QUEUED
ata3.00: cmd 60/04:00:d4:82:85/00:00:1f:00:00/40 tag 0 ncq 2048 in
res 40/00:18:d3:82:85/00:00:1f:00:00/40 Emask 0x4 (timeout)
ata3.00: status: { DRDY }</pre>
<p>Everywhere I found this error referenced, such as in <a href="https://ubuntuforums.org/showthread.php?t=2272486" target="_blank" rel="nofollow noopener">forums</a>, the final conclusion was typically &#8220;the SATA connector is defective&#8221;, or &#8220;it&#8217;s a power related issue&#8221; where the errors disappeared after upgrading the power supply, etc. It sort of makes sense with regards to the DTLE setting causing a similar issue.</p>
<p>It also looks strikingly similar to <a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/550559" target="_blank" rel="nofollow noopener">Ubuntu bug #550559</a> where there is no insight on the cause, other than &#8220;disabling NCQ in the kernel fixes it&#8221;… but the original (AMI) BIOS does not disable NCQ support in the controller, and it doesn&#8217;t fix the DTLE setting itself.</p>
<p><img class="size-full wp-image-21425 alignnone" src="https://puri.sm/wp-content/uploads/2017/08/thats-not-enough-we-have-to-go-deeper.jpg" alt="" width="570" height="311" srcset="https://puri.sm/wp-content/uploads/2017/08/thats-not-enough-we-have-to-go-deeper.jpg 570w, https://puri.sm/wp-content/uploads/2017/08/thats-not-enough-we-have-to-go-deeper-300x164.jpg 300w" sizes="(max-width: 570px) 100vw, 570px" /></p>
<h2>Chasing the wind</h2>
<p>So, not knowing what to do exactly and not finding any information in datasheets, I decided to try and figure it out using some good old <strong>reverse engineering</strong>.</p>
<p>First, I needed to see what the original BIOS did… but when I opened it in UEFIExtract, it turns out there&#8217;s a <strong>bunch</strong> of &#8220;modules&#8221; in it. What I mean by &#8220;a bunch&#8221; is <strong>about 1581 modules</strong> in the AMI UEFI BIOS, from what I could count. Yep. And &#8220;somewhere&#8221; in one of those, the answer must lay. I didn&#8217;t know what to look for; some modules are named, some aren&#8217;t, so I obviously started with the file called &#8220;SataController&#8221;—I thought I&#8217;d find the answer in it quickly enough simply by opening it up with <a href="https://www.hex-rays.com/products/ida/" target="_blank" rel="nofollow noopener">IDA</a>, but nope: that module file pretty much doesn&#8217;t do anything. I also tried &#8220;PcieSataController&#8221; and &#8220;PcieSataDynamicSetup&#8221; but those weren&#8217;t of much help either.</p>
<p>I then looked at the code in coreboot to see how exactly it initializes the SATA controller, and found this bit of code:</p>
<pre> /* Step 1 */
 sir_write(dev, 0x64, 0x883c9003);</pre>
<p>I don&#8217;t really know what this does but to me it looks suspiciously like a &#8220;magic number&#8221;, where for some reason that value would need to be set in that variable for the SATA controller to be initialized. So I looked for that variable in all of the UEFI modules and found <em>one</em> module that has that same magic value, called &#8220;PchInitDxe&#8221;. Progress! But the code was complex and I quickly realized it would take me a <em>long</em> time to reverse engineer it all, and time was something I didn&#8217;t have—remember, shipments were blocked by this, and customers were asking us <em>daily</em> about their order status!</p>
<h2>The RAM in storm</h2>
<p>One realization that I had was that the error is always about this &#8220;READ FPDMA QUEUED&#8221; command… which means it&#8217;s somehow related to DMA, and therefore related to RAM—so, could there be RAM corruption occurring? Obviously, I tested the RAM with memtest and no issues turned up, and since we had finally received the hardware, I could push for receiving the schematics from the motherboard designer (I was previously told it would be a distraction to pursue schematics when there were so many logistical issues to fix first).</p>
<ul>
<li>As I finally received the schematics and started studying them, I found that there were some discrepancies between the RComp resistor values in the schematics and what I had set in coreboot, so I fixed that… but it made no difference.</li>
<li>I thought that maybe the issue then is with the DQ/DQS settings of the RAM initialization (which is meant for synchronization), but I didn&#8217;t have the DQ/DQS settings for this motherboard and I couldn&#8217;t figure it out from the schematics, so what I did was to simply hexdump the entire UEFI modules, and grep for &#8220;79 00 51&#8221; which is the 16 bit value of &#8220;121&#8221; followed by the first byte of the 16 bit value of &#8220;81&#8221;, which are two of the RComp resistor values. That allowed me to find 2 modules which contained the values of the Rcomp resistors for this board, and from there, I was able to find the DQ and DQS settings that were stored in the same module, just a few bytes above the Rcomp values, as expected. I tested with these new values, and… it made no difference. No joy.</li>
</ul>
<h1>A night with no moon</h1>
<p>What else could I do? &#8220;If only there was a way to run the original BIOS in an emulator and catch every I/O it does to initialize the SATA controller!&#8221;</p>
<p>Well, there <em>is</em> something like that, it&#8217;s called <a href="https://www.serialice.com/" target="_blank" rel="noopener">serialICE</a> and it&#8217;s part (sort of?) of the coreboot umbrella project. I was very happy to find that, but after a while I realized I can&#8217;t make use of it (at least not easily): it requires us to replace the BIOS with this serialICE which is a very very minimal BIOS that basically only initializes the UART lines and loads up qemu, then you can &#8220;connect&#8221; to it using the serial port, send it the BIOS you want to run, and while serialICE runs the BIOS it will output all the I/O access over the serial port back to you… That&#8217;s great, and exactly what I need, unfortunately:</p>
<ul>
<li>the Librems do not have a serial port that I can use for that;</li>
<li>looking at the schematics, the only UART pad that is available is for TX (for receiving data), not RX (for sending data to the machine);</li>
<li>I can&#8217;t find the TX pad on the motherboard, so I can&#8217;t even use that.</li>
</ul>
<p>Thankfully, I was told that there is a way to use xHCI usb debugging capabilities even on Skylake, and Nico Huber wrote <a href="https://git.codelabs.ch/?p=libxhcidbg.git;a=summary" target="_blank" rel="noopener">libxhcidbg</a> which is a library implementing the xHCI usb debug features. So, all I would need to make serialICE work would be to:</p>
<ul>
<li>port coreboot to use libxhcidebug to have the USB debugging feature, test it and make sure it all works, or&#8230;</li>
<li>port my previous <a href="https://puri.sm/posts/coreboot-on-the-librem-13-v2-part-1/">flashconsole</a> work to serialICE then find a way to somehow send/bundle the AMI BIOS inside the serialICE or put it somewhere in the flash so serialICE can grab it directly without me needing to feed it to it through serial.</li>
</ul>
<p>Another issue is that for the USB debug to work, USB needs to be initialized, and there is no way for me to know if the AMI BIOS initializes the SATA controller before or after the USB controller, so it might not even be helpful to do all that yak shaving.</p>
<p><img class="alignnone size-full wp-image-21423" src="https://puri.sm/wp-content/uploads/2017/08/real-yak-shaving.jpg" alt="" width="600" height="343" srcset="https://puri.sm/wp-content/uploads/2017/08/real-yak-shaving.jpg 600w, https://puri.sm/wp-content/uploads/2017/08/real-yak-shaving-300x172.jpg 300w" sizes="(max-width: 600px) 100vw, 600px" /></p>
<p>The other solution (to use flashconsole) might not work either because we have 16MB of flash and I expect that a log of all I/O accesses will probably take a lot more space than that, so it might not be useful either.</p>
<p>And even if one or both of the solutions actually worked, sifting through thousands of I/O accesses to find just the right one that I need, might be like looking for a needle in a haystack.</p>
<p>Considering the amount of work involved, the uncertainty of whether or not it would even work, and the fact that I really didn&#8217;t have time for such animal cruelty (remember: shipments on hold until this is fixed!), I needed to find a quicker solution.</p>
<h1>The anger of a gentle man</h1>
<p>At that point, I was starting to lose hope for a quick solution and I couldn&#8217;t find any more tables to flip:</p>
<blockquote><p>&#8220;This issue is <em>so</em> weird! I can&#8217;t figure out the cause, nothing makes sense, and there&#8217;s no easy way to track down what needs to be done in order to get it fixed.&#8221;</p></blockquote>
<p>And then I noticed something. While it will sometimes fail to boot, sometimes will boot without issues, sometimes will trigger ATA errors in dmesg, sometimes will stay silent… one thing was consistent: once Linux boots, we don&#8217;t experience any issues—there was no kernel panic &#8220;because the disc can&#8217;t be accessed&#8221;, no &#8220;input/output error&#8221; when reading files… there is no real visible issue other than the few ATA errors we see in dmesg at the beginning when booting Linux, and those errors don&#8217;t re-appear later.</p>
<p>After doing quite a few tests, I noticed that whenever the ATA errors happen for a few times, the Linux kernel ends up dropping the ATA link speed to 3Gbps instead of the default 6Gbps, and that once it does, there aren&#8217;t any errors happening afterwards. I eventually came to the conclusion that those ATA errors are the same issue causing the boot errors from SeaBIOS/GRUB, and that they only happened when the controller was setup to use 6Gbps speeds.</p>
<p>What if I was wrong about the DTLE setting, and potential RAM issues? What if all of this is because of a misconfiguration of the controller itself? What if all AMI does is to disable the 6Gbps speed setting on the controller so it can&#8217;t be used?!</p>
<p>So, of course, I checked, and nope, it&#8217;s not disabled, and when booting Linux from the AMI BIOS, the link was set up to 6Gbps and had no issues… so it must be something else, related to that. I dumped every configuration of the SATA controller—not only the PCI address space, but also the AHCI ABAR memory mapped registers, and any other registers I could find that were related to the SATA/AHCI controller—and I made sure that they matched exactly between the AMI BIOS and the coreboot registers, and… still nothing. It made even less sense! If all the SATA PCI address space and AHCI registers were exactly the same, then why wouldn&#8217;t it work?</p>
<p>I gave up!</p>
<p><img class="alignnone size-full wp-image-21424" src="https://puri.sm/wp-content/uploads/2017/08/damnit-steve-you-said-you-were-good-at-debugging.png" alt="" width="210" height="157" /></p>
<p>…ok, I actually didn&#8217;t. I temporarily gave up trying to fix the problem&#8217;s root <em>cause</em>, but only because I had an idea for <strong>a workaround that could yield a quick win</strong> instead: if Linux is able to drop the link speed to 3Gbps and stop having any issues, then why can&#8217;t I do the same in coreboot? Then both SeaBIOS and GRUB would stop having issues trying to read from the drive, ensuring the drive will allow booting properly.</p>
<p>I decided I would basically do the same thing as Linux, but do it purposedly <em>in coreboot</em>, instead of it being done &#8220;in Linux&#8221; after errors start appearing.</p>
<p>While not the &#8220;ideal fix&#8221;, such a workaround would at least let the Skylake-based Librems boot reliably for all users, allowing us to release the shipments so customers can start receiving their machines as soon as possible, after which I would be able to take the time to devise the &#8220;ideal&#8221; fix, and provide it as a firmware update.</p>
<h2>Sleeping under the wagon: an overnight workaround</h2>
<p>I put my plan in motion:</p>
<ul>
<li>I looked at the datasheet and how to configure the controller&#8217;s speed, and found that I could indeed disable the 6Gbps speed, but for some reason, that didn&#8217;t work.</li>
<li>Then I tried to make it <em>switch</em> to 3Gbps, and that still didn&#8217;t work.</li>
<li>I went into the Linux kernel&#8217;s SATA driver to see what it does exactly, and realized that I didn&#8217;t do the switch to 3Gbps correctly. So I fixed my code in coreboot, and the machines started booting again.
<ul>
<li>I also learned what exactly happens in the Linux kernel: when there&#8217;s an error reading the drive, it will retry a couple of times; if the error keeps happening over and over again, then it will drop the speed to 3Gbps, otherwise, it keeps it as-is. That explains why we sometimes see only one ATA error, sometimes 3, and some other times 20 or more; it all depends on whether the retries worked or not.</li>
<li>Once I changed the speed of the controller to 3Gbps, I stopped having troubles booting into the system because both SeaBIOS and GRUB were working on 3Gbps and were not having any issues reading the data. However, once Linux boots, it resets the controller, which cancels out the changes that I did, and Linux starts using the drive at 6Gbps. That&#8217;s not really a problem because I know that Linux will retry any reads, and will drop to 3Gbps on its own once errors start happening, but it has the side effect that users will be seeing these ATA error message on their boot screen or in dmesg.</li>
</ul>
</li>
</ul>
<p>&nbsp;</p>
<p><img class="alignnone size-medium wp-image-21505" src="https://puri.sm/wp-content/uploads/2017/08/flat800x800075f-300x191.jpg" alt="" width="300" height="191" srcset="https://puri.sm/wp-content/uploads/2017/08/flat800x800075f-300x191.jpg 300w, https://puri.sm/wp-content/uploads/2017/08/flat800x800075f.jpg 600w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<h1>The next chapter: probably less than 10 years from now</h1>
<p>As you can see, small issues like that are a real puzzle, and that&#8217;s the kind of thing that can make you waste a month of work just to &#8220;get it working&#8221; (let alone &#8220;find the perfect fix&#8221;). This is why I typically don&#8217;t give time estimates on this sort of work. We&#8217;re committed though on getting you the best experience with your machines, so we&#8217;re still actively working on everything.</p>
<p>Here&#8217;s a summary of the current situation:</p>
<ul>
<li>You will potentially see errors in your boot screen, but it&#8217;s not a problem since Linux will fix it</li>
<li>It&#8217;s not a hardware issue, since it doesn&#8217;t happen with the AMI BIOS, we just need to figure out what to configure to make it work.</li>
<li>There is nothing to be worried about, and I expect to fix it in a future coreboot firmware update, which we&#8217;ll release to everyone once it&#8217;s available (we&#8217;re working on integration with <a href="http://fwupd.org/" target="_blank" rel="noopener">fwupd</a>, so maybe we&#8217;ll release it through that, I don&#8217;t know yet).</li>
</ul>
<p>It&#8217;s taken me much longer than anticipated to write this blog post (2 months exactly), as other things kept getting in the way—avalanches of emails, other bugs to fix, patches to test/verify, scripts to write, and a lot of things to catch up on from the one month of intense debugging during which I had neglected all my other responsibilities.</p>
<p>While I was writing this status report, I didn&#8217;t make much progress on the issue—I&#8217;ve had 3 or 4 enlightenments and I thought I suddenly figured it all out, only to end up in a dead end once again. Well, once I do figure it out, I will let you all know! Thanks for reading and thanks for your patience.</p>
<hr />
<p>End notes: <small>if you didn&#8217;t catch some references, or paragraph titles in this post, then you need to read <a href="https://www.patrickrothfuss.com/content/books.asp" target="_blank" rel="noopener">The KingKiller Chronicles</a> by Patrick Rothfuss (<a href="https://en.wikipedia.org/wiki/The_Name_of_the_Wind" target="_blank" rel="noopener">The Name of the Wind</a> and <a href="https://en.wikipedia.org/wiki/The_Wise_Man%27s_Fear" target="_blank" rel="noopener">The Wise Man&#8217;s Fear</a>). These are some of the best fantasy books I&#8217;ve ever read, but be aware that the final book of the trilogy may not be released for another 10 years because the author <em>loves</em> to do millions of revisions of his manuscripts until they are &#8220;perfect&#8221;.</small></p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/coreboot-on-the-skylake-librems-part-2/">Coreboot and Skylake, part 2: A Beautiful Game!</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Coreboot on the Librem 13 v2, part 1</title>
		<link>https://puri.sm/posts/coreboot-on-the-librem-13-v2-part-1/</link>
		<pubDate>Thu, 15 Jun 2017 20:38:18 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Giving and contributing back]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=19188</guid>
		<description><![CDATA[<p>Hello everyone! I am very happy to announce that the coreboot port to the Librem 13 v2 as well as the Librem 15 v3 is done! Wow, what an adventure! The entire thing took about 2 weeks of hard work, and an additional week of testing, fixing small issues that kept popping up, and cleaning up [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/coreboot-on-the-librem-13-v2-part-1/">Coreboot on the Librem 13 v2, part 1</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Hello everyone! I am very happy to announce that the coreboot port to the Librem 13 v2 as well as the Librem 15 v3 is done! Wow, what an adventure! The entire thing took about 2 weeks of hard work, and an additional week of testing, fixing small issues that kept popping up, and cleaning up the code/commits.</p>
<p>It was truly an adventure, and I would have liked to stop and take the time to write 10 blog posts during that time, one for every major bump in the road or milestone, but I was under a strict deadline because we needed to finish the port before we started shipping the new Librem 13 v2 hardware (from now on referred to as &#8216;the v2&#8217;), so it could be shipping with coreboot pre-installed from day one. Now that the port is finished, I can finally start writing the first chapter in the story.</p>
<p><strong><em>TL;DR:</em></strong> in the process of porting the Skylake-based Librem 13 v2 to coreboot, I have implemented a new debugging method (&#8220;flashconsole&#8221;) and added it to coreboot. It has been <a href="https://review.coreboot.org/#/c/19849">reviewed</a> and merged upstream.<span id="more-19188"></span> The &#8220;flashconsole&#8221; driver is a debugging method for coreboot to write its console log to the SPI flash itself. So if you want to port a board to coreboot and you don&#8217;t have access to UART (or don&#8217;t want to solder UART wires to the motherboad), and can&#8217;t use USB debugging (on skylake for example), then you can enable the CONSOLE_SPI_FLASH configuration option and the console log will be written to the flash. When you use your external programmer, just dump the flash first, then you can use &#8216;<em>cbfstool rom.bin read -r CONSOLE -f console.log</em>&#8216; to extract the console log from it. No wires, no mess, no soldering required. Well, you do still need the external flasher, but you already have to use it to unbrick the machine since it wasn&#8217;t booting (and if it was booting, then you already have log access through cbmem, so you don&#8217;t need uart or flash console).</p>
<h1>Getting your feet wet</h1>
<p>Since I learned my lesson when I first tried to do the v2 port (my, oh so embarassing <a href="https://puri.sm/posts/diving-back-into-coreboot-development/" class="broken_link">first attempt</a>), I decided to grab all the logs I could get from the v2 before doing anything else. After running all the commands from the <a href="https://www.coreboot.org/Motherboard_Porting_Guide">Motherboard Porting Guide</a>, I copied the files over to my work laptop, and when I tried to look at the flash contents, I couldn&#8217;t find the rom.bin file! Maybe the cat ate it? It turns out, when I was trying to dump the flash, I hadn&#8217;t noticed that the &#8216;flashrom&#8217; command returned this error :</p>
<blockquote>
<pre>Found chipset "Intel Sunrise Point (Skylake-U Premium)" with PCI ID 8086:9d48.
ERROR: This chipset is not supported yet.</pre>
</blockquote>
<p>Well, that&#8217;s interesting, flashrom doesn&#8217;t support the Skylake processors (confirmed <a href="https://www.flashrom.org/Supported_hardware">here</a>). So my first task would be to add Skylake support to flashrom. After I mentioned that in IRC, Nico Huber said that he <a href="https://review.coreboot.org/#/q/owner:%22Nico+Huber%22++topic:intel_chipset_support+project:flashrom">already did</a> port flashrom to Skylake, but it&#8217;s just been untested/unreviewed/unmerged. I decided to start reviewing those changes, to get my feet wet, understand how flashrom works, how to read the Intel PCH datasheet, and also to contribute something to the coreboot/flashrom community other than by submitting new code. I&#8217;ve sent my comments on a few of those patches, some things got fixed and/or merged, until I had to stop because my deadline was catching up to me.</p>
<h1>The boring part</h1>
<p>The first thing I had to do when I started the port was to understand what needed to be done. I&#8217;ve watched <a href="https://www.youtube.com/watch?v=8wPskpLHFIo">this talk</a> by Shawn Nematbakhsh in the 2014 Chrome OS Firmware Summit where he explained the process of porting a new chromebook board to coreboot. Since I knew that the v2  was based on the skylake family of Intel processors, I looked at existing skylake boards in the coreboot tree and I found a few : Google Chell, Google Glados, Google Lars, Intel KBLRVP and Intel Kunimitsu. I decided to use the Google Chell board as my starting point (this was a random choice), so I copied the mainboard/google/chell directory into mainboard/purism/librem13v2 and I started to edit the files. I mainly edited the Kconfig/Kconfig.name/board_info.txt files to replace &#8216;google/chell&#8217; by &#8216;purism/librem13&#8217; everywhere I found it. Then I started removing files or references that were chromeos specific and after fumbling a bit in the dark, and removing anything that I thought wasn&#8217;t needed or that I didn&#8217;t understand, I managed to get coreboot to compile.</p>
<p>I also took the time of course to extract the vbios, download the FSP image, adapt the Kconfig file, and update the GPIO values to match the original firmware (more on that in a future post).</p>
<p>When I tested it though, it didn&#8217;t work, obviously. I needed to know what went wrong, I needed to debug it! Unfortunately, I couldn&#8217;t find any UART pads on the motherboard, and when I looked at the usbdebug (which I used for the v1), I realized that it is not implemented for Skylake. After some research, I realized that usbdebug was actually a feature of Broadwell processors, but on Skylake it&#8217;s different, it&#8217;s called DCI, and it requires some proprietary hardware, and proprietary software to talk over a proprietary protocol in order to get the DCI debugging working. I did not want to do that, so I looked for an alternative.</p>
<h1>Now the fun begins</h1>
<p>For me, the obvious choice for debugging was to use the SPI flash itself. After all, I was testing different things blindly, and every time that it failed to work, I was using my external flasher to write a new coreboot version to it. Why not read the flash at the same time and grab the log from it. This felt like such an obvious method for debugging but to my surprise, it wasn&#8217;t implemented in coreboot, so I decided to do just that.</p>
<p>First, I needed to be able to test my implementation, so I decided to implement it for Broadwell so I could test it on the v1 hardware first. Once it would work on the v1, then I could try it on the v2. I looked at the API used by coreboot to write to the flash, and used that to write my log to a fixed offset in the flash (which I knew was unused), then tested it. It worked! Wow, that was fast. This is going to be soooo easy! Yeah&#8230; right&#8230;</p>
<p>So now that it worked with a hard coded offset, I need to make it write to a CBFS file. The CBFS (CoreBoot FileSystem, I assume) has various sections in it called &#8216;files&#8217;, and after looking at the API for a bit, I figured out how to make it parse the CBFS and give me the offset and size of the &#8216;console&#8217; file. I then changed the Makefile.inc so it would add a &#8216;console&#8217; file to CBFS when the option is enabled. I then test, and my &#8216;cbfsconsole&#8217; logger doesn&#8217;t work anymore. I played with it for a while without understanding the problem. Eventually, I found out that if I was writing at offset 0x200000 (my hardcoded value, pointing to unused space), it was working, but if I was writing to offset 0x260000 (the offset of the &#8216;console&#8217; file in CBFS), it wasn&#8217;t working. I even removed the cbfs-related code and just hardcoded the value to 0x260000, it was still not working. Aaron Durbin (adurbin on IRC) came to the rescue, after understanding what I was doing and the issues I was having, he asked me *how* I was creating the &#8216;console&#8217; file that was added to cbfs, and he immediatly saw the problem. The file was copied from /dev/zero, so it was all zeroes, but that&#8217;s not how NOR flash works. Apparently, you can&#8217;t write a &#8216;1&#8217; in a NOR flash, you can only change a &#8216;1&#8217; into a &#8216;0&#8217;, but not a &#8216;0&#8217; into a &#8216;1&#8217;. Since my console file was all zeroes, all my writes were not working. Well, that was news to me, I didn&#8217;t know that&#8217;s how NOR flash worked.. So, what do you do if you want to turn a &#8216;0&#8217; into a &#8216;1&#8217;? Well, that&#8217;s simple, you do a &#8216;sector erase&#8217;, which will erase the entire sector (turning it entirely into 1s (0xff data)), *then* you can write back your data. That also explains this life-long question I always had of &#8220;why does flashrom always erase sectors before it writes the data into it&#8221;.</p>
<p>So, here is the right way of populating any sector of the flash on which you expect to write anything :</p>
<pre>dd if=/dev/zero count=1 bs=$(__cbfsconsole_size) | tr '\000' '\377'</pre>
<p>Now that I had a proper &#8216;console&#8217; file, and my driver was writing the log. I added the code to do a sector erase so whenever the PC boots, the &#8216;console&#8217; file would be erased entirely so the log can be written to it safely. After all, if I try to write over existing data, it will just be a mess of old and new data. Unfortunately, this caused me my second headache.</p>
<p>Before I get into that, I will first, quickly talk about all the hours I wasted, trying to enable cbfsconsole for bootblock and romstage. You see, coreboot has 3 stages, each being executed as independent programs. The bootblock is the very first code that gets executed when you turn on the computer, it will setup the processor to use its cache to act as RAM, then it will execute the romstage. The romstage will initialize the RAM, then the ramstage is executed, which will do most of the actual hardware initialization. When I wrote cbfsconsole, I had it initially enabled only for ramstage, and now that it was working, I decided to enable it for the bootblock and romstage stages. Unfortunately, that didn&#8217;t work because I was using a global variable in my code, and because the SPI driver is doing <em>crazy</em> things like &#8216;malloc&#8217; (allocating memory) and also using global variables, which of course, you can&#8217;t do before the RAM has been initialized.</p>
<p>So after messing with it for a while, I found out that coreboot uses a nice trick where you can declare global variables in a certain way (using the <em>CAR_GLOBAL</em> macro) and then you need to access them differently (using <em>car_get_var</em> and <em>car_set_var</em>) and then you can use global variables, which will just be stored in the cache-as-ram (CAR) section of the binary, instead of being stored in RAM. After I ported my cbfsconsole to use the CAR_GLOBAL trick, and then spending a few hours, trying to get it to compile, I eventually realized that it was a crazy idea, cbfsconsole used a global variable, but it also used the SPI flasher API which itself used global variables, but the SPI flasher itself used various SPI driver implementations which themselves used malloc and global variables. Even after I disabled all the drivers and only left the WIMBOND driver, and ported it to use CAR_GLOBAL, it was not finished, because the SPI driver uses Broadwell specific PCI interfaces, which I had to include and which themselves used global variables. It was a never-ending game where it was not trivial to port the entire thing to use CAR_GLOBAL. So I eventually gave up and thought that I could never get the logger to work on the bootblock and romstage stages (which is crucially important because the crash on the v2 was happening in those stages).</p>
<p>The following day however, as I was trying to compile coreboot for the v2 (skylake), I enabled the cbfsconsole by mistake and it compiled. Shocked, I realized that on skylake, there was a new hardware-sequencing implementation for the SPI driver which didn&#8217;t use any global variables or anything. So yeah, cbfsconsole would have worked if I had just tried it on Skylake before trying it on Broadwell!</p>
<p>Since my cbfsconsole was now properly compiling for Skylake, it was time to test it on the v2. Unfortunately, it was obviously not working. At that point though, I was already joined by Matt “<a href="https://mrchromebox.tech/" target="_blank" rel="noopener noreferrer">Mr. Chromebox</a>” DeVillier, who had access to a Chromebook Chell with the Servo (debug) connector installed, and he volunteered to test the cbfsconsole on his Google Chell to see if it would work. Once he enabled cbfsconsole, his Chell Chromebook stopped booting, but using his servo debugger, he was able to get the debug logs which showed him this peculiar line :</p>
<pre>SPI Transaction Timeout (Exceeded 15 ms) at Flash Offset d0f000 HSFSTS = 0x3f066020</pre>
<p>After a lot of debugging, reading the datasheet for the SPI hardware sequencer and testing various things, the only conclusion I could get to was that the Skylake hardware SPI sequencer was frozen for no particular reason, and that was causing everything to just freeze. Well, to be honest, it was freezing because the SPI transactions would timeout, causing the SPI driver to print the debug line &#8220;SPI Transaction Timeout&#8221; above, which itself would make it try to write it again to the flash, and we end up in an infinite loop.</p>
<p>I gave up again on trying to understand it and I went to the #coreboot IRC channel asking if someone knew why this would happen. Aaron Durbin came to the rescue once again, telling us that some implementations might freeze if we try to erase a sector that is already erased. Of course the sector was already erased, since it was all full of 0xff data (see above), and trying to erase it is what&#8217;s causing all our problems! Once I removed the code that erases the sectors, and replaced it with code that would read the &#8216;console&#8217; file, and set its starting offset to the first occurence of the 0xff byte, the cbfsconsole worked! Matt reported that his Chell device booted, and when I tested on the v2, I finally got some output!</p>
<h1>Finalizing things</h1>
<p>Now that we had a way to get a debug log out of coreboot, it was time to get it to work on the v2. Unfortunately, it was crashing it seems on the very first thing that it was trying to do. This was the entire log :</p>
<pre>coreboot-4.5-1805-g7da7ddf-dirty Fri May 12 20:15:36 UTC 2017 bootblock starting...
Calling FspTempRamInit</pre>
<p>It didn&#8217;t take long to fix that because Matt had experience with that. It looks like the FSP needs us to give it a Microcode address and length that are not zero. Even though the FSP Integration Guide says that setting the MicrocodeRegionBase and MicrocodeRegionLength parameters to zero means that no microcode update is available, the reality is that the FSP simply freezes or crashes if a valid non-zero-sized Microcode is not provided to it.</p>
<p>In this case, coreboot was disappointing, because on Broadwell, the Microcode files were automatically included in the build since they are distributed with coreboot (in the &#8216;blobs&#8217; repository), but for Skylake, they are not available, and that&#8217;s because Intel decided to make you accept a non-distribute license for downloading the microcode files, so they were of course never added to coreboot. The problem here is that coreboot simply adds a zero-sized cpu_microcode_blob.bin file to CBFS instead of complaining that the file could not be found. Also, we have to manually set the memory location and file size in the config file, even though those values could easily be programatically retrieved using the same CBFS APIs I used for the &#8216;console&#8217; file.</p>
<p>Anyways, once I added the microcode file and set its position and length in the config, the FspTempRamInit was successful and the bootblock finished and loaded the romstage, which of course crashed at the FspMemoryInit call.</p>
<p>I will spare you the details today of how we got the memory init to work, and I will leave that for a future blog post. Suffice to say that it wasn&#8217;t trivial, but once we got memory working, we ended up with another crash. This time, the last line from the log was :</p>
<pre>Calling FspTempRamExit API</pre>
<p>After investigating the code, it looked like right after that call, the romstage main was returning, and it was jumping back into assembly code to teardown the Cache-as-RAM system that had been setup initially, then it would call the ramstage. I started trying to understand all it did, and trying to figure out why it would crash in the assembly code, and what might have been different in the various registers, etc.. Thankfully, I didn&#8217;t waste too much time on this, because Matt was asked to test something on a Google Sentry Chromebook, so he switched his environment to the Sentry and tested what he had to test for someone else, and then he saw that it was crashing at the exact same place as us on the v2. It was working for him before, and yet, it wasn&#8217;t working now. He realized he still had the cbfsconsole enabled, and once he disabled it, it booted. This was an incredibly lucky thing for us to realize (without wasting a week on this), that cbfsconsole was the one blocking coreboot. Once I disabled cbfsconsole support for bootblock and romstage, I was happy to see the ramstage booting and the screen light up!</p>
<p>For a while though, I kept it like that. We didn&#8217;t need to have cbfsconsole working for both romstage and ramstage, as long as ramstage was booting, that&#8217;s all I needed to see the logs of. Fast forward a couple of weeks later, and after the port was done, I came back to this issue. Actually, I simply mentioned the problem that I &#8220;still have to fix&#8221; on IRC and Aaron Durbin diagnosed the problem and came up with the solution right away. You see, when you use CAR_GLOBAL variable, and the FspTempRamInit is called (which tears down the cache-as-ram), the content of those global CAR variables are copied to the actual RAM, and it works just fine. However, if your variable itself contains a pointer to another CAR variable, then your data was copied but its content points to the old cache address, so when you try to access it, you can&#8217;t. This is what was happening for cbfsconsole. The SPI handler itself had the bug because it was storing a pointer to the SPI driver and that variable was wrong after the CAR was removed. The trick to fix it was to simply replace the calls &#8220;<em>car_get_var_ptr</em>&#8221; into &#8220;<em>car_sync_var_ptr&#8221;</em> which would migrate the data to the appropriate RAM location before returning the CAR pointer. Once I did that, the cbfsconsole was working on all 3 stages at the same time and without issues.</p>
<h1>Porting to FMAP</h1>
<p>There was one discussion we had on IRC about cbfsconsole, which was about how it should not be writing to the CBFS in the first place. My argument was that the MRC cache is also written in a CBFS file. The MRC cache is a memory cache, because memory discovery, test and initialization takes about 10 seconds, but those RAM settings are saved in the cache, which can be provided to the FSP, and subsequent boots only take 200 ms to initialize the RAM with the cache. Aaron thought that was wrong too and that the CBFS API doesn&#8217;t provide us with any writing mechanism. It is true after all, I used the CBFS API to find the offset and size in the flash for the console file, and used a different API to write to it. Coreboot has a different concept called FMAP (Flash map), which is used to map different areas in the flash to be used by coreboot. The FMAP defines the size of the flash, the offset/size of the BIOS region, and in that region, the offset and size of the CBFS. Aaron believes that the console log should have been written to a separate FMAP area besides the CBFS rather than inside a CBFS file itself. The reason is simple, while it is currently possible to write to it, it is possible that in the future, the CBFS would implement a checksum system, which would become broken if we wrote to it directly in the manner I just used (I think it actually already has checksums, I just ignore them).</p>
<p>After the discussion about the pros/cons of using FMAP instead of CBFS to store the console log, I decided to rename my cbfsconsole driver into &#8216;flashconsole&#8217;, and I implemented support for using an FMAP area. The code has even been simplified now because the FMAP API can directly return the right Read/Write object for us to use and there is no need to work around the limitation of the CBFS API. When the option is enabled the CONSOLE area is automatically added to the resulting coreboot image, and once you dump your flash, you can extract the FMAP console, using this command :</p>
<pre>cbfstool rom.bin read -r CONSOLE -f console.log</pre>
<p>And that&#8217;s it.</p>
<h1>Conclusion</h1>
<p>The Librem port was a great experience, but it would never have been possible without having access to a debug log. I am happy to have implemented the flashconsole method of debugging, which will be very useful in the future for anyone who wants to port coreboot to a new board, for which they do not have easy access to UART pads. I have sent this feature upstream for review, and it has been merged. You can see it <a href="https://review.coreboot.org/#/c/19849/">here</a>.</p>
<p>In my next blog post, I will explain how we got the memory init to work, and the various issues we got. Also, what actual steps are needed to port a new board to coreboot (GPIO, memory, PCI, ACPI) and what I&#8217;ve learned in the past 2 weeks.</p>
<p>Stay tuned!</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/coreboot-on-the-librem-13-v2-part-1/">Coreboot on the Librem 13 v2, part 1</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Reverse-engineering the Intel Management Engine&#8217;s ROMP module</title>
		<link>https://puri.sm/posts/reverse-engineering-the-intel-management-engine-romp-module/</link>
		<pubDate>Wed, 10 May 2017 16:12:30 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Additional Press Information]]></category>
		<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>
		<category><![CDATA[Reverse engineering]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Software freedom]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=18666</guid>
		<description><![CDATA[<p>Last month, while I was waiting for hardware to arrive and undergo troubleshooting, I had some spare time to begin some Intel ME reverse engineering work. First, I need to give some shout out to Igor Skochinsky, a Hex-Rays developer, who had been working on reverse engineering the Intel ME for a while, and who [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/reverse-engineering-the-intel-management-engine-romp-module/">Reverse-engineering the Intel Management Engine&#8217;s ROMP module</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Last month, while I was waiting for hardware to arrive and <a href="https://puri.sm/posts/preventing-interference-from-the-old-bios-while-flashing-coreboot/">undergo troubleshooting</a>, I had some spare time to begin some <a href="https://puri.sm/learn/intel-me/">Intel ME</a> reverse engineering work.<span id="more-18666"></span></p>
<p>First, I need to give some shout out to <a href="https://www.slideshare.net/codeblue_jp/igor-skochinsky-enpub">Igor Skochinsky</a>, a Hex-Rays developer, who had been working on reverse engineering the Intel ME for a while, and who has been very generous in sharing his notes and research on the ME with us, which is going to be a huge help and cut down months of reverse engineering and guesswork. Igor was very helpful in getting me to understand the bits that didn&#8217;t make sense to me.</p>
<p>The first thing I wanted to try and reverse was the ROMP module. It is one of the two modules that me_cleaner doesn&#8217;t remove, and given how small it is (less than 1KB of code+data), I thought it would be a good starting point. Turns out my hunch was right, as I finished reverse engineering that module after only a couple of days.</p>
<p>I have uploaded the C equivalent of the code to my github account and you can see the file here:<a href="https://github.com/kakaroto/purism-playground/blob/master/me_re/romp.c"> romp.c</a> as well as the <a href="https://github.com/kakaroto/purism-playground/blob/master/me_re/rapi.h">rapi.h</a> header that I used for defining RAPI (ROM API) calls and data structures (most of that info was taken from Igor&#8217;s shared information). Note that this romp.c/rapi.h code is not meant to be compiled (for now), but serves more as a proof of concept—or a way for others who are less at ease with assembly to audit the code and understand what it does exactly. A long term goal would be to make it compile and generate a binary-compatible result (with the same hash as the Intel files).</p>
<p>There are some more good news too: in that small bit of code, I have already found one bug in their implementation. I doubt that particular bug instance is exploitable as-is, but it&#8217;s a good indicator that their code is probably going to be full of bugs and it won&#8217;t be long before we find an exploitable one.</p>
<ul>
<li>The bug is simple: when the ROMP module reads the partition from the SPI flash, after it validates the RSA signature, it copies it to a memory address and locks that memory address so it can&#8217;t be modified by the main CPU. However, they made a mistake and didn&#8217;t shift the size by 2 (effectively multiply by 4), which means that they are only locking ¼ of the region that needs to be locked. This could mean that there is a portion of the partition manifest that is accessible by the CPU which could allow us to modify the hash of a module and put our own code in it, since the signature has already been checked, and the module hash is in that ¾ portion that isn&#8217;t locked.</li>
<li>Unfortunately, we can&#8217;t seem to be able to use it because the ROMP module is executed very early, before the DRAM is initialized, and so it&#8217;s probably using/locking the internal RAM of the Intel ME ARC core, not the RAM of the main CPU. If, however, I can find the same bug (crossing fingers for a lazy Intel developer doing a copy/paste of that code) in the BUP module or any other module that executes on the main RAM, it would become exploitable and would allow us unsigned code execution on the ME processor… Which would be a nice shortcut for us.</li>
</ul>
<p>As the Intel Management Engine&#8217;s ROMP module is now reversed and auditable (bringing us one little step closer in the <a href="https://puri.sm/learn/freedom-roadmap/">freedom roadmap</a>), we now understand much better what it&#8217;s doing (Igor thinks it might be a way to recover from an incomplete ME update, since it looks for an FTPR-named partition in the NFTP partition of the FPT header). We&#8217;ll continue digging soon. For the time being, as I received hardware prototypes for <a href="https://puri.sm/posts/spring-2017-product-design-update/">the new batch of Librems</a>, I need to get back to porting them to coreboot.</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/reverse-engineering-the-intel-management-engine-romp-module/">Reverse-engineering the Intel Management Engine&#8217;s ROMP module</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Preventing AMI&#8217;s BIOS from interfering with coreboot flashing on the Librem 13</title>
		<link>https://puri.sm/posts/preventing-interference-from-the-old-bios-while-flashing-coreboot/</link>
		<pubDate>Fri, 14 Apr 2017 21:05:07 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Benchmarks and testing]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Laptops]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=16932</guid>
		<description><![CDATA[<p>I wrote recently about one of our collaborators having tried to install coreboot and unfortunately bricking his laptop in the process. I sent him mine as a replacement, then he swapped hard drives and he sent me his testing unit, so that I could investigate what happened. This is what we found. Once I received [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/preventing-interference-from-the-old-bios-while-flashing-coreboot/">Preventing AMI&#8217;s BIOS from interfering with coreboot flashing on the Librem 13</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>I wrote <a href="https://puri.sm/posts/neutralizing-intel-management-engine-on-librem-laptops/">recently</a> about one of our collaborators having tried to install coreboot and unfortunately bricking his laptop in the process. I sent him mine as a replacement, then he swapped hard drives and he sent me his testing unit, so that I could investigate what happened. This is what we found.<span id="more-16932"></span></p>
<p>Once I received his laptop, I obviously wanted to dump its flash to see what went wrong, but it was&#8230; not cooperating. My external programmer setup was working fine with my previous laptop, but now it was somehow completely unable to detect the ROM chip. I set out to figure out why, I tried everything: I used my logic analyzer to see if the SPI data had the right values, I tried a different power supply, a different FTDI chip, different USB cables, anything I could think of&#8230; and it made no sense whatsoever. Sometimes it would show me the right data in the logic analyzer, but the FTDI would not see the same data; most of the times though, it looked as if the MISO pin was being pulled high, so I even tried to wire a resistor to ground in order to pull down on the MISO pin, without luck.</p>
<p>Then, after four hours of intense troubleshooting, it suddenly worked, without warning. What had I done to make it work? I had no idea at first on what I did, but I remembered this as being my last sequence of events before it had worked :</p>
<ol>
<li>I had a suspicion of a defective FTDI chip and was using my backup chip (which was also not working up until now);</li>
<li>I had powered down the ATX power supply providing 3.3V to the motherboard</li>
<li>I used the laptop&#8217;s power supply to turn on the laptop and try to read the chip while it was on (knowing quite well that it wouldn&#8217;t work since the motherboard itself would be driving the SPI chip&#8217;s pins high/low, thus interfering with the FTDI chip);</li>
<li>I shut down the laptop, removed the charging cable and put the external power supply on again</li>
<li>I tried to dump the flash, and that&#8217;s when it worked!</li>
</ol>
<p>I had done similar manipulations hundreds of times already, and whenever I connected the flasher to the ROM (battery removed of course  and external ATX power supply on), the flasher couldn&#8217;t detect the chip. Quite annoying.</p>
<p><strong>Then I found a way to trick the hardware.</strong> While the FTDI chip is connected to the SPI flash, if I insert the charging cable into the laptop for about 2 seconds (and quickly remove it) <em>then</em> turn the power supply back on&#8230; suddenly the FTDI can detect and read/write to the flash chip without problems. Without a doubt this makes no sense at all (the joys of hardware), but it is 100% reproducible, so when I discovered that trick I simply thanked the lords of Kobol for their offering and I dumped the flash, then unbricked the laptop. Oh, and yes, my original FTDI chip had become defective, so switching to the backup one was also a required step.</p>
<h1>Encounters with chimeras</h1>
<figure id="attachment_17350" style="width: 462px" class="wp-caption alignright"><img class="wp-image-17350 size-full" src="https://puri.sm/wp-content/uploads/2017/03/Chimera-PSF.jpg" alt="" width="462" height="502" srcset="https://puri.sm/wp-content/uploads/2017/03/Chimera-PSF.jpg 462w, https://puri.sm/wp-content/uploads/2017/03/Chimera-PSF-276x300.jpg 276w" sizes="(max-width: 462px) 100vw, 462px" /><figcaption class="wp-caption-text">Behold, the &#8220;AMI-coreboot&#8221; chimera.</figcaption></figure>
<p>Inspecting the flash dump, I was in for a surprise: the coreboot image was corrupted in a strange way, it had parts of the old AMI BIOS in the middle of the coreboot BIOS. Essentially, a chimera.</p>
<p>Let&#8217;s study this strange creature.</p>
<ul>
<li>The old factory BIOS started at offset 0x200000 in the ROM (the first 2MB of the ROM are reserved for the ME)</li>
<li>After coreboot was flashed, the old factory BIOS had apparently &#8220;moved&#8221; and was now in the ROM at offset 0x220000…</li>
<li>Unfortunately, coreboot was already at offset 0x200000, so 128KB (0x20000 bytes) into the coreboot image&#8217;s region, the old BIOS had somehow inserted itself there and was corrupting our coreboot image.</li>
</ul>
<p>I was completely baffled by that discovery. How could it have happened? The only thing I knew was that our collaborator had flashed coreboot from within <a href="https://www.qubes-os.org/" target="_blank">Qubes OS</a>, so I installed Qubes OS, spent some time learning how to use it, figured out how to install flashrom into &#8220;dom0&#8221;, how to move my coreboot image into dom0 and how to flash it. I rebooted and&#8230; it was working fine. So the problem wasn&#8217;t QubesOS, which brought me back to square one. I shelved the problem at that time and moved on to writing my coreboot installation script instead.</p>
<p>After my coreboot installation script was done, it was time to beta-test it (beyond just testing it myself). François Téchéné from our team volunteered to try it on his Librem 13. To be sure, I hopped on a conference call with him for this operation. Everything was going well, and after he powered off his laptop… it was a brick too. Curses!</p>
<p>Well, we&#8217;re back to the chimera then. Now we have seen <em>two</em> chimeras, so we know they&#8217;re real. Why was it working for me (I tested at least 100 times during development of the script) and Todd but not for <em>some</em> others? I tried the script again on my machine, powered off the laptop, and then got a brick too. I retried multiple times and kept getting the same corrupted coreboot image with the displaced old BIOS written in the middle of it. This was making less and less sense, and making me more and more tense. <strong>What was wrong with my alchemy?!</strong></p>
<p>My script was already testing that flashrom was writing the ROM properly (by reading it back and ensuring it would get the exact same hash), but in this case after turning off the computer, I would get a different reading (the corrupt image) when reading with an external flash programmer. Below are some comparisons (left vs right) where you can see, on the left, the original BIOS image, and on the right, the chimera :</p>
<p>You see how the images match but the offsets are different (from 0x200000 to 0x220000) :</p>
<p><img class="alignnone size-large wp-image-17347" src="https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-2-1024x491.png" alt="" width="960" height="460" srcset="https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-2-1024x491.png 1024w, https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-2-300x144.png 300w, https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-2-768x368.png 768w, https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-2.png 1468w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p>And this is the end of the changes, where you can see that the data is not entirely the same (the top part, also some of the lower part is mangled), and the data is matching from 0x21FFFF in the original BIOS with the 0x23FFFF in the chimera) :</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-1.png"><img class="alignnone size-large wp-image-17346" src="https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-1-1024x474.png" alt="" width="960" height="444" srcset="https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-1-1024x474.png 1024w, https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-1-300x139.png 300w, https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-1-768x356.png 768w, https://puri.sm/wp-content/uploads/2017/03/ami-interference-flashrom-1.png 1500w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p>I wondered if there was a bug in flashrom or in the internal SPI programmer that would cause this corruption. Maybe it was writing incorrectly but somehow caching the data so that when we read it back (and when flashrom itself verifies the data after it wrote it) it would give us the data we asked to write but not the one that was actually written?</p>
<h1>Finding the alkahest</h1>
<p>As I asked around on IRC in the #flashrom channel, <em>agaran</em> (IRC nickname) came to the rescue and after analyzing the binary files and the diffs (images above), he noticed that the &#8220;old BIOS&#8221; data looked more like some &#8220;NVRAM Storage&#8221; instead of being actual BIOS code. He suggested that maybe something was writing that data when I was powering off the laptop.</p>
<p><img class="alignright wp-image-17351" src="https://puri.sm/wp-content/uploads/2017/03/The-Alchymist-in-Search-of-the-Philosophers-Stone.jpg" alt="" width="478" height="627" srcset="https://puri.sm/wp-content/uploads/2017/03/The-Alchymist-in-Search-of-the-Philosophers-Stone.jpg 600w, https://puri.sm/wp-content/uploads/2017/03/The-Alchymist-in-Search-of-the-Philosophers-Stone-229x300.jpg 229w" sizes="(max-width: 478px) 100vw, 478px" />At that moment, I had an epiphany:<strong> all these last few months, I was almost always rebooting (or suspending) the machine after flashing coreboot, and when I was actually powering it off, it was quite probably always when I was testing a new coreboot version on a laptop that already had a previous version of our coreboot image!</strong> When I was in the conference call with François, he said, &#8220;I&#8217;ll power off the laptop&#8221;, which somehow stuck in my mind so when testing on my own later that day I was now subconciously using the &#8220;poweroff&#8221; command instead of the &#8220;reboot&#8221; command, which made all the difference!</p>
<p>I then spent a couple of days testing: I flashed the original factory BIOS, powered off, then flashed coreboot, then powered off again (or suspended, or rebooted, depending on the test case), probably 20 times for each scenario (every poweroff required flashing using the external hardware flasher, which required the charging cable trick to make it detect the rom). I was then able to confirm that:</p>
<ul>
<li>Whenever we use &#8220;poweroff&#8221;, or even using &#8220;echo o &gt; /proc/<a href="https://en.wikipedia.org/wiki/Magic_SysRq_key">sysrq-trigger</a>&#8220;, the flash was getting corrupted.</li>
<li>If we &#8220;reboot&#8221;, &#8220;pm-suspend&#8221;, &#8220;halt&#8221;, do a force shutdown by holding the power button, or &#8220;echo b &gt; /proc/<a href="https://en.wikipedia.org/wiki/Magic_SysRq_key">sysrq-trigger</a>&#8220;, the flash would not get corrupted and coreboot would be fine.</li>
<li>No corruption happens if I power off when coreboot is running. This only happens if the currently-running BIOS is the factory AMI BIOS.</li>
</ul>
<p>I had eventually connected my logic analyzer again, and realized that the corruption was happening <em>after</em> the Linux power off sequence, right after the screen backlight turns off and before the power LED turns off. I was happy to have written my previous script to analyze the logic trace and return a command execution log, which showed me that indeed, that&#8217;s what was running and rewriting my sectors.</p>
<p>The best explanation we have so far is that the factory BIOS has an <a href="https://en.wikipedia.org/wiki/System_Management_Mode">SMM</a> hook on the <a href="https://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface#Global_states">S5</a>-state transition (shut down), which gets part of the old BIOS to execute, verify if the BIOS settings it has in memory are still matching the values in the ROM, if it doesn&#8217;t match, then it writes them back again. Because why not. And the reason the data is displaced by an offset of 128KB is probably because that same BIOS code will not find the NVRAM storage at its usual 0x200000 offset, so it decides to leave that area intact and instead just write it in the 0x220000 offset).</p>
<h1>Turning lead into gold</h1>
<p>In theory, the workaround is easy: <em>reboot and do not power off after installing coreboot.</em> However, as I&#8217;m writing an install script that should work for every Librem 13 users, and I want it to be as fool-proof as possible, I cannot allow that. Sure, I could have the script&#8217;s startup tell people that they need to reboot their machine at the end of the script and that it &#8220;can&#8217;t be postponed&#8221;, and then have the reboot done as part of the script itself, but what if someone prevents it from rebooting, and ends up shutting down their laptop instead? I&#8217;m sure there <em>will</em> be someone who does that, bricking up their laptop in the process, and we certainly don&#8217;t want that. So I started looking for an alternative solution to leave no margin for error.</p>
<p>There is no obvious way (that I could find) to disable that SMM hook, so I eventually decided to simply shift the coreboot image to a different region in the flash ROM, leaving that &#8220;AMI bios settings&#8221; area free. By doing so, we waste about 256KB of the 6MB BIOS region, but we are not that constrained for space and it&#8217;s a much better solution than risking a brick.</p>
<p>So <strong>now, I have a coreboot image that works in <em>both</em> situations;</strong> whether you power off or reboot your laptop, it will not get corrupted anymore, no matter what (but my script still does an automatic reboot at the end to make sure the old BIOS SMM hook doesn&#8217;t get executed, as an extra safety measure). What a great way to end the week!</p>
<p><em>— this epic tale was brought to you by Youness&#8217; scientific rigor and Jeff&#8217;s homeric storytelling</em></p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/preventing-interference-from-the-old-bios-while-flashing-coreboot/">Preventing AMI&#8217;s BIOS from interfering with coreboot flashing on the Librem 13</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Neutralizing the Intel Management Engine on Librem Laptops</title>
		<link>https://puri.sm/posts/neutralizing-intel-management-engine-on-librem-laptops/</link>
		<pubDate>Thu, 09 Mar 2017 15:00:37 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Benchmarks and testing]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Linux kernel]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>
		<category><![CDATA[Privacy]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Software freedom]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=15191</guid>
		<description><![CDATA[<p>In my last blog post, I have spoken of the completion of the Purism coreboot port for the Librem 13 v1 and mentioned that I had some good news about the Intel Management Engine disablement efforts (to go further than our existing quarantine) and to &#8220;stay tuned&#8221; for more information. Since then I got a [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/neutralizing-intel-management-engine-on-librem-laptops/">Neutralizing the Intel Management Engine on Librem Laptops</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In my <a href="https://puri.sm/posts/librem-13-coreboot-report-february-25th-2017/">last blog post</a>, I have spoken of the completion of the <a href="https://puri.sm/coreboot/" target="_blank">Purism coreboot port</a> for the Librem 13 v1 and mentioned that I had some good news about the Intel Management Engine disablement efforts (to go further than <a href="https://puri.sm/learn/avoiding-intel-amt/" target="_blank">our existing quarantine</a>) and to &#8220;stay tuned&#8221; for more information. Since then I got a little side-tracked with some more work on coreboot (more below), but now it&#8217;s time to share with you the good news!<span id="more-15191"></span></p>
<h1>Ladies and Gentlemen, Clean Your Engines!</h1>
<p><strong>I am happy to say that neutralizing the ME works! </strong>I investigated the effectiveness of neutralizing the Management Engine using the <a href="http://github.com/corna/me_cleaner">me_cleaner</a> tool (which is an amazing feat of the community), and then I tested to make sure the ME was indeed neutralized and that the Librem 13 stays on for over 30 minutes. We plan to <strong>go even further than that</strong> in the future and <strong>reverse-engineer the remaining parts</strong> just so we can attain 100% freedom.</p>
<p>First of all, you need to understand what me_cleaner does. You can of course go read the technical details on their wiki on <a href="https://github.com/corna/me_cleaner/wiki/How-does-it-work%3F">how it works</a>, but to put it simply, the ME is organized in multiple <a href="https://www.slideshare.net/codeblue_jp/igor-skochinsky-enpub/17">modules</a>, each handling a specific task. The me_cleaner tool deletes most modules (utilities, kernel, network stack, and a Java virtual machine<em>—Yes! You read that right</em>), pretty much everything except the hardware initialization (BUP = Bring UP) module in the ME image. After the BUP module is executed, it can&#8217;t find the other modules, so it stops executing (as it has nothing to execute into), but at that point the 30 minutes watchdog has <em>already</em> been disabled by the BUP itself, so we can keep running. This is already a great improvement! The watchdog is precisely the issue that had been blocking us when we did our initial investigations a year ago.</p>
<p>After I ran the me_cleaner script on the BIOS image, and flashed it, I needed to test and make sure that the ME was indeed neutralized. I used the &#8220;intelmetool&#8221; that comes with coreboot and which is used to communicate with the ME PCI device to get information from it. Unfortunately, the intelmetool kept crashing, which was a good sign because it apparently couldn&#8217;t find the ME, but a crash (segmentation fault) is not really a conclusive answer… so I looked at its code, figured out what it did wrong, fixed it, then tested it again. This time, it gave me lots of output, and it confirmed that the ME was basically unresponsive. I then checked the output of &#8220;cbmem&#8221;—coreboot&#8217;s debug log during the boot sequence—and it showed that the ME was now stuck in &#8220;bring up phase&#8221;, its state was &#8220;recovery&#8221; instead of &#8220;normal&#8221;.</p>
<p>Bring out the Champagne! The ME is not only <a href="https://puri.sm/learn/avoiding-intel-amt/" target="_blank">quarantined</a>, it is <strong>now officially neutralized</strong> and the Librem remains working beyond the 30 minutes time limit that Intel had put in place!</p>
<figure id="attachment_15692" style="width: 721px" class="wp-caption alignnone"><a href="https://en.wikipedia.org/wiki/File:Veuve_clicquot_bottle_sizes.jpg" target="_blank"><img class="wp-image-15692 size-full" src="https://puri.sm/wp-content/uploads/2017/03/Veuve-clicquot-Champagne-bottles.jpg" alt="Champagne bottles" width="721" height="514" srcset="https://puri.sm/wp-content/uploads/2017/03/Veuve-clicquot-Champagne-bottles.jpg 721w, https://puri.sm/wp-content/uploads/2017/03/Veuve-clicquot-Champagne-bottles-300x214.jpg 300w" sizes="(max-width: 721px) 100vw, 721px" /></a><figcaption class="wp-caption-text">Pictured: our recommended &#8220;Defeat of the Intel ME&#8221; celebration kit.</figcaption></figure>
<h1>The remains</h1>
<p>A question remains, however: &#8220;What exactly did we remove, and what remains?&#8221; So I tried to dig into that as well.</p>
<p>First of all, the Intel ME image takes 2MB of space in the BIOS flash, but not all of those 2MB are used. It&#8217;s made of different modules, which can be compressed with LZMA or with a private/secret Huffman dictionary. There is a total of 1.2MB of actual compressed code in the image, which gives us a total of 1.6MB (1662976 bytes) of uncompressed code in 23 modules.</p>
<p>Of those 23 modules, 21 modules are completely removed from the ME partition, and we leave only 2 modules: ROMP and BUP. The ROMP module is <span style="text-decoration: line-through;">a &#8220;ROM bypass&#8221; module which is used to bypass the ROM initialization code and it&#8217;s</span> less than 1KB of code, used to load the BUP module and execute it. The BUP module is a 116KB module which is used to initialize the ME hardware. So we end up with 120KB (122880) of data (108224 bytes actually, if we ignore the end of the ROMP and BUP modules which are empty) which represents 7.38% of the total ME code. We have effectively removed over 92.6% of the ME code without any adverse effects (but see further below).</p>
<p>And so we removed <em>plenty of stuff,</em> but most importantly, <strong> we completely removed the ME kernel as well as the network stack.</strong> You can see the full list of modules here:</p>
<pre>## Original ME modules :
total 1.6M
8.0K -rw-r--r-- 1 kakaroto kakaroto 8.0K Feb 28 17:08 AFWS-20687000.mod
12K -rw-r--r-- 1 kakaroto kakaroto 12K Feb 28 17:08 BOP-20392000.mod
116K -rw-r--r-- 1 kakaroto kakaroto 116K Feb 28 17:08 BUP-200d4000.mod
16K -rw-r--r-- 1 kakaroto kakaroto 16K Feb 28 17:08 CLS-206e0000.mod
4.0K -rw-r--r-- 1 kakaroto kakaroto 4.0K Feb 28 17:08 ClsPriv-20716000.mod
12K -rw-r--r-- 1 kakaroto kakaroto 12K Feb 28 17:08 FPF-206b3000.mod
132K -rw-r--r-- 1 kakaroto kakaroto 140K Feb 28 17:08 FTPM-20777000.mod
60K -rw-r--r-- 1 kakaroto kakaroto 60K Feb 28 17:08 HOSTCOMM-20396000.mod
24K -rw-r--r-- 1 kakaroto kakaroto 24K Feb 28 17:08 HOTHAM-2032b000.mod
16K -rw-r--r-- 1 kakaroto kakaroto 16K Feb 28 17:08 ICC-203ad000.mod
272K -rw-r--r-- 1 kakaroto kakaroto 272K Feb 28 17:08 JOM-208c2000.mod
344K -rw-r--r-- 1 kakaroto kakaroto 344K Feb 28 17:08 KERNEL-200f8000.mod
28K -rw-r--r-- 1 kakaroto kakaroto 28K Feb 28 17:08 MCTP-20379000.mod
28K -rw-r--r-- 1 kakaroto kakaroto 28K Feb 28 17:08 ME_TUNNEL-203b4000.mod
52K -rw-r--r-- 1 kakaroto kakaroto 52K Feb 28 17:08 NET_STACK-20383000.mod
20K -rw-r--r-- 1 kakaroto kakaroto 20K Feb 28 17:08 NFC-208bb000.mod
196K -rw-r--r-- 1 kakaroto kakaroto 204K Feb 28 17:08 Pavp-20040000.mod
124K -rw-r--r-- 1 kakaroto kakaroto 124K Feb 28 17:08 POLICY-2034d000.mod
4.0K -rw-r--r-- 1 kakaroto kakaroto 4.0K Feb 28 17:08 ROMP-200d2000.mod
60K -rw-r--r-- 1 kakaroto kakaroto 60K Feb 28 17:08 SESSMGR-20719000.mod
44K -rw-r--r-- 1 kakaroto kakaroto 44K Feb 28 17:08 SESSMGR_PRIV-2015a000.mod
4.0K -rw-r--r-- 1 kakaroto kakaroto 4.0K Feb 28 17:08 UPDATE-2003e000.mod
32K -rw-r--r-- 1 kakaroto kakaroto 32K Feb 28 17:08 utilities-2036f000.mod
## Cleaned ME modules :
total 120K
4.0K -rw-r--r-- 1 kakaroto kakaroto 4.0K Feb 28 17:15 ROMP-200d2000.mod
116K -rw-r--r-- 1 kakaroto kakaroto 116K Feb 28 17:15 BUP-200d4000.mod</pre>
<h1>A few things to watch out for</h1>
<h2>Possible graphics problems</h2>
<p>Unfortunately for me, on one of my machine&#8217;s set-ups, the i915 graphics driver would constantly crash with Wayland. I have tried an Ubuntu 16.04  live USB and haven&#8217;t had any problems with it, but when trying with two different PureOS installs, I had one being extremely stable while the other had the graphics driver crashing. I could still SSH into the machine and do what I wanted, but I couldn&#8217;t login into my desktop. Running &#8220;startx&#8221; in a terminal was working, however, without causing additional crashes of the graphics driver.</p>
<p>Other people on the team tested on their own Librem 13 and couldn&#8217;t reproduce the issue.</p>
<p>I spent some time trying to debug that phenomenon, but without much success. I tried updating/downgrading the kernel and comparing Wayland versions, and couldn&#8217;t figure out what was different between my two PureOS installs. I eventually put that aside because I had other things to do, and this could wait, given that I only experienced this problem on one particular machine.</p>
<h2>Microcode or no microcode, that is the question!</h2>
<p>Then came the idea of removing the microcode update from coreboot. This is a tricky question.</p>
<ul>
<li>The way the CPU is made, it comes with a predefined &#8220;microcode&#8221;, basically some sort of &#8220;arrangement&#8221; of the low-level transistor blocks to define the &#8220;high-level&#8221; x86 instruction sets the processor supports. Sometimes if an instruction doesn&#8217;t behave the way it should, Intel will release a microcode update to &#8220;re-arrange&#8221; the transistor blocks in order to fix bugs in how the instructions are behaving. Those bugs can be anything: silent data corruption, security flaws, or very visible kernel panics.</li>
<li>Some people, however, may decide not to have a microcode update in their BIOS because it&#8217;s technically an <a href="https://puri.sm/learn/blobs/" target="_blank">unknown binary</a>—even though the CPU hardware itself already comes with an initial microcode configuration pre-burned in its silicon.</li>
</ul>
<p>After researching the implications of removing the microcode update from coreboot, I tested it. I ran prime95 for over 28 hours without any errors (what I forgot to mention in <a href="https://puri.sm/posts/librem-13-coreboot-report-february-25th-2017/" target="_blank">my previous blog post</a> is that my prime95 results back then were actually made on a microcode-less system!) The system seems to run fine, boots, logs me in without problems and is perfectly usable, so that&#8217;s great… but it&#8217;s of course no guarantee that the system won&#8217;t have hidden bugs that I can&#8217;t notice, or small data corruption, etc. If anyone wants to remove the microcode updates from their BIOS, they can do that, and they can be safe in knowing that the system will be &#8220;usable&#8221;, but of course this comes with a big disclaimer on the risks involved. Todd (our CEO) has tested his machine extensively with coreboot without microcode updates and said that the machine would lock-up completely in less than 24 hours, after a few days of testing, he added back the microcode updates and the system became stable again. Your mileage may vary.</p>
<p>Here are some comments about this that I&#8217;ve received from the #coreboot IRC channel:</p>
<blockquote><p>&lt;avph&gt; microcode problems are weird. They can appear in many different problems. I have encountered: VT-X very broken, movies playing (SIMD broken?), wrong CPUID, &#8230;<br />
&lt;pgeorgi&gt; I guess the most common issues fixed by microcode updates are typically related to caching bugs, which often have security impact. TLB broken, write-back unstable, stuff like that. There&#8217;s hardly a single tool you can run and hope that it&#8217;ll catch all those bugs.<br />
&lt;the7thstranger&gt; I have never seen an x86 chip that didn&#8217;t fail in some way without ucode updates, so don&#8217;t get your hopes up</p></blockquote>
<h1>Back for more coreboot work</h1>
<p>In the introduction, I mentioned some coreboot issues that distracted me. Nothing major at the beginning: there was a small typo (and apparently without consequences) in one of the commits I wrote in coreboot, which was not noticed until after it was merged, so I had to fix that (quick and easy) and send it to coreboot for <a href="https://review.coreboot.org/#/c/18514/">review</a>/merging (not so quick and easy). The coreboot team was great in giving me good feedback pretty quickly (my commit message wasn&#8217;t up to their standards because I did it in a rush), and it got merged upstream.</p>
<p>Then, unfortunately, during beta testing, someone in the team bricked his Librem 13 (good thing we&#8217;re testing with our own devices first, huh?) We&#8217;re not yet sure why this happened, so I&#8217;m waiting to receive this person&#8217;s unit to debug that. In the meantime, I had to send my Librem 13 to them so they can get their laptop back to work. Once I receive their &#8220;brick&#8221;, I&#8217;ll be able to investigate why it&#8217;s not booting, whether it was a problem in flashing coreboot (due to QubesOS or a bad version of flashrom or due to user error), if it&#8217;s a problem with coreboot itself, or if it&#8217;s a problem with the hardware (that laptop might have been an early prototype, which means the hardware may be different, I&#8217;ll have to check to make sure).</p>
<p>For now, I&#8217;m also still working on a fool-proof (as much as possible) install script that will build coreboot for you and install it, limiting any risks of user-error that might cause a bricked machine. Once I know what happened to that bricked Librem (and fix it), then I&#8217;ll be able to continue working on that installation script (it&#8217;s hard to test it without any hardware on hand!), after which we&#8217;ll do some more &#8220;in-house&#8221; beta testing before releasing a public beta test for everybody.</p>
<p>Thankfully, any brick of the laptop can easily be recovered by using an external hardware flasher and the original BIOS. I have the original BIOS from that specific machine, since a backup was made before coreboot was flashed to it, so I can recover it quickly.</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/neutralizing-intel-management-engine-on-librem-laptops/">Neutralizing the Intel Management Engine on Librem Laptops</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>The Librem 13 v1 coreboot port is now complete</title>
		<link>https://puri.sm/posts/librem-13-coreboot-report-february-25th-2017/</link>
		<pubDate>Sat, 25 Feb 2017 22:00:29 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Benchmarks and testing]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Giving and contributing back]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>
		<category><![CDATA[Software freedom]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=14838</guid>
		<description><![CDATA[<p>Here are the news you&#8217;ve been waiting for: the coreboot port for the Librem 13 v1 is 100% done! I fixed all of the remaining issues, it is now fully working and is stable, ready for others to enjoy. I fixed the instability problem with the M.2 SATA port, finished running all the tests to [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/librem-13-coreboot-report-february-25th-2017/">The Librem 13 v1 coreboot port is now complete</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p><a href="https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.29.42-small.jpg"><img class="alignright size-medium wp-image-15189" src="https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.29.42-small-300x168.jpg" alt="" width="300" height="168" srcset="https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.29.42-small-300x168.jpg 300w, https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.29.42-small-768x431.jpg 768w, https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.29.42-small.jpg 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a>Here are the news you&#8217;ve been waiting for: <strong>the coreboot port for the Librem 13 v1 is 100% done! </strong>I fixed all of the remaining issues, it is now fully working and is stable, ready for others to enjoy. I fixed the instability problem with the M.2 SATA port, finished running all the tests to ensure coreboot is working correctly, fixed the headphone jack that was not working, made the boot prettier, and started investigating the Intel Management Engine issue. Read on for details.<span id="more-14838"></span></p>
<p>Currently our test matrix looks like this—100% tested and working:</p>
<div style="color: #339966; font-size: 70%; text-decoration: line-through; column-count: 2; column-gap: 2%; -moz-column-count: 2; -webkit-column-count: 2; -moz-column-gap: 2%; -webkit-column-gap: 2%;">
<ol>
<li>Cold boot: memory controller works.</li>
<li>Cold boot: all installed DRAM is online.</li>
<li>Cold boot: graphics controller works.</li>
<li>Cold boot: SATA controller succeeds.</li>
<li>Cold boot: EC controller responds ok to init code.</li>
<li>Cold boot: LCD backlight turns on.</li>
<li>Cold boot: linux boots ok in text mode.</li>
<li>Cold boot: linux boots ok in framebuffer (boot splash) mode.</li>
<li>Cold boot: X initializes the LCD at full native resolution.</li>
<li>Cold boot: X enables hardware acceleration.</li>
<li>Boot time: Cold boot to grub succeeds in less than a set timeout.</li>
<li>Boot time: Reboot from linux back to linux succeeds in less than a set timeout.</li>
<li>Boot time: Power down succeeds in less than a set timeout.</li>
<li>SeaBIOS test: keyboard works.</li>
<li>Grub test: keyboard works.</li>
<li>Grub test: text mode and framebuffer graphics work.</li>
<li>Cold boot to USB linux succeeds.</li>
<li>Reboot to USB linux succeeds.</li>
<li>EC test: fan spins.</li>
<li>EC test: holding power for &gt;5 seconds forces a power down.</li>
<li>ACPI test: lid switch works.</li>
<li>ACPI test: power button event received ok.</li>
<li>ACPI test: AC power on/off event received ok.</li>
<li>ACPI+EC+battery test: battery percentage works.</li>
<li>Media keys on keyboard work in linux.</li>
<li>Device tests: internal mic, internal speakers, webcam, webcam mic, wifi, bluetooth, hard drive, SSD, SD card, each USB port, headphone jack.</li>
<li>prime95 (one instance bound to each hyperthread) for a fixed time to test CPU thermal management.</li>
<li>glxgears for a fixed time to test GPU thermal management.</li>
<li>During prime95 test, CPU digital thermal sensor should give reasonable results.</li>
<li>Linux suspend ok.</li>
<li>LCD backlight adjustable in linux.</li>
<li>Linux kernel boot messages should not contain too many errors.</li>
</ol>
</div>
<hr class="ttfmake-hr" style="border-style: dotted; border-top-width: 2px;" />
<p>The next steps will be:</p>
<ol>
<li>Write a script for users to beta test the coreboot release easily, and document the whole thing;</li>
<li>Determine the best method to extract the existing BIOS parts and flash coreboot, avoiding any code redistributing;</li>
<li>Package it all in a .deb that PureOS users can simply apply as an update to get their BIOS replaced by coreboot.</li>
</ol>
<hr class="ttfmake-hr" style="border-style: solid; border-top-width: 1px;" />
<h1>How did you fix those last issues?</h1>
<h2>The M.2 SATA port</h2>
<p>In my previous post I noted some <a href="https://puri.sm/posts/librem-13-coreboot-report-february-3rd-2017/">strange issues with the M.2 SATA port</a>. I thought it had something to do with the <a href="https://en.wikipedia.org/wiki/PCI_configuration_space">PCI configuration</a> (the subsystem ID was different). I hadn&#8217;t had time to investigate this too much, but I had an idea that needed to be reconsidered, something I had tried very early on but it had failed because coreboot didn&#8217;t support it, and I thought that I had the wrong idea&#8230;</p>
<p>Basically, the <a href="https://www.coreboot.org/Creating_A_devicetree.cb#Introduction">devicetree.cb</a> of the Librem 13 says this:</p>
<p><code> # Port 0 tuning for link stability<br />
register "sata_port0_gen3_dtle" = "9"</code></p>
<p>Since the 2.5&#8243; SATA is on port 0, while the M.2 SATA is on port 3, and my M.2 SATA issues were of a &#8220;link stability&#8221; nature, I figured, I&#8217;d just add this to the device tree and that this might solve the problem:</p>
<p><code> register "sata_port3_gen3_dtle" = "9"</code></p>
<p>…but that didn&#8217;t work outright (didn&#8217;t compile), so I shelved that idea.</p>
<p>After posting my previous blog entry mentioning the M.2 issue, I went on coreboot&#8217;s IRC channel and asked if this &#8220;gen3_dtle&#8221; thing could be the cause, and someone mentioned that the behavior I see is the exact behavior he was seeing on his board until he added a similar line to the devicetree.cb file for his board, so it at least confirmed that was my problem… but the SATA initialization code for the Intel Broadwell SoC does not have support for that register for port 3, only for port 0 and port 1. After looking at the code, I realized that it&#8217;s probably only because nobody had needed to use it for port 3 until today. Then comes the obvious question: what does that value mean, what is the SATA DTLE, and how do I add it for port 3? Well, the soc/intel/broadwell/sata.c file uses that devicetree register and sets some &#8220;IOBP Registers&#8221; on the SATA controller using that value, and the &#8220;IOBP registers&#8221; are defined in soc/intel/broadwell/include/soc/sata.h like this :</p>
<p><code>/* SATA IOBP Registers */<br />
#define SATA_IOBP_SP0_SECRT88 0xea002688<br />
#define SATA_IOBP_SP1_SECRT88 0xea002488<br />
#define SATA_IOBP_SP0DTLE_DATA 0xea002750<br />
#define SATA_IOBP_SP0DTLE_EDGE 0xea002754<br />
#define SATA_IOBP_SP1DTLE_DATA 0xea002550<br />
#define SATA_IOBP_SP1DTLE_EDGE 0xea002554</code></p>
<p>So the obvious next questions are &#8220;What are these magic numbers?&#8221; and &#8220;What magic number should I use for port 2 and port 3?&#8221;. Unfortunately, there really is <em>no information</em> about what these &#8220;IOBP registers&#8221; mean, or what those values are, or where to get them from. Someone in #coreboot said that information comes from an Intel specification document that is only available under <a href="https://en.wikipedia.org/wiki/Non-disclosure_agreement">NDA</a>.</p>
<p>Considering that &#8216;SP0&#8217; is for port 0 and &#8216;SP1&#8217; is for port 1, and that the value goes from 0xea002<strong>750</strong> for port 0 to 0xea002<strong>550</strong> for port 1… I thought, &#8220;It would be funny if…&#8221; and set port 2 as 0xea002<strong>350</strong>, port 3 as 0xea002<strong>150,</strong> and tested it. It worked! Those guessed magic values for port 2 and 3 fixed the M.2 instability issues I was seeing. Well. That went better than expected.</p>
<p>I then booted the Librem from the SSD and started testing everything else in my list, at which point I found out that the headphones jack wasn&#8217;t working.</p>
<p><img class="aligncenter size-full wp-image-15187" src="https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.46.29-small-crop.jpg" alt="" width="100%; height:auto;" srcset="https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.46.29-small-crop.jpg 1000w, https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.46.29-small-crop-300x69.jpg 300w, https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.46.29-small-crop-768x177.jpg 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></p>
<h2 style="text-align: center;">The Harrowing Jeopardy<br />
of <span style="color: #999999;">the</span><br />
Headphone Jack</h2>
<p style="font-family: Serif; margin-left: 20%; margin-right: 20%;"><em>&#8220;This might be a PulseAudio bug&#8221;, thought I. Alas, after attempting everything I could with PulseAudio, the issue remained—from the headphones came nothing but deafening silence. I pondered the untimely physical death of Headphone Jack (&#8220;A hardware issue? Inconceivable!&#8221;), so I hammered the vendor BIOS back into the corpse to be sure… and lo and behold, Headphone Jack was alive! Thus I started the investigation into the causes of its disappearance amidst coreboot.</em></p>
<p>After a few days of looking at various possible causes and finding nothing, I realized that most patches in the coreboot git log mentioning &#8220;headphones&#8221; were modifying <em>hda_verb.c</em> or <em>hda_verb.h</em> (HDA means &#8220;Intel High Definition Audio&#8221;) and I realized the file contains the structure that is used to initialize the &#8220;codec&#8221; that runs on the sound card.</p>
<p>I recalled the codec#0 file that I had grabbed from the machine with original BIOS according to the <a href="https://www.coreboot.org/Motherboard_Porting_Guide">motherboard porting guide</a> and I compared it with the one from coreboot, and I found very few (and insignificant) differences, so it didn&#8217;t make any sense. Eventually, I decided to compare the content of <em>hda_verb.c</em> with the data from the codec#0 file even though it didn&#8217;t change from AMI bios to coreboot, and I noticed something strange right away.</p>
<p>codec#0:<br />
<code>Codec: Intel Broadwell HDMI<br />
Address: 0<br />
AFG Function Id: 0x1 (unsol 0)<br />
Vendor Id: 0x80862808<br />
Subsystem Id: 0x80860101</code></p>
<p>hda_verb.c:<br />
<code>0x19910269, /* Codec Vendor / Device ID: Realtek ALC269 */<br />
0x19910269, /* Subsystem ID */</code></p>
<p>Well, well! That&#8217;s not the same thing at all: the codec ID is different, the subsystem ID is different, the device ID/codec name is not even the same. Then I noticed the &#8216;0x8086&#8217; in the codec id and it was the same vendor id as the Intel PCI vendor id, so on a hunch and out of curiosity, I decided to run &#8220;lspci&#8221; and search for the Audio PCI device to see if the PCI vendor/product id matches the codec id from the codec#0 file</p>
<p><code>lspci -nn | grep -i audio<br />
00:03.0 Audio device [0403]: Intel Broadwell-U Audio Controller [8086:160c] (rev 09)<br />
00:1b.0 Audio device [0403]: Intel Wildcat Point-LP High Definition Audio Controller [8086:9ca0] (rev 03)</code></p>
<p>Hey, I have two audio controllers for some reason! I looked at the script I ran to get the code#0 and it grabbed the file from /proc/asound/card0/codec#0, but when I looked at my /proc/asound directory, I had both a &#8220;card0&#8221; directory and a &#8220;card1&#8221; directory. I peeked into the card1/codec#0 file and found this :</p>
<p><code>Codec: Realtek ALC269VB<br />
Address: 0<br />
AFG Function Id: 0x1 (unsol 1)<br />
Vendor Id: 0x10ec0269<br />
Subsystem Id: 0x19910269<br />
...<br />
Control: name="Headphone Playback Switch", index=0, device=0</code></p>
<p>Ah-ha! Now, to figure out why it didn&#8217;t work. I copied that card1/codec#0 file, inserted the headphones and copied it again, compared the two and found differences (it detects when the headphones are inserted), flashed coreboot, copied the files again, with and without the headphones , then I compared the codec files from the coreboot system to the codec files from the AMI bios… and there were no differences between the files!</p>
<p>Some hours of head scratching ensued. Then, as I was looking at the codec#0 file, I noticed that it did not match what I had seen before, so copied the files yet again and compared the codec files from coreboot and AMI… and suddenly, they were completely different. I shrugged and continued my investigation. I later realized that the codec does not get reinitialized during a reboot, so that&#8217;s why the codec had not changed after I flashed coreboot and rebooted—I had to do a full shutdown and power on again in order to have the codec re-initialized by coreboot!</p>
<p>So, after comparing the codecs from the AMI and coreboot bioses and comparing with the contents of hda_verb.c, I saw differences that I couldn&#8217;t explain, and after I while I wanted to debug what was happening in coreboot and realized that there are already some debug messages being printed by the code that initializes the codec using the hda_verb.c data. I ran the &#8216;cbmem&#8217; utility, printed the coreboot debug messages, and found this:</p>
<p><code>HDA: Initializing codec #0<br />
HDA: codec viddid: 10ec0269<br />
HDA: No verb table entry found</code></p>
<p>That&#8217;s when I realized the error. The codec viddid (vendor id/device id) is 0x10ec0269, yet hda_verb.c had it set to 0x19910269 (which is actually the subsystem ID), so coreboot was simply never finding the data from hda_verb and never initializing the codec. So I fixed the codec ID in hda_verb.c and recompiled coreboot. I fully shut down the laptop and powered it back on, then the headphones jack was working. Hooray!</p>
<h1>The boot splash—Beauty is Pain</h1>
<p>My next step was to add a nice bootsplash image to the boot process. It wasn&#8217;t strictly necessary at this point, but I wanted to do that, so I did. The problem is that it wasn&#8217;t working (surprise, surprise).</p>
<p>First, you have to add the bootsplash image in menuconfig, which adds it to the coreboot.rom… but doesn&#8217;t use it. So then you need to tell coreboot to actually show the bootsplash image, which didn&#8217;t work.</p>
<ul>
<li>I figured it&#8217;s because the VGA graphics aren&#8217;t initialized since it&#8217;s SeaBIOS that runs the VGA option ROM (vbios), so I enabled coreboot to run the VGA option ROM, then I enabled it to run all PCI option ROMs.</li>
<li>I then realized I probably had to use an image with the exact resolution of the VESA mode being used… and it still didn&#8217;t work.</li>
<li>At that point I thought, &#8220;Maybe it was happening too fast for me to see&#8221;, so I enabled the option to keep the graphics in VESA mode.</li>
</ul>
<p>I asked on IRC and those present told me that it was supposed to be &#8220;as simple as adding the image to coreboot and that&#8217;s it&#8221;. Eventually, while debugging, I saw an error message in cbmem from the SeaBIOS payload itself:</p>
<p><code>jpeg_decode failed with return code 9...</code></p>
<p>But I didn&#8217;t care about SeaBIOS because I wanted <em>coreboot</em> to show the image.</p>
<p>Eventually, I had another &#8220;What if…&#8221; moment and asked someone on IRC who had a working bootsplash to send me the image they used. I tried it and it worked! So the problem was my own image. After I made sure the resolutions matched, I had no idea what to look for next, and online, I couldn&#8217;t find any information on what requirements the image had to have.</p>
<p>I also realized that coreboot could show the bootsplash, but SeaBIOS would also find the bootsplash image in CBFS (in the bios filesystem basically) and would also show it, so I had <em>both</em> coreboot and SeaBIOS attempting to show the bootsplash, and if SeaBIOS was showing an error in decrypting the JPEG, it was probably the same reason why coreboot was refusing to display it. I then looked at the jpeg module in the SeaBIOS code and found the -9 error that it returned… it had something to do with the colorspace being wrong, as jpeg_decode only supports YCBR:22:11:11</p>
<p><code>#define ERR_NOT_YCBCR_221111 9</code></p>
<p>I looked at how to determine the colorspace of the JPEG image and how to change to YCBCR:22:11:11 but couldn&#8217;t find much information, so I started reading the code of jpeg_decode and understanding the binary structure of the JPEG file format (did anyone say <a href="http://www.urbandictionary.com/define.php?term=yak%20shaving" target="_blank">yak shaving</a>?), until I found which bits in the JPEG header were specifying the colorspace. I then opened GIMP and tried various things until I found where to change the colorspace, then wrangled with the options until I found which one was setting the bits to perfectly match the YCBCR:22:11:11 colorspace that SeaBIOS required. At that point, I was just using &#8220;hexdump&#8221; and reading the jpeg data structure to determine if it would work. In GIMP, we need to set the &#8220;Subsampling&#8221; advanced option to &#8220;4:2:0 (chroma quartered)&#8221;.</p>
<p>Once I did that, I booted and… <em>still. No. Bootsplash. </em> ლ(ಠ益ಠლ)</p>
<p>I looked at the cbmem log again and this time it was error 11, instead of 9:</p>
<p><code>#define ERR_NOT_SEQUENTIAL_DCT 11</code></p>
<p>Now, that didn&#8217;t mean much; I kept looking for this sequential DCT information, but couldn&#8217;t find any information about it. There were 3 bytes in the SOS (Start of Scan) marker of the JPEG headers, which were the ones that the jpeg_decode function was using to decide if it returned that error or not, and everywhere I looked, it was either not explaining what those bytes meant or defining them as &#8220;ignorableBytes&#8221; or explaining them as &#8220;unused&#8221; or &#8220;skip 3 bytes&#8221; or something like that, without explaining what they were or what they were for… eventually, I tried to bruteforce it, and I found that disabling the &#8220;progressive&#8221; option in GIMP will set those 3 bytes to the value that SeaBIOS&#8217; jpeg_decode requires (which is 0x003F00, by the way). This gives us these JPEG export options in GIMP:</p>
<p><img class="alignnone wp-image-15234 size-full" src="https://puri.sm/wp-content/uploads/2017/02/coreboot-splash-gimp-export-options-annotated.png" width="707" height="644" srcset="https://puri.sm/wp-content/uploads/2017/02/coreboot-splash-gimp-export-options-annotated.png 707w, https://puri.sm/wp-content/uploads/2017/02/coreboot-splash-gimp-export-options-annotated-300x273.png 300w" sizes="(max-width: 707px) 100vw, 707px" /></p>
<p>And voilà! With those settings, the splash image gets shown. Easy peasy, huh?</p>
<figure id="attachment_15190" style="width: 960px" class="wp-caption alignnone"><a href="https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.18.50.jpg"><img class="size-large wp-image-15190" src="https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.18.50-1024x721.jpg" alt="" width="960" height="676" srcset="https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.18.50-1024x721.jpg 1024w, https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.18.50-300x211.jpg 300w, https://puri.sm/wp-content/uploads/2017/02/2017-02-14-15.18.50-768x541.jpg 768w" sizes="(max-width: 960px) 100vw, 960px" /></a><figcaption class="wp-caption-text">The Librem 13 v1 successfully showing the splash with coreboot (temporary artwork)</figcaption></figure>
<p>Afterwards, we asked François to create some more minimalistic bootsplash. This is roughly what it looks like now (keep in mind the picture is a bit overexposed here as well, so it looks better with the naked eye):</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/02/2017-02-24-17.26.40.jpg"><img class="alignnone size-large wp-image-15235" src="https://puri.sm/wp-content/uploads/2017/02/2017-02-24-17.26.40-1024x768.jpg" alt="" width="960" height="720" srcset="https://puri.sm/wp-content/uploads/2017/02/2017-02-24-17.26.40-1024x768.jpg 1024w, https://puri.sm/wp-content/uploads/2017/02/2017-02-24-17.26.40-300x225.jpg 300w, https://puri.sm/wp-content/uploads/2017/02/2017-02-24-17.26.40-768x576.jpg 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<h1>Upstreaming the work</h1>
<p>I went through all of our test matrix and verified that everything works as expected. I ran prime95 for 28.5 hours without issues and verified that the CPU/GPU temperatures remain acceptable under both heavy CPU load (prime95) as well as heavy GPU load (uncapped glxgears):</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-40-10-crop.jpeg"><img class="alignnone size-thumbnail wp-image-15243" src="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-40-10-crop-150x150.jpeg" alt="" width="150" height="150" srcset="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-40-10-crop-150x150.jpeg 150w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-40-10-crop-180x180.jpeg 180w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-40-10-crop-300x300.jpeg 300w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-40-10-crop-600x600.jpeg 600w" sizes="(max-width: 150px) 100vw, 150px" /></a> <a href="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-46-07-crop.jpeg"><img class="alignnone size-thumbnail wp-image-15244" src="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-46-07-crop-150x150.jpeg" alt="" width="150" height="150" srcset="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-46-07-crop-150x150.jpeg 150w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-46-07-crop-180x180.jpeg 180w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-46-07-crop-300x300.jpeg 300w" sizes="(max-width: 150px) 100vw, 150px" /></a> <a href="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-57-15-crop.jpeg"><img class="alignnone size-thumbnail wp-image-15245" src="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-57-15-crop-150x150.jpeg" alt="" width="150" height="150" srcset="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-57-15-crop-150x150.jpeg 150w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-57-15-crop-180x180.jpeg 180w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-57-15-crop-300x300.jpeg 300w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-13-57-15-crop-600x600.jpeg 600w" sizes="(max-width: 150px) 100vw, 150px" /></a> <a href="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-04-29-crop.jpeg"><img class="alignnone size-thumbnail wp-image-15246" src="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-04-29-crop-150x150.jpeg" alt="" width="150" height="150" srcset="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-04-29-crop-150x150.jpeg 150w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-04-29-crop-180x180.jpeg 180w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-04-29-crop-300x300.jpeg 300w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-04-29-crop-600x600.jpeg 600w" sizes="(max-width: 150px) 100vw, 150px" /></a> <a href="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-53-34-crop.jpeg"><img class="alignnone size-thumbnail wp-image-15247" src="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-53-34-crop-150x150.jpeg" alt="" width="150" height="150" srcset="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-53-34-crop-150x150.jpeg 150w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-53-34-crop-180x180.jpeg 180w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-53-34-crop-300x300.jpeg 300w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-15-14-53-34-crop-600x600.jpeg 600w" sizes="(max-width: 150px) 100vw, 150px" /></a> <a href="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-21-17-53-05-crop.jpeg"><img class="alignnone size-thumbnail wp-image-15248" src="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-21-17-53-05-crop-150x150.jpeg" alt="" width="150" height="150" srcset="https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-21-17-53-05-crop-150x150.jpeg 150w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-21-17-53-05-crop-180x180.jpeg 180w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-21-17-53-05-crop-300x300.jpeg 300w, https://puri.sm/wp-content/uploads/2017/02/Screenshot-from-2017-02-21-17-53-05-crop-600x600.jpeg 600w" sizes="(max-width: 150px) 100vw, 150px" /></a></p>
<p>…and eventually came to the conclusion that our coreboot release is done, stable and working.</p>
<p>I reviewed, cleaned and committed my changes, and <a href="https://review.coreboot.org/#/q/status:merged+project:coreboot+branch:master+topic:purism/librem13">sent the commits upstream</a> (to coreboot) for review. Unlike in academia, the reviews were quick and painless: no changes were asked and it was all merged into the coreboot master branch on February 22nd.</p>
<p>While finishing the coreboot port, I also started to play around with the me_cleaner and testing the Librem with the Intel Management Engine disabled and various CPU configurations. We have some good news to report on this. Stay tuned.</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/librem-13-coreboot-report-february-25th-2017/">The Librem 13 v1 coreboot port is now complete</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Librem 13 coreboot report &#8211; February 3rd, 2017: It&#8217;s Alive!</title>
		<link>https://puri.sm/posts/librem-13-coreboot-report-february-3rd-2017/</link>
		<pubDate>Fri, 03 Feb 2017 21:17:45 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=14224</guid>
		<description><![CDATA[<p>Hi again everyone and welcome to the &#8220;Good news&#8221; post! It&#8217;s been 3 weeks since I wrote my last blog post but this is going to be a short update, in big part because I&#8217;ve spent the first two weeks sick in bed and thus wasn&#8217;t able to do much at all. However, in the [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/librem-13-coreboot-report-february-3rd-2017/">Librem 13 coreboot report &#8211; February 3rd, 2017: It&#8217;s Alive!</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<figure id="attachment_14339" style="width: 605px" class="wp-caption alignright"><a href="https://puri.sm/wp-content/uploads/2017/01/2017-01-24-11.41.34-librem-13-memtest-with-coreboot.jpg"><img class="wp-image-14339" src="https://puri.sm/wp-content/uploads/2017/01/2017-01-24-11.41.34-librem-13-memtest-with-coreboot-1024x768.jpg" alt="2017-01-24--11.41.34 librem 13 memtest with coreboot" width="605" height="454" srcset="https://puri.sm/wp-content/uploads/2017/01/2017-01-24-11.41.34-librem-13-memtest-with-coreboot-1024x768.jpg 1024w, https://puri.sm/wp-content/uploads/2017/01/2017-01-24-11.41.34-librem-13-memtest-with-coreboot-300x225.jpg 300w, https://puri.sm/wp-content/uploads/2017/01/2017-01-24-11.41.34-librem-13-memtest-with-coreboot-768x576.jpg 768w, https://puri.sm/wp-content/uploads/2017/01/2017-01-24-11.41.34-librem-13-memtest-with-coreboot.jpg 1500w" sizes="(max-width: 605px) 100vw, 605px" /></a><figcaption class="wp-caption-text">Memtest with coreboot on the Librem 13</figcaption></figure>
<p>Hi again everyone and welcome to the &#8220;Good news&#8221; post!</p>
<p>It&#8217;s been 3 weeks since I wrote my <a href="https://puri.sm/posts/librem-13-coreboot-report-january-12-2017/">last blog post</a> but this is going to be a short update, in big part because I&#8217;ve spent the first two weeks sick in bed and thus wasn&#8217;t able to do much at all. However, in the last week I <em>did</em> manage to make some big progress, and the result represents such a great milestone that it warrants a blog post of its own. And, well, I doubt many will complain about not having to read through a wall of text for today&#8217;s blog post 🙂</p>
<p>So the good news is: <strong>coreboot is working on the Librem 13.</strong> The laptop boots into Linux and most things are working! The only issue I have found so far is that the M.2 SATA port doesn&#8217;t seem to work properly yet (see below for more info).<span id="more-14224"></span></p>
<h1>Getting video output</h1>
<p>&nbsp;</p>
<p>You may remember that, at the end of my <a href="https://puri.sm/posts/librem-13-coreboot-report-january-12-2017/">2nd blog post</a>, I had finally managed to build coreboot with all of the binary blobs included and it <em>should</em> have worked but it didn&#8217;t for &#8220;some reason&#8221;, so I was going to try to enable debugging to see where it froze.</p>
<p>After installing the &#8220;<a href="https://www.coreboot.org/BeagleBone_Black_-_screwdriver">Screwdriver</a>&#8221; image on the BeagleBone Black and enabling the <a href="https://www.coreboot.org/EHCI_Debug_Port">EHCI debugging </a>in the coreboot config, I was able to get the debug output from coreboot. It was really quite easy to achieve. The screwdriver image for BBB is pretty much a &#8220;boot it and it will Just Work™&#8221; thing, no configuration or app installs to do on it. As for enabling EHCI debugging, it took me a couple of tries because I had to enable two options in different config menus, not just one (enable EHCI log debugging, then enable the option to send the log via USB), but thankfully the wiki page explained that so once I followed the docs, it was quite simple. And for the curious/future reference, the USB port which outputs the EHCI debugging is the one on the <em>right</em> side of the laptop.</p>
<p>Once I had the boot log from coreboot, I noticed that it hadn&#8217;t frozen anywhere, the last line was about coreboot launching the payload SeaBIOS, so coreboot did everything up until the end. I checked the various steps and it had initialized the RAM, the refcode, the VBIOS, etc. I figured, &#8220;Maybe it&#8217;s a configuration issue&#8221;, so I checked my lspci output from before, and saw that the VGA Controller PCI ID was &#8220;8086,1616&#8221;, then I went into the coreboot config and saw that it was set to &#8220;8086,0406&#8221;. So I changed that, and flashed coreboot and when I booted the machine, the video controller worked and I saw the SeaBIOS prompt. Hurray!</p>
<h1>The Curious Case of the M.2 SSD</h1>
<p>Unfortunately, once I tried booting Linux, it failed with a &#8220;Read Error&#8221;:</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/02/2017-02-02-16.49.12.jpg"><img class="alignnone wp-image-14439 size-medium" src="https://puri.sm/wp-content/uploads/2017/02/2017-02-02-16.49.12-300x111.jpg" width="300" height="111" srcset="https://puri.sm/wp-content/uploads/2017/02/2017-02-02-16.49.12-300x111.jpg 300w, https://puri.sm/wp-content/uploads/2017/02/2017-02-02-16.49.12-768x285.jpg 768w, https://puri.sm/wp-content/uploads/2017/02/2017-02-02-16.49.12.jpg 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>After spending some time trying to figure it out and not being able to (there is no &#8220;Read Error&#8221; string or anything that could print such a string in the SeaBIOS code, so I couldn&#8217;t track down where the error came from, and there is no EHCI debug since coreboot is already done booting and the issue is from SeaBIOS), I tried booting PureOS from the USB installation drive instead, and I was able to boot into the live environment without any problems. Wow, first success! PureOS is booting with coreboot! There was much rejoicing.</p>
<p>To begin investigating the SSD issue, I used the same set of commands from the <a href="https://www.coreboot.org/Motherboard_Porting_Guide">Motherboard porting guide</a> and started comparing the results, and there were a few differences, but I&#8217;m still not sure what they mean. Here&#8217;s an example of some of the differences between the two lspci outputs (the problematic SATA controller) :</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/02/L13-M2-SATA-coreboot-lspci-diff-meld.png"><img class="alignnone size-large wp-image-14440" src="https://puri.sm/wp-content/uploads/2017/02/L13-M2-SATA-coreboot-lspci-diff-meld-1024x454.png" alt="L13 M2 SATA coreboot lspci diff meld" width="960" height="426" srcset="https://puri.sm/wp-content/uploads/2017/02/L13-M2-SATA-coreboot-lspci-diff-meld-1024x454.png 1024w, https://puri.sm/wp-content/uploads/2017/02/L13-M2-SATA-coreboot-lspci-diff-meld-300x133.png 300w, https://puri.sm/wp-content/uploads/2017/02/L13-M2-SATA-coreboot-lspci-diff-meld-768x341.png 768w, https://puri.sm/wp-content/uploads/2017/02/L13-M2-SATA-coreboot-lspci-diff-meld.png 1598w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p>For reference, you can see the full lspci output <a href="https://paste.fedoraproject.org/545065/raw/" class="broken_link">with</a> and <a href="https://paste.fedoraproject.org/545067/raw/" class="broken_link">without</a> coreboot.</p>
<p>Even after booting into Linux, the internal SSD was not accessible, and &#8216;dmesg&#8217; was showing errors initializing the SATA controller.</p>
<p>SeaBIOS was sometimes seeing the M.2 SSD (but was never able to boot from it):</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-16.25.19.jpg"><img class="alignnone size-medium wp-image-14350" src="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-16.25.19-300x106.jpg" alt="2017-01-31--16.25.19" width="300" height="106" srcset="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-16.25.19-300x106.jpg 300w, https://puri.sm/wp-content/uploads/2017/01/2017-01-31-16.25.19-768x271.jpg 768w, https://puri.sm/wp-content/uploads/2017/01/2017-01-31-16.25.19.jpg 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>Sometimes, it wouldn&#8217;t see the M.2 SSD at all:</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-17.24.38.jpg"><img class="alignnone size-medium wp-image-14349" src="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-17.24.38-300x104.jpg" alt="2017-01-31--17.24.38" width="300" height="104" srcset="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-17.24.38-300x104.jpg 300w, https://puri.sm/wp-content/uploads/2017/01/2017-01-31-17.24.38-768x265.jpg 768w, https://puri.sm/wp-content/uploads/2017/01/2017-01-31-17.24.38.jpg 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>&#8230;and sometimes, it would just show garbage:</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-18.11.29.jpg"><img class="alignnone size-medium wp-image-14352" src="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-18.11.29-300x144.jpg" alt="2017-01-31--18.11.29" width="300" height="144" srcset="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-18.11.29-300x144.jpg 300w, https://puri.sm/wp-content/uploads/2017/01/2017-01-31-18.11.29-768x369.jpg 768w, https://puri.sm/wp-content/uploads/2017/01/2017-01-31-18.11.29.jpg 1000w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>However, it had no issues detecting and booting from the USB stick, so I had an idea; I installed a 2.5&#8243; HDD into my Librem 13 and tried that. It was immediatly detected by the PureOS liveUSB. So I installed PureOS on the HDD, and rebooted. While SeaBIOS still didn&#8217;t detect the SSD, it detected the 2.5&#8243; HDD and was able to boot flawlessly with it. Still no SSD detection even with PureOS fully booted from the HDD however, and dmesg still complained about various SATA initialization issues.</p>
<p>I took the opportunity to test the wifi, video card, speakers, and everything seemed to work. I then booted into MemTest86+ and tested the RAM overnight. There were no errors after more than 17 hours of RAM testing.</p>
<p>As I booted Linux again I noticed the ME PCI device wasn&#8217;t in the lspci output, so I wondered if I somehow messed up the ME partition, therefore I left the computer running for a couple of hours to make sure it wouldn&#8217;t shut down (due to ME watchdog), then I noticed something weird: <strong>I suddenly had a /dev/sdb* set of devices.</strong> The output of &#8216;dmesg&#8217; showed that it magically was able to detect it somehow and I was now able to access the M.2 SSD.</p>
<p><img class="size-full wp-image-14337 alignnone" src="https://puri.sm/wp-content/uploads/2017/01/what-sorcery-is-this.jpg" alt="what-sorcery-is-this" width="559" height="227" srcset="https://puri.sm/wp-content/uploads/2017/01/what-sorcery-is-this.jpg 559w, https://puri.sm/wp-content/uploads/2017/01/what-sorcery-is-this-300x122.jpg 300w" sizes="(max-width: 559px) 100vw, 559px" /></p>
<p>So I did a few more tests, and it seems that after a few minutes (30 minutes to an hour), the M.2 SSD connector will suddenly start responding and Linux will be able to initialize it and detect/access the SSD. It also seems that suspending/resuming the laptop helps trigger the M.2 initialization much faster. I still have no idea why this happens. And once, it managed to initialize the SSD after only 3 seconds instead of the usual 30 minutes, as you can see in this &#8216;dmesg&#8217; output here :</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-dmesg-errors.png"><img class="alignnone size-medium wp-image-14348" src="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-dmesg-errors-300x167.png" alt="2017-01-31 dmesg errors" width="300" height="167" srcset="https://puri.sm/wp-content/uploads/2017/01/2017-01-31-dmesg-errors-300x167.png 300w, https://puri.sm/wp-content/uploads/2017/01/2017-01-31-dmesg-errors-768x428.png 768w, https://puri.sm/wp-content/uploads/2017/01/2017-01-31-dmesg-errors-1024x570.png 1024w, https://puri.sm/wp-content/uploads/2017/01/2017-01-31-dmesg-errors.png 1338w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<p>I have now started reading up on the PCI Configuration space in order to understand the differences in the lspci output and hopefully fix the M.2 issues. My current theory is that since the PCI subsystem ID is different when using the vendor BIOS than from using the coreboot BIOS, it&#8217;s possible that the subsystem ID somehow tells SeaBIOS/Linux that this specific SATA controller has a quirk that changes the initialization timings. This is only a wild guess for the time being, hopefully in the next few weeks I&#8217;ll understand enough about the way PCI initialization works to be able to figure out what goes wrong.</p>
<h1>Summarizing</h1>
<p>My current status is that PureOS boots and is perfectly usable, however the M.2 controller doesn&#8217;t work reliably. Also, the MEI PCI device as well as the USB EHCI device have disappeared from the &#8216;lspci&#8217; output (both USB ports are working though). The lspci output is also different for most of the other devices when compared to the original BIOS.</p>
<p>One other thing worth mentioning is that I have stopped using the IC clip already. Since I am able to boot into Linux with coreboot, I can now use flashrom to flash the BIOS directly from Linux and I&#8217;ve used it to do my BIOS updates while testing in the last few days. This is great, because not only does it speed up development, but it also confirms/tests the process that existing Librem 13 owners will go through to update their laptops to coreboot.</p>
<p>Here is the Acceptance Test Matrix that I mentioned in my previous article, which I&#8217;ve found in an old <a href="https://blogs.coreboot.org/blog/2015/09/02/2015-08-28-librem-13-weekly-bios-update/">post</a> on the coreboot blog, where I&#8217;ve stricken whatever I have had time to test and confirm as working, and made bold anything known not to work :</p>
<ol>
<li><span style="color: #339966;"><del>Cold boot: memory controller works.</del></span></li>
<li><span style="color: #339966;"><del>Cold boot: all installed DRAM is online.</del></span></li>
<li><span style="color: #339966;"><del>Cold boot: graphics controller works.</del></span></li>
<li><span style="color: #ff6600;"><strong>Cold boot: SATA controller succeeds.</strong></span></li>
<li>Cold boot: EC controller responds ok to init code.</li>
<li><span style="color: #339966;"><del>Cold boot: LCD backlight turns on.</del></span></li>
<li><span style="color: #339966;"><del>Cold boot: linux boots ok in text mode.</del></span></li>
<li><span style="color: #339966;"><del>Cold boot: linux boots ok in framebuffer (boot splash) mode.</del></span></li>
<li><span style="color: #339966;"><del>Cold boot: X initializes the LCD at full native resolution.</del></span></li>
<li><del><span style="color: #339966;">Cold boot: X enables hardware acceleration.</span></del></li>
<li>Boot time: Cold boot to grub succeeds in less than a set timeout.</li>
<li>Boot time: Reboot from linux back to linux succeeds in less than a set timeout.</li>
<li>Boot time: Power down succeeds in less than a set timeout.</li>
<li><span style="color: #339966;"><del>SeaBIOS test: keyboard works.</del></span></li>
<li><span style="color: #339966;"><del>Grub test: keyboard works.</del></span></li>
<li><span style="color: #339966;"><del>Grub test: text mode and framebuffer graphics work.</del></span></li>
<li><span style="color: #339966;"><del>Cold boot to USB linux succeeds. (We plan to use SeaBIOS for boot device selection, barring major bugs.)</del></span></li>
<li><span style="color: #339966;"><del>Reboot to USB linux succeeds.</del></span></li>
<li><span style="color: #339966;"><del>EC test: fan spins.</del></span></li>
<li><span style="color: #339966;"><del>EC test: holding power for &gt;5 seconds forces a power down.</del></span></li>
<li><span style="color: #339966;"><del>ACPI test: lid switch works.</del></span></li>
<li><del><span style="color: #339966;">ACPI test: power button event received ok.</span></del></li>
<li><del><span style="color: #339966;">ACPI test: AC power on/off event received ok.</span></del></li>
<li><del><span style="color: #339966;">ACPI+EC+battery test: battery percentage works.</span></del></li>
<li>Media keys on keyboard work in linux.</li>
<li>Device tests: internal mic, <span style="color: #339966;"><del>internal speakers,</del></span> webcam, webcam mic, <span style="color: #339966;"><del>wifi</del>,</span> bluetooth, <span style="color: #339966;"><del>hard drive</del>,</span> <strong>SSD</strong>, SD card, <span style="color: #339966;"><del>each USB port</del>,</span> headphone jack.</li>
<li>prime95 (one instance bound to each hyperthread) for a fixed time to test CPU thermal management.</li>
<li>glxgears for a fixed time to test GPU thermal management.</li>
<li>During prime95 test, CPU digital thermal sensor should give reasonable results.</li>
<li><span style="color: #339966;"><del>Linux suspend ok.</del></span></li>
<li><del><span style="color: #339966;">LCD backlight adjustable in linux.</span></del></li>
<li><span style="color: #339966;"><del>Linux kernel boot messages should not contain too many errors.</del></span> <strong>(Only the SATA errors are appearing)</strong></li>
</ol>
<p>As you can see we have at least 22 out of 32 items that are considered tested and done, which means we&#8217;re at least two-thirds there—most of the other items are probably working as well, I just hadn&#8217;t had time to test them yet.</p>
<p>I hope to have the M.2 issues fixed within the next couple of weeks, then, after making sure it is perfectly safe to flash coreboot to any Librem 13, we&#8217;ll probably release a beta image for people to test (it will come with plenty of disclaimers though!) After that, I&#8217;ll work on disabling the Intel ME (first by using the <a href="https://github.com/corna/me_cleaner">me_cleaner</a> tool, then testing if it works as expected).</p>
<p>We&#8217;ll keep you posted on the progress.</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/librem-13-coreboot-report-february-3rd-2017/">Librem 13 coreboot report &#8211; February 3rd, 2017: It&#8217;s Alive!</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
		<item>
		<title>Librem 13 coreboot report &#8211; January 12, 2017</title>
		<link>https://puri.sm/posts/librem-13-coreboot-report-january-12-2017/</link>
		<pubDate>Thu, 12 Jan 2017 17:45:13 +0000</pubDate>
		<dc:creator><![CDATA[Youness Alaoui]]></dc:creator>
				<category><![CDATA[Firmware and BIOS]]></category>
		<category><![CDATA[Advanced readers]]></category>
		<category><![CDATA[Boot and BIOS]]></category>
		<category><![CDATA[Laptops]]></category>
		<category><![CDATA[Newsletter and status updates]]></category>

		<guid isPermaLink="false">https://puri.sm/?p=12966</guid>
		<description><![CDATA[<p>Hello again Purists! I&#8217;ve made some progress on the coreboot port to the Librem 13 v1 hardware. You probably remember that my initial post about coreboot development was mostly about the v2 hardware and all the mistakes I made while getting familiar with BIOS development. One comment I&#8217;ve heard on the previous post is that [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/librem-13-coreboot-report-january-12-2017/">Librem 13 coreboot report &#8211; January 12, 2017</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Hello again Purists! I&#8217;ve made some progress on the coreboot port to the Librem 13 v1 hardware.<span id="more-12966"></span></p>
<p><img class="alignright size-medium wp-image-13016" src="https://puri.sm/wp-content/uploads/2017/01/logic-analyzer_and_probes-300x169.jpg" alt="logic-analyzer_and_probes" width="300" height="169" srcset="https://puri.sm/wp-content/uploads/2017/01/logic-analyzer_and_probes-300x169.jpg 300w, https://puri.sm/wp-content/uploads/2017/01/logic-analyzer_and_probes-768x432.jpg 768w, https://puri.sm/wp-content/uploads/2017/01/logic-analyzer_and_probes.jpg 1000w" sizes="(max-width: 300px) 100vw, 300px" />You probably remember that <a href="https://puri.sm/posts/diving-back-into-coreboot-development/" class="broken_link">my initial post</a> about coreboot development was mostly about the v2 hardware and all the mistakes I made while getting familiar with BIOS development. One comment I&#8217;ve heard on the previous post is that it was over-complicated to use a Logic Analyzer in order to do a dump of the flash. <em>Of course</em> it was over-complicated, but I did it for reasons other than just creating a dump. I did it because:</p>
<ul>
<li>I hadn&#8217;t received the sockets/other hardware I ordered.</li>
<li>It sounded like a fun thing to do while I wait. And I simply love using the Saleae Logic Analyzer, and I look for any excuse to use it!</li>
<li>The logic analyzer doesn&#8217;t <em>only</em> give me a dump, it gives me a trace of all accesses, it allows me to see &#8220;which offsets are accessed when&#8221;.</li>
<li>When I see the process of what happens exactly (which bytes are read/executed first, where does it jump, etc.), it helps me better understand the boot process.</li>
<li>It lets me see which areas of the flash are ignored/not accessed. That also allows me to see which areas/partitions of the ME region are not protected by a signature (if the reads are not all sequential).</li>
<li>If I see the ME code being read in its entirety twice, it might mean that there is a <a href="https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use">ToCToU</a> exploit that can be used there (signature is checked during the first read, then the ME code is loaded into memory).</li>
</ul>
<p>So yeah, it might have been overkill, but it was interesting to do, that&#8217;s why I did it.</p>
<h1>Dumping the Librem 13 v1 BIOS from software</h1>
<p>At the end of my previous post, I explained that I had finally found a Librem 13 v1 that I could use. Given how it took us 3 weeks to finally manage to get one, I don&#8217;t want to be making the same mistakes this time around and bricking a very hard-to-replace laptop. Therefore, I decided against soldering a socket on the motherboard this time, or to be more precise, I decided to only solder the socket <em>after/if</em> I brick the laptop (once it becomes necessary). So my first task was to try, by any means necessary, to dump the flash contents using software only. Of course, I still did my logic analyzer trace, just for fun 🙂</p>
<p>I found the flash chip to be an 8MB MX25L6406E chip, and the vendor BIOS was from American Megatrends (AMI). <img class="alignright size-full wp-image-13345" src="https://puri.sm/wp-content/uploads/2017/01/AptioV-screenshot.png" alt="aptiov-screenshot" width="627" height="417" srcset="https://puri.sm/wp-content/uploads/2017/01/AptioV-screenshot.png 627w, https://puri.sm/wp-content/uploads/2017/01/AptioV-screenshot-300x200.png 300w" sizes="(max-width: 627px) 100vw, 627px" />Since I knew that flashrom wouldn&#8217;t work on laptops (more on that later), the first thing I tried was to find the flashing tool from the <a href="https://ami.com/products/bios-uefi-firmware/">AMI utilities</a>. I didn&#8217;t know what kind of BIOS I had, but looking at the screenshot from the <a href="https://ami.com/products/bios-uefi-firmware/aptio-v/">Aptio-V</a> page, it was clear that it wasn&#8217;t Aptio-V, so I had the choice between AMIBIOS or Aptio-4&#8230; so I first tried the one for AMIBIOS, I created a bootable DOS USB stick and copied AFUDOS to it&#8230; but it failed, then I tried the tool for Aptio-4, it failed, but it gave me an error message that said I need to use the tool for Aptio-5, so I finally downloaded the AFUDOS utility for the Aptio-V BIOS and that one worked (facepalm!). So I dumped my BIOS, success! Hmm, it&#8217;s only a 6MB file, weird&#8230;</p>
<p>Now, I figured that &#8220;It&#8217;s nice and all, but I need to be able to do it from a GNU/Linux platform&#8221;, because Librem users will be using PureOS so they&#8217;d need a way to dump/flash their BIOS from there. Thankfully, I found that AMI also has a tool called &#8220;AFULNX&#8221; for GNU/Linux, but for some reason it&#8217;s not available for download. I eventually found a link to it, which I can&#8217;t seem to find again now, but I also found this great <a href="http://hargrave.info/articles/afulnx.html" class="broken_link">article</a> by Roman Hargrave that explained just how &#8220;awesome&#8221; (emphasis: sarcasm) AFULNX is. To make a long story short, the AFULNX tool will extract the source for a kernel module and try to build it, which will always fail because they are missing an include, then it deletes those source files, so I&#8217;d have to be quick enough to suspend the process before it deletes the files, then make a copy and fix the code so it compiles, then I need that kernel module file to be renamed (otherwise on the next execution it deletes it and retries).</p>
<p>Anyway, I managed to run AFULNX and dump my kernel. It&#8217;s another 6MB binary, which is weird because I know from the spec of the chipset, that the flash is supposed to be 8MB. So I compare the BIOS I dumped with the one that was dumped with the Logic Analyzer… Surprise, surprise, they are completely different. After a little investigating, I realize they are not so different, but the BIOS dumped by AFULNX is actually the last 6MB of the flash, while the first 2MB were completely skipped. Comparing the images from the v1 and v2 BIOS images, and also looking at the LA trace, I could see that the first thing being read is the offset 0x10, which contains the magic number 0x5aa5f00f in both images, so I figured that the flash has some sort of &#8220;filesystem&#8221; which itself contains the BIOS file, and that the AFULNX binary only dumps that BIOS file without the filesystem itself. This meant that my dump was useless in the case of a bricked laptop. I needed a full flash image, otherwise I couldn&#8217;t recover.</p>
<p>I then started investigating what this &#8220;filesystem&#8221; is, and I can&#8217;t say that I found a lot of documentation! Thankfully, I know the magic number of 0x5aa5f00f and that helped me find some stuff about it such as a patch on flashrom talking about supporting &#8220;<a href="https://www.flashrom.org/pipermail/flashrom/2013-June/011083.html">ROM layout from IFD</a>&#8220;, then, I found the magic number in the ichdesc.py from the tool called <a href="https://github.com/fesh0r/romdump">romdump</a> which seems to be used to split the raw flash into multiple parts (one of which is the 6MB BIOS file from AFULNX), the file calls it the &#8220;ICH flash descriptor&#8221;… which led me to something called &#8220;<a href="https://libreboot.org/docs/hcl/gm45_remove_me.html#ich9gen">ich9gen</a>&#8221; that is used to generate that structure (so, is it an ICH9 or an IFD format?). Obviously ICH is a reference to the Intel Controller Hub, which I assume is the one parsing that flash structure (but then why does the <a href="https://www.coreboot.org/Developer_Manual#Hardware_Overview">coreboot developer manual</a> say that the CPU just loads the top most 16 bytes from the flash? That&#8217;s clearly not the case since there is an actual structure to the BIOS and the ICH is the one parsing it prior to the BIOS getting executed). Anyway, I eventually figured out that it&#8217;s called (in coreboot speak) a &#8220;descriptor&#8221; which is used to define &#8220;regions&#8221; in the flash, one of those regions is the Intel ME firmware, another one is the GbE (Gigabit Ethernet) configuration data, which is used to configure the Intel integrated GbE device (it contains the MAC address for example), as well as the BIOS region which contains the actual UEFI BIOS.</p>
<p>So… at that point I still haven&#8217;t managed to do a proper full flash dump using a software method, but at least, I have good BIOS dumps from AFULNX and AFUDOS, right? I then decide to use romdump to extract the BIOS from my logic-analyzer dump, and compare the BIOS dump from AFULNX with the one from the Logic Analyzer, to see what kind of corruption I got from the logic analyzer… and when comparing the two, I realize that the BIOS dumped from AFULNX <em>is</em> the one that is corrupted!</p>
<p><img class="alignnone size-full wp-image-12703" src="https://puri.sm/wp-content/uploads/2016/12/facepalm.jpg" alt="facepalm" width="485" height="364" srcset="https://puri.sm/wp-content/uploads/2016/12/facepalm.jpg 485w, https://puri.sm/wp-content/uploads/2016/12/facepalm-300x225.jpg 300w" sizes="(max-width: 485px) 100vw, 485px" /></p>
<p>In the AFULNX BIOS dump, there were some huge chunks that were all &#8220;0xffffffff&#8221; but were filled with data in the logic analyzer BIOS dump. Also, There were some differences in some bytes which, when I looked at the full LA trace, I saw those bytes being read about 20 times with the exact same data being returned each time (confirming the data to be valid) and yet, the one from AFULNX was different…</p>
<p>So I compared the AFULNX dump with the bios dump from AFUDOS, and… <strong>the files were different!</strong> The two BIOS dumps from AFULNX and AFUDOS were not only very different from the logic analyzer dump, they were also highly different from each other, confirming that they were <strong>both</strong> corrupted. That just makes everything <em>worse…</em> Why would a software-based dump of the BIOS result in corrupted data? And that&#8217;s using the official tool!</p>
<p><img class="alignnone size-full wp-image-13267" src="https://puri.sm/wp-content/uploads/2017/01/double-facepalm.jpg" alt="double-facepalm" width="510" height="364" srcset="https://puri.sm/wp-content/uploads/2017/01/double-facepalm.jpg 510w, https://puri.sm/wp-content/uploads/2017/01/double-facepalm-300x214.jpg 300w" sizes="(max-width: 510px) 100vw, 510px" /></p>
<p>If the data is corrupted, how can I trust it? Most importantly how can I write to the BIOS if writing might cause it to be corrupted (i.e.: &#8220;is coreboot failing or is the image that was written to the flash wrong&#8221;)? Since AFULNX is not open-source, I was hoping to eventually reverse engineer AFULNX itself, to figure out what it does and port those &#8220;exceptions&#8221; (if there are any) to flashrom to make it support the Librem 13 hardware. That would allow the users to dump and write their flash with the coreboot BIOS using the free/libre and open source flashrom tool, but if that data can&#8217;t be trusted, it&#8217;s unacceptable. I need to find a way to do a proper and reliable dump of the flash.</p>
<h1>Interlude: building coreboot</h1>
<p>While I was thinking on how to do the dump, I decided to move to something else: building coreboot for the Librem (I had previously built coreboot for qemu, following the instructions on <a href="https://www.coreboot.org/Lesson1">the wiki</a>, but that&#8217;s not very helpful for the Librem 13). So I configured coreboot with &#8216;make menuconfig&#8217;, set the mainboard to the Librem 13, and ran &#8216;make&#8217;. Of course, it failed for some magical reason that I can&#8217;t remember right now, but after wrestling a bit with it I eventually realized that I was missing the BLOBs in the 3rdparty/blobs directory, and without it, I couldn&#8217;t build it. So I tried to disable the blobs from the config, but it still complained. I couldn&#8217;t find information on where to find those blobs that it needed, and I was a bit lost in all of that, to be honest. The only information I found was about the <a href="https://www.coreboot.org/Binary_situation">binary situation</a> of coreboot but not on how and where to find the binary blobs, what filename to give to the files, in which directory to put them, etc. I&#8217;m going to skip ahead now and spare you the details of long nights crying and wondering <em>&#8220;What am I doing wrong?&#8221;</em> and just tell you that the coreboot project has a separate <a href="https://review.coreboot.org/#/admin/projects/blobs">repository for binary blobs</a> which needs to be cloned into the &#8216;3rdparty/&#8217; directory (replacing the empty &#8216;blobs&#8217; directory in it). Also, even if you ask for a fake IFD in the config, removing the need for the descriptor.bin and me.bin binaries, it will <em>still</em> look for the microcode blobs, which is a separate config option (which was causing things to fail for me).</p>
<p>So, the good news is, the CPU microcode blobs are in that blobs repository… but the descriptor.bin and me.bin binaries are not, and those will have to be created/copied manually; they come from my own flash dump and can be extracted using the tool &#8216;utils/ifdtool&#8217; from my full raw BIOS dump. <em>Great,</em> I don&#8217;t have that!</p>
<h1>Back to the dump!</h1>
<p><img class="size-full wp-image-13268 alignright" src="https://puri.sm/wp-content/uploads/2017/01/IC-test-clip.jpg" alt="ic-test-clip" width="600" height="600" srcset="https://puri.sm/wp-content/uploads/2017/01/IC-test-clip.jpg 600w, https://puri.sm/wp-content/uploads/2017/01/IC-test-clip-150x150.jpg 150w, https://puri.sm/wp-content/uploads/2017/01/IC-test-clip-300x300.jpg 300w, https://puri.sm/wp-content/uploads/2017/01/IC-test-clip-180x180.jpg 180w" sizes="(max-width: 600px) 100vw, 600px" /></p>
<p>Time to try some alternative methods. In the previous blog post, I spoke about the possibility of using an <a href="https://www.sparkfun.com/products/13153">IC test clip</a> (actually, about using the Logic Analyzer&#8217;s test clips) and an external power supply to power the flash chip, but I considered that to be a dangerous thing to do (based on some post I read on the flashrom mailing list). It turns out that while I was afraid of doing that, it&#8217;s really not <em>that</em> dangerous and it is actually <em>the</em> preferred method of doing things.</p>
<ul>
<li>I apparently got &#8216;tricked&#8217; into using the socket method simply because I stumbled onto <a href="https://www.coreboot.org/Soldering_a_socket_on_your_board">this page</a> in the coreboot wiki and thought that&#8217;s what I needed to do.</li>
<li>Last week, <a href="https://puri.sm/about/team/">Zlatan</a> was at the <a href="https://en.wikipedia.org/wiki/Chaos_Communication_Congress">CCC</a> and participated in the coreboot install session, where he got someone from coreboot to dump his flash, compile coreboot and flash it on his Librem 13. It didn&#8217;t work, but it was a helpful event because I realized, &#8220;If coreboot developers are using the IC test clip and it&#8217;s safe, then I probably also should&#8221;, so I researched that further and found posts/wiki pages that confirm it to be a good method to use, then I ordered one, received it overnight, and started playing around with doing a dump of the flash using hardware—but without soldering!</li>
</ul>
<p>With the IC test clip on hand, I started looking for docs about that tool and saw a lot of wiki pages explaining how to do it. Most of them said to use an ATX Power supply to supply the 3.3V to the chip, and to always connect the power line last. So my first try was to connect the IC clip (so easy to use! Wonderful.) to my breadboard with the same FTDI <a href="http://www.digikey.ca/product-detail/en/UM232H/768-1103-ND/2614628?WT.mc_id=IQ_7604_G_pla2614628&amp;wt.srch=1&amp;wt.medium=cpc&amp;WT.srch=1&amp;mkwid=s&amp;pcrid=102742927745&amp;pkw=&amp;pmt=&amp;pdv=c" class="broken_link">UM232H</a> as before, then disconnect the battery from the laptop, then connect the power line. The LED on the FTDI suddenly dimmed (it is powering much more than just the flash chip), and my PC was suddenly unable to access the FTDI chip. It still recognizes it but it complains about being unable to reset it. So I brought out a second FTDI chip, and used the first one for all the data/signal lines, and the second one for the power line only (and I did connect the ground from both FTDI chips together), but it was failing, it just couldn&#8217;t recognize the flash. I eventually realized that the problem was that flashrom was trying to read from the wrong FTDI (since I had two connected to my PC), so once I specified the right serial number to use, it was still failing, this time with &#8220;unable to read serial from device&#8221;. I suppose that second FTDI was simply draining my laptop&#8217;s USB power or something, I&#8217;m not sure exactly what the issue was, but I decided to just go grab myself an ATX power supply and use that instead. After I shorted the PS_ON pin on the power supply to get it to turn on, and made sure the orange wires are for the 3.3V power rail, I connected it all and tried again, it still failed! But at least, I was getting a response. I was getting this response from the chip :</p>
<pre>RDID returned 0xe1 0x10 0x0b. RDID byte 0 parity violation. probe_spi_rdid_generic: id1 0xe1, id2 0x100b</pre>
<p>But once I checked the datasheet for the MX25L6406E chip, it said that the RDID response (the manufacturer/device ID) should be 0xc2 0x20 0x17, and I noticed that 0xe1 is 1 bit shifted from 0xc2, so I figured that the FTDI must be too fast for the flash chip (even though FTDI was running at 30MHz, and the flash datasheet says it supports a clock of 86MHz—maybe only for reads?). I decided to try lowering the clock, so I changed the clock to 15MHz and it worked! So yay, finally, I was able to dump the flash. I did five dumps, and they all had the exact same checksum, that meant that there was no corruption in any of the dumps. Now I can get back to work!</p>
<p>For the curious, here is the command I used to dump the flash:</p>
<pre>../flashrom/flashrom -p ft2232_spi:type=232H,serial=FTVDZ6J5,divisor=4 -c "MX25L6406E/MX25L6408E" -V -r v1.rom</pre>
<p>I was then able to use the idftool to split the rom image into the 3 regions it contained (the descriptor, the ME and the BIOS regions). It didn&#8217;t contain a GbE region because the Librem does not use the Intel network card. I put the right files in the right directories and coreboot finally compiled!</p>
<h2>A good scare</h2>
<p>Now, before I test out coreboot, I decided to go grab all the information I can on my hardware, so that if something happens, at least, I would have that. so I went to the <a href="https://www.coreboot.org/Motherboard_Porting_Guide">Motherboard Porting Guide</a> on coreboot.org, read it, installed all the dependencies, then after quickly looking at the commands that I&#8217;m told to copy-paste (just some lspci, lsusb, etc.), I proceeded to paste this block of commands in my terminal in order to gather all the logs that I would need :</p>
<pre> lspci -nnvvvxxxx &gt; lspci.log 2&gt;lspci.err.log
 lsusb -vvv &gt; lsusb.log 2&gt;lsusb.err.log
 superiotool -deV &gt; superiotool.log 2&gt; superiotool.err.log
 inteltool -a &gt; inteltool.log 2&gt; inteltool.err.log
 ectool -i &gt; ectool.log 2&gt;ectool.err.log
 msrtool &gt; msrtool.log 2&gt;msrtool.err.log
 dmidecode &gt; dmidecode.log 2&gt;dmidecode.err.log
 biosdecode &gt; biosdecode.log 2&gt;biosdecode.err.log
 nvramtool -x &gt; nvramtool.log 2&gt;nvramtool.err.log
 dmesg &gt; dmesg.log 2&gt;dmesg.err.log
 flashrom -V -p internal:laptop=force_I_want_a_brick &gt; flashrom_info.log 2&gt;flashrom_info.err.log
 flashrom -V -p internal:laptop=force_I_want_a_brick -r rom.bin &gt; flashrom_read.log 2&gt;flashrom_read.err.log
 acpidump &gt; acpidump.log 2&gt;acpidump.err.log
 for x in /sys/class/sound/card0/hw*; do cat "$x/init_pin_configs" &gt; pin_"$(basename "$x")"; done
 for x in /proc/asound/card0/codec#*; do cat "$x" &gt; "$(basename "$x")"; done
 cat /proc/cpuinfo &gt; cpuinfo.log 2&gt;cpuinfo.err.log
 cat /proc/ioports &gt; ioports.log 2&gt;ioports.err.log
 cat /sys/class/input/input*/id/bustype &gt; input_bustypes.log</pre>
<p>And only <em>after</em> I pasted it, I saw the next line in the wiki (below the block of commands) that says, &#8220;Save all logs in safe place, and also rom.bin file.&#8221;, and noticed that flashrom is used in there too, but since I knew flashrom typically doesn&#8217;t work on <a href="https://www.flashrom.org/Laptops">laptops</a> (as explained in my last blog post) I assumed that command probably just didn&#8217;t work and there would be no rom.bin&#8230; until I saw the option given to flashrom: <em>laptop=force_i_want_a_brick </em>…</p>
<p><img class="alignnone size-full wp-image-13343" src="https://puri.sm/wp-content/uploads/2017/01/Massimo.jpg" alt="massimo" width="800" height="529" srcset="https://puri.sm/wp-content/uploads/2017/01/Massimo.jpg 800w, https://puri.sm/wp-content/uploads/2017/01/Massimo-300x198.jpg 300w, https://puri.sm/wp-content/uploads/2017/01/Massimo-768x508.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /></p>
<p>I was half horrified, half amused—this seemed like a ridiculously dangerous thing to put in a long &#8220;to be copy/pasted&#8221; block of seemingly harmless commands. &#8220;Those options shouldn&#8217;t be part of a script, they should be set consciously by the user after a big warning!&#8221;, I thought. I later discussed this on IRC with the coreboot developers; while most agree that the risk is minimal and it is fairly safe, it was also agreed upon that the option shouldn&#8217;t be there in the wiki because of the risk to the user. So that will change soon (if not by a coreboot dev, then I will edit the wiki to add clear warnings).</p>
<p>Thankfully, the resulting &#8220;rom.bin&#8221; had the full 8MB BIOS dump in my case, and it was all correct (I later compared it with my dump made with the IC clip, and it was almost identical, small differences must be due to the ME constantly writing data to the flash and thus changing some bytes). And so it seems I can indeed dump the flash from software only. Whew!</p>
<p>After some research and discussion on IRC, it turns out that the big problem with flashrom and laptops is the EC (The Embedded Controller), which handles battery charging, the power on/off events,etc..) : if the EC is reading the flash, then you can get some conflicts. Sometimes the EC will appear as a fake flash to the PCH and act as a proxy, but either way, the real problem is just the conflict between EC and PCH trying to access the flash, and <strong>it happens to be safe on the Librem 13 because the EC is using a seperate flash chip instead</strong>. An old <a href="https://puri.sm/posts/2015-08-21-librem-13-weekly-progress-update/">blog post</a> from 2015 on the Purism blog confirms that. So, no more need for AFULNX (or reverse engineering what it does to bypass the EC): we can certainly use flashrom to dump and write the coreboot update to the Librem 13 laptops.</p>
<h2>Finding Nemo and Dory: the MRC and the VBIOS</h2>
<p>I then used my IC clip setup to write the coreboot image into the flash, and turned on the laptop. The laptop stayed on, but the screen remained black. I asked around on the coreboot IRC channel to get some pointers. After posting my config file, I was told that I am missing 2 important items: the mrc.bin binary blob, and the VBIOS (Video/VGA BIOS); without a VBIOS there would be no graphics support, and without mrc.bin there would be no RAM. So I started searching for this &#8220;mrc.bin&#8221;, and found very <a href="https://www.google.ca/webhp?sourceid=chrome-instant&amp;ion=1&amp;espv=2&amp;ie=UTF-8#q=coreboot+mrc.bin">little</a> <a href="https://www.coreboot.org/index.php?search=MRC&amp;title=Special%3ASearch&amp;go=Go">information</a> on what is &#8220;MRC&#8221;, what it is for and where I can get it. Thankfully, the folks on IRC were very nice and helped me figure things out.</p>
<p><strong>The MRC blob</strong> does the <a href="https://www.coreboot.org/Developer_Manual/RAM_init">RAM initialization</a>, and it is necessary for the Broadwell architecture to use MRC.bin because there is no native memory init support in coreboot for Haswell/Broadwell chips, unlike <a href="https://www.coreboot.org/Intel_Native_Raminit">older Intel chips</a>. From my understand, it&#8217;s in some kind of Google-specific format or that Google is the one creating those mrc.bin binary blobs, and apparently, it can&#8217;t be redistributed, but I&#8217;m not sure… So I have 3 options, either use the provided MRC.bin from a chromebook&#8217;s (with similar chipset) coreboot but not be able to redistribute it (users would have to extract it from the chromebook bios image themselves), or I could use the Intel FSP, but support in coreboot is incomplete, so I&#8217;d have to add the support for it somehow, or reverse engineer the memory initialization and re-implement that in coreboot natively. I think reverse engineering it may be the best thing for the future, but for now all I want is to get this running as fast as possible, so I&#8217;ll go with the MRC solution for now.</p>
<ul>
<li>In any case, I couldn&#8217;t just download the mrc.bin file from somewhere, and it was not in coreboot&#8217;s blobs repository either. It&#8217;s apparently the same blob as the one used in the Google Chromebook Samus which uses a similar Broadwell chipset, all I needed to do was to run the &#8216;./utils/chromebook/crosfirmware.sh samus&#8217; command which would download the chromebook recovery image for the Samus device, and extract the BIOS from it. Then I could use cbfstool to extract the mrc.bin binary from it as explained in this <a href="https://patchwork.ozlabs.org/patch/596597/">commit </a>(see additions to the README file). Unfortunately, cbfstool would refuse to extract/print the BIOS because it couldn&#8217;t detect it as being a coreboot BIOS. Thankfully, someone on IRC (coolstar) quickly told me to use &#8216;-r BOOT_STUB&#8217; option which fixes things. Once I did that, I got the mrc.bin file.</li>
<li>Then I was told I would also need the refcode&#8230; &#8220;What is the refcode?&#8221; Well, they didn&#8217;t know, and it doesn&#8217;t seem to be clear either from the coreboot config help page, as it only says it&#8217;s an &#8220;external reference code to be put in cbfs&#8221; (by the way, cbfs is the coreboot filesystem which contains all the coreboot code and blobs, etc..). Eventually, I found some <a href="http://lists.denx.de/pipermail/u-boot/2016-March/248052.html">email</a> on the U-boot mailing list saying that the Broadwell chipsets need an additional reference code to be executed in order to initialize the PCH. So I extracted the refcode binary blob as well and added it to coreboot.</li>
</ul>
<p><strong>The VBIOS</strong>, on the other hand, was the easy part. I followed the instructions from the <a href="https://www.coreboot.org/VGA_support">coreboot wiki</a>, I tried the bios_extract method, but it couldn&#8217;t recognize my BIOS as being an AMI BIOS, so I looked in the bios_extract source code, and figured out how it detects the BIOS vendor (it looks for specific strings in it), and I realized that my BIOS didn&#8217;t fit (it didn&#8217;t have anything close to those strings at all) and it wasn&#8217;t a simple bug to fix it and make it work… so I figured, maybe it&#8217;s considered a &#8220;UEFI&#8221; bios, so I followed the &#8220;UEFI method&#8221; which uses the UEFITool, so I installed it, ran it, gave it my vendor BIOS, and it recognized it as a UEFI bios and showed me a tree of &#8220;lots of stuff&#8221;:</p>
<p><a href="https://puri.sm/wp-content/uploads/2017/01/UEFITool.png"><img class="alignnone size-large wp-image-13382" src="https://puri.sm/wp-content/uploads/2017/01/UEFITool-1024x533.png" alt="UEFITool" width="960" height="500" srcset="https://puri.sm/wp-content/uploads/2017/01/UEFITool-1024x533.png 1024w, https://puri.sm/wp-content/uploads/2017/01/UEFITool-300x156.png 300w, https://puri.sm/wp-content/uploads/2017/01/UEFITool-768x400.png 768w, https://puri.sm/wp-content/uploads/2017/01/UEFITool.png 1600w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p>To find the VBIOS, the wiki says to:</p>
<blockquote><p>* Look for the &#8220;CSMCORE&#8221; DXE Driver ? usually having the hash &#8216;a062cf1f-8473-4aa3-8793-600bc4ffe9a8&#8217;?<br />
* Search for text &#8220;VGA Compatible BIOS&#8221; (<b>uncheck unicode</b>)<br />
* Search for text &#8220;PCIR&#8221; (<b>uncheck unicode</b>)</p></blockquote>
<p>And so, I did, I found the DXE Driver called &#8220;CSM DXE&#8221; with the correct hash. I thought that I would then open that item and search for &#8220;VGA Compatible BIOS&#8221; in it, but nope, when I did the search, it gave me a completely different module, and when I searched for &#8220;PCIR&#8221; it gave me a bunch of different modules which matched… and I had no idea what to chose. I made my choice on the single result from &#8220;VGA Compatible BIOS&#8221; and extracted that one. I tried it and it didn&#8217;t work, so I wasn&#8217;t sure if it was right, but it <em>felt</em> right. Eventually, I put back my original vendor BIOS on the flash, booted the Librem 13 into PureOs, and used the &#8220;extraction from mapped memory&#8221; method to grab the VBIOS directly from GNU/Linux. As I compared it, it was identical to the vbios.bin that I extracted from UEFITool, so I at least knew that I had the right file.</p>
<hr class="ttfmake-hr" style="border-style: dotted; border-top-width: 2px;" />
<h1>Next steps</h1>
<p><img class="alignright wp-image-12704" src="https://puri.sm/wp-content/uploads/2016/12/Navy_Diver-680x1024.jpg" alt="Going deep." width="384" height="578" srcset="https://puri.sm/wp-content/uploads/2016/12/Navy_Diver-680x1024.jpg 680w, https://puri.sm/wp-content/uploads/2016/12/Navy_Diver-199x300.jpg 199w, https://puri.sm/wp-content/uploads/2016/12/Navy_Diver-768x1157.jpg 768w, https://puri.sm/wp-content/uploads/2016/12/Navy_Diver.jpg 996w" sizes="(max-width: 384px) 100vw, 384px" />I now have coreboot with the proper descriptor, ME regions, VBIOS, MRC.bin (and refcode), but I don&#8217;t know yet why it still doesn&#8217;t boot. The next step for me will be to see how I can debug it. There are some ways to debug coreboot but I haven&#8217;t looked at them yet. There&#8217;s an <a href="https://blogs.coreboot.org/blog/2015/08/14/2015-08-14-librem-13-weekly-progress-update/">old blog post</a> about debugging coreboot on the Librem 13, but I&#8217;m not sure I&#8217;m in the mood to be soldering on the LPC lines (and where are they?), but Zlatan in the CCC coreboot session said that the coreboot developer was able to debug that it had stopped at the vga init stage for him (they didn&#8217;t have the VBIOS, I think), so there is obviously going to be a way to do that, and I doubt they soldered on the LPC lines in the middle of a conference. I think it&#8217;s safe to assume that I could use a beaglebone black (which I have already) and use the <a href="https://www.coreboot.org/EHCI_Debug_Port">EHCI debug port</a> to capture debug information. That will be my challenge for next week and once I achieve that, I will be able to debug what happens and hopefully figure out what went wrong and fix coreboot so it can boot the Librem 13!</p>
<p>Now, there are still some questions that I needed to know.</p>
<ul>
<li>For example, assuming I get coreboot to work on my Librem 13, how can I know that it&#8217;s doing it&#8217;s job? I need a checklist of what coreboot is supposed to be doing and a way to check if it does it correctly. Thankfully, I found <a href="https://blogs.coreboot.org/blog/2015/09/02/2015-08-28-librem-13-weekly-bios-update/">this old article</a> that lists a checklist of 32 items for the Librem 13 coreboot port to be considered done.</li>
<li>I also wanted to know what are the risks to the motherboard if I have a wrong configuration in coreboot, are there components that could get fried? I got the answer today from IRC (thank you agra, avph, felix_, icon, for all the help), and the answer is that it&#8217;s &#8220;highly unlikely&#8221; that I could damage the board, although it <em>is</em> possible, such as supplying a too high voltage to the memory controller. Most boards are safe however, as the voltage regulator would not allow such things, but some motherboards might not be as safe as others, so I&#8217;d need to check the voltage regulators on my board to see what kind of values they allow.</li>
</ul>
<p>So, now, I feel much more at ease with everything. My knowledge is of course still quite incomplete, but I don&#8217;t feel as blind as I felt last month, and I have a clear path towards what I need to be doing. Hopefully, I can find out easily how to enable debugging next week, figure out where everything went wrong, fix it, and &#8220;Tada! coreboot works!&#8221; But yeah, it&#8217;s probably going to be a little more complicated than that 😉</p>
<p>The post <a rel="nofollow" href="https://puri.sm/posts/librem-13-coreboot-report-january-12-2017/">Librem 13 coreboot report &#8211; January 12, 2017</a> appeared first on <a rel="nofollow" href="https://puri.sm/">Purism</a>.</p>
]]></content:encoded>
			</item>
	</channel>
</rss>
