carlosslessI make things and then write about themZola2023-10-19T00:00:00+00:00https://carlossless.io/atom.xmlHacking the NuPhy Air60 keyboard: part 22023-10-19T00:00:00+00:002023-10-19T00:00:00+00:00https://carlossless.io/nuphy-air-60-part-2/<p>It's time I wrote an update on this project again!</p>
<p>Since my <a href="/nuphy-air-60">last update</a>, I've been working on bootstrapping a development toolchain and producing a minimal firmware where I could initialize and test the core features of the SH68F90A along side of booting back into the ISP bootloader (otherwise the keyboard will become unprogramable via USB).</p>
<p>I am happy to say that I managed to do that, and released everything I have done so far on <a href="https://github.com/carlossless/sh68f90a-experiments">github</a>.</p>
<h2 id="v2-has-already-been-released">V2 has already been released<a class="zola-anchor" href="#v2-has-already-been-released" aria-label="Anchor link for: v2-has-already-been-released">§</a>
</h2>
<p>Before I get into what I managed to do, I should note that NuPhy have recently released <a href="https://nuphy.com/products/air60-v2">V2 of the Air60</a> and <a href="https://nuphy.com/products/air75-v2">Air75</a> keyboards. These new versions are powered by ARM MCUs instead of the 8051-based SH68F90A and comes with <a href="https://github.com/qmk/qmk_firmware">QMK</a> support out of the box.</p>
<p>I originally started this project, because I wanted to have QMK-like firmware on this keyboard, but since these news have come out, it has becomes purely a learning experience.</p>
<p>If you're interested in this project because of the possibility of running QMK on a Air60 or Air75 I really recommend you to just get the new version of these keyboards!</p>
<p>But anyway, on to the toolchain...</p>
<h2 id="embracing-open-source-tooling">Embracing Open-Source Tooling<a class="zola-anchor" href="#embracing-open-source-tooling" aria-label="Anchor link for: embracing-open-source-tooling">§</a>
</h2>
<p>A core principle of this project is to use all open source tooling to build the firmware. That's why I am using <a href="https://sdcc.sourceforge.net/">SDCC</a> here, instead of the proprietary <a href="https://developer.arm.com/Tools%20and%20Software/Keil%20PK51">Keil C51</a> which seems to be a standard for developing for 8051 MCUs.</p>
<p>I have SDCC configured with the smallest device size, so that all variables are put onto the IRAM, unless they are annotated differently (<code>__xdata</code>, <code>__code</code>, etc.).</p>
<p>The firmware size is 61440 leaving the remaining 4096 bytes untouched for the ISP bootloader.</p>
<p>When the ISP bootloader flashes the given firmware the finalisation routine looks for a <code>ljmp</code> instruction at <code>0xeffb</code> and if considers it valid, it will place it at <code>0x0000</code>, otherwise it will place a <code>ljmp</code> to <code>0xf000</code> (back to the bootloader itself). I gather that this is a mechanism to prevent corrupted firmware from being written to the device and then never being able to boot back into itself. Though, if you write non-corrupted, but non-working firmware, you won't be able to boot back into the ISP and you will need a programming device, like the sinolink. Be careful!. (Did I mention this is an incredibly brickable device?)</p>
<p>Anyway, because of this reason, I have added <a href="https://github.com/carlossless/sh68f90a-experiments/blob/main/src/preboot.asm">preboot.asm</a> which places this <code>ljmp</code> that points to the start of the user firmware at the previously mentioned place.</p>
<h1 id="diving-into-sh68f90a-s-capabilities">Diving into SH68F90A's Capabilities<a class="zola-anchor" href="#diving-into-sh68f90a-s-capabilities" aria-label="Anchor link for: diving-into-sh68f90a-s-capabilities">§</a>
</h1>
<p>The SH68F90A on the Air60 (and other Air models) come with the following <a href="https://github.com/carlossless/sh68f90a-experiments/blob/main/README.md#code-options">code-options</a> set. Since I would like to be able to load both the stock firmware and my own firmware through USB, I can't change these values to something else, but that also means that my firmware needs to do some specific initialization for the functionality these options require.</p>
<p>The first thing that needs to be setup is the 24MHz SYSCLK infrastructure, this involves initializing the PLL and then swiching SYSCLK to use the clock signal that's coming out of it, instead of the 128kHz OSC. <a href="https://github.com/carlossless/sh68f90a-experiments/blob/main/src/clock.c">link</a></p>
<p>Next, since we have the watchdog enabled, we need to configure the watchdog to use a comfortable overflow amount and then make sure that our firmware clears the watchdog timer before it overflows. (I wasn't able to test the WDT RESET flag, that would've helped in making this firmware a little bit less brickable). <a href="https://github.com/carlossless/sh68f90a-experiments/blob/main/src/watchdog.h">link</a></p>
<p>USB signaling also requires 3.3V, so we also need to initialize the internal voltage regulator. <a href="https://github.com/carlossless/sh68f90a-experiments/blob/main/src/ldo.c">link</a></p>
<p>Here we're already at a point where we have done enough initialization for the ISP bootloader program to work, so already, we could jump into it if we wanted <a href="https://github.com/carlossless/sh68f90a-experiments/blob/main/src/isp.c">link</a>.</p>
<p>GPIO setup is fairly straightforward, we setup the inputs and outputs, pull-ups according to the key matrix rows (input) and columns (output) and the RGB leds per row, per column. <a href="https://github.com/carlossless/sh68f90a-experiments/blob/main/src/gpio.c">link</a></p>
<p>Lastly, a pretty important tool for debugging (in absence of on-chip debugging via USB) is getting UART to work. This is fairly straightforward, and explained ok-ish in the datasheet, but the macros I added to calculate <code>SBRT</code> and <code>SFINE</code> values based on the desired baudrate should make it more easy to work with. Also, since the default (TXD, RXD) UART pins are harder to reach, I am setting the <code>MAPPING</code> register to <code>0x5a</code> to use the M_TXD and M_RXD pins instead, because they are also connected to the columns and the removable switch sockets, plugging in header cables for my USB<->SERIAL device, though it should be noted that PWM signals will interfere with the UART signals and you might get garbage in your serial output.</p>
<p><img src="https://carlossless.io/nuphy-air-60-part-2/uart.jpg" alt="uart connected through 5th and 6th key columns" /></p>
<p align="center">
<img alt="hello world printed on screen" src="hello-world.png">
</p>
<h2 id="on-the-horizon">On the horizon<a class="zola-anchor" href="#on-the-horizon" aria-label="Anchor link for: on-the-horizon">§</a>
</h2>
<p>Moving forward I will be continuing work on <a href="https://github.com/carlossless/sh68f90a-experiments">sh68f90a-experiments</a> focusing on getting the following functionalities to work:</p>
<ol>
<li>Key Matrix</li>
<li>PWM + RGB LED Matrix</li>
<li>USB (it's a working keyboard!)</li>
<li>Wireless (stretch-goal)</li>
</ol>
<p>Stay tuned for more updates!</p>
Hacking the NuPhy Air60 keyboard: part 12023-04-19T00:00:00+00:002023-04-19T00:00:00+00:00https://carlossless.io/nuphy-air60/<p>Not too long ago, I got a <a href="https://nuphy.com/products/air60">NuPhy Air60</a> keyboard. I got it because I think it looks great! It has a mostly aluminum body, low profile switches along with low profile keycaps, switch sockets so that they can be removed without soldering, 2.4G wireless alongside Bluetooth, and RGB backlighting (yay?). Great right? I think so.</p>
<p><img src="https://carlossless.io/nuphy-air60/keyboard.jpg" alt="keyboard" /></p>
<p>What's not great about it is its software and its firmware. NuPhy has a Windows-only tool to configure the keyboard and from what I can tell it's very limited in what sort of key combinations it can support... For a long time, I've been using a <a href="https://github.com/komar007/gh60">GH60</a> with <a href="https://github.com/qmk/qmk_firmware">QMK</a> until it broke on me and since then I've been mostly using Apple keyboards.</p>
<p>So I opened up the keyboard and when I was greeted with an IC that was labeled only with a "BYK916" I knew that this won't be easy... There was barely any information about chips like this. Seemingly Chinese companies would use this sort of labeling to hide away hardware implementation details or make their own custom packages, but I can't tell for sure.</p>
<p><img src="https://carlossless.io/nuphy-air60/mcu.jpg" alt="BYK916" /></p>
<p>I tried looking for any info online and on my first try I found nothing... A little bit of time passed and I tried again - this time there was a <a href="https://www.reddit.com/r/RedragonGaming/comments/nsdw7x/comment/hjwyu8q">reddit post</a> mentioning that a package like this was found in another keyboard and is actually a relabeled <a href="https://www.sinowealth.com/detaile?pro_id=105">Sinowealth SH68F90</a>. Interesting! But it's still a dead end for me since I don't have any tools to program these chips. On my third try, I was lucky enough to find <a href="https://github.com/gashtaan/sinowealth-8051-dumper">gashtaans sinowealth-8051-dumper</a> which supported my MCU. I didn't own any Arduinos by this point, so I set out to buy a Nano, and along the way I also learned about the existence of the ATmega328P clone LogicGreen LGT8F328P, but I digress...</p>
<p>I set up my Arduino with the dumper firmware and was able to <a href="https://github.com/gashtaan/sinowealth-8051-dumper/issues/2#issuecomment-1440488904">semi-successfully read firmware</a>. Nice!</p>
<p><img src="https://carlossless.io/nuphy-air60/flash-dump.jpg" alt="flash dumping setup" /></p>
<p>After a bit of rummaging through datasheets, buying a Sinolink programmer off of Taobao, and consulting others interested in this hardware I eventually figured out that I could use the already built-in ISP mode to upload my own firmware via USB, with no additional hardware needed. After a bit of sniffing and analyzing NuPhy's firmware update utility, I started building my own tool and...</p>
<p>I present you the <a href="https://github.com/carlossless/sinowealth-kb-tool">sinowealth-kb-tool</a>!</p>
<p>The tool is not only capable of replacing the existing device firmware but also reading it completely verbatim. Also, while working on the tool I became familiar with different variations of this bootloader in other keyboards out there in the wild and I hope to add support for more of them in the future!</p>
<p>Many thanks to <a href="https://github.com/gashtaan">@gashtaan</a> for the dumper and <a href="https://github.com/swiftgeek">@swiftgeek</a> for his documentation efforts!</p>
<p>Now on to writing some firmware... See you in the <a href="/nuphy-air-60-part-2">next part</a>!</p>
Raspberry Pi PoE+ hat with nixos2022-08-07T00:00:00+00:002022-08-07T00:00:00+00:00https://carlossless.io/nix-rpi-poe-plus-hat/<p>As previously mentioned in <a href="https://carlossless.io/rpi-cluster-at-home/">my last post</a>, I've been using <a href="https://nixos.org/">nixos</a> to run my raspberry-pi k3s cluster.</p>
<p>Things have been working great and managing these machines has never been this pleasant, <strong>except for one thing</strong> - the cooling fans which come with the <a href="https://www.raspberrypi.com/products/poe-plus-hat/">PoE+ hats</a> refuse to work out of the box with nixos.</p>
<p>These fans are enabled without any extra configuration under <a href="https://www.raspberrypi.com/software/">Raspberry Pi OS</a>, so I know that they <em>can</em> work, it just leaves me to figure out how to make them work...</p>
<h2 id="journey">Journey<a class="zola-anchor" href="#journey" aria-label="Anchor link for: journey">§</a>
</h2>
<p>After doing a bit of research I found that due to an incompatibility with the RPi bootloader and how nixos is designed to be used, the device tree cannot be passed down from the bootloader to the kernel, and thus a dtb must be "pre-baked" before some of the optional hardware, like these fans, can be used. This means that all overlays must be applied at compile time before the final dtb is produced. Nixos provides <code>hardware.deviceTree.overlays</code> to do just that.</p>
<p>Naturally, using <code>hardware.deviceTree.overlay</code> would be the way to go, and there's already <a href="https://github.com/NixOS/nixos-hardware/blob/09ed30ff3bb67f5efe9c77e0d79aca01793526ca/raspberry-pi/4/poe-hat.nix#L18">examples of taking almost unchanged overlays from rpi/linux</a> and applying them through this mechanism.</p>
<p>Unfortunately, some of the overlays that are available in <a href="https://github.com/raspberrypi/linux/tree/rpi-5.15.y/arch/arm/boot/dts/overlays">raspberrypi/linux</a> can not be successfully applied with the <code>fdtoverlay</code> tool used <a href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/os-specific/linux/device-tree/default.nix#L24">here</a>. It just fails with barely any output other than a not-so-helpful <code>FDT_NOT_FOUND</code> error, and even running it in verbose mode with <code>fdtoverlay -v</code> does not provide any additional hints.</p>
<p>Digging into it more, I found that these overlays actually require RPiFs own <a href="https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/dtmerge/dtmerge.c">dtmerge</a> tool for successfully application.</p>
<p>After a bit of fiddling, I found that exchanging the implementation of applyOverlay with one that uses <code>dtmerge</code> instead of <code>fdtoverlay</code> was enough to successfully produce a valid dtb, and with it, kick my rpi fans into motion.</p>
<h2 id="result">Result<a class="zola-anchor" href="#result" aria-label="Anchor link for: result">§</a>
</h2>
<p>I have created <a href="https://github.com/NixOS/nixos-hardware/pull/442">a pull-request in nixos-hardware</a> using the previously mentioned findings as a solution. <del>I'm not sure if this will ever be merged, but even if it won't be, it should serve as an example to anyone who would like to get their PoE+ hat fans working under nixos</del>.</p>
<p>UPDATE: It's been merged!</p>
Raspberry Pi Cluster @ Home2022-07-16T00:00:00+00:002022-07-16T00:00:00+00:00https://carlossless.io/rpi-cluster-at-home/<p>I recently decided to move most of my meager server workloads from the cloud back to my own home.</p>
<p>If you're asking <strong>"why???"</strong> Then I would have to ask you to settle down and inform you that it's much more a <strong>"why not???"</strong> situation.</p>
<p>I wanted to try and learn <a href="https://nixos.org/">nixos</a> and <a href="https://kubernetes.io/">k8s</a> (through <a href="https://k3s.io/">k3s</a>) and I like the idea of owning and having control over my hardware, that's pretty much the whole reason.</p>
<p>I'm not the first to do something like this and there are plenty of resources from people like <a href="https://www.jeffgeerling.com/tags/k3s">Jeff Geerling</a> that are doing the same with similar setups.</p>
<h2 id="hardware">Hardware<a class="zola-anchor" href="#hardware" aria-label="Anchor link for: hardware">§</a>
</h2>
<p>I wanted to have a nice clean rack-mountable enclosure for this cluster, but that took me on a path to design and produce several accessories to get more utility out of it, like <a href="https://github.com/carlossless/keystone-oled">keystone-oled</a> and <a href="https://github.com/carlossless/qwiic-hat">qwiic-hat</a>. Here are a few images of the project in it's current state.</p>
<table><thead><tr><th>Enclosure</th><th>Front</th><th>Qwiic Hat</th><th>Mounted</th></tr></thead><tbody>
<tr><td><a href="/rpi-cluster-at-home/enclosure.jpg"><img src="/rpi-cluster-at-home/enclosure.jpg" alt="enclosure" /></a></td><td><a href="/rpi-cluster-at-home/front.jpg"><img src="/rpi-cluster-at-home/front.jpg" alt="front" /></a></td><td><a href="/rpi-cluster-at-home/qwiic-hat.jpg"><img src="/rpi-cluster-at-home/qwiic-hat.jpg" alt="i2c-hat" /></a></td><td><a href="/rpi-cluster-at-home/mounted.jpg"><img src="/rpi-cluster-at-home/mounted.jpg" alt="mounted" /></a></td></tr>
</tbody></table>
<h3 id="bom">BOM<a class="zola-anchor" href="#bom" aria-label="Anchor link for: bom">§</a>
</h3>
<ul>
<li>1x <a href="https://shop.racknex.com/19-inch-raspberry-pi-rackmount-kit-um-sbc-209/">racknex UM-SBC-209</a></li>
<li>4x <a href="https://www.raspberrypi.com/products/raspberry-pi-4-model-b/">Raspberry Pi 4B</a></li>
<li>4x <a href="https://www.raspberrypi.com/products/poe-plus-hat/">POE+ hat</a></li>
<li>16x M2.5 15mm standoffs</li>
<li>8x M2.5 5mm standoffs</li>
<li>16x M2.5 flathead philips screws</li>
<li>4x <a href="https://www.reichelt.de/sg/de/buchsenleisten-2-54-mm-2x02-gerade-mpe-094-2-004-p119926.html?&trstct=pos_0&nbc=1">2x2 2.54mm socket</a> - for RPi POE pins</li>
<li>4x <a href="https://www.reichelt.de/sg/de/raspberry-pi-gpio-header-40-polig-rm-2-54-farblich-kodiert-rpi-header-cg2-p266032.html">2x20 2.54mm socket with long pins</a> - for RPi GPIO pins</li>
<li>4x <a href="https://github.com/carlossless/keystone-oled">keystone-oled</a></li>
<li>4x <a href="https://www.buydisplay.com/i2c-white-0-49-inch-oled-display-module-64x32-arduino-raspberry-pi">0.49 inch OLED SSD1306 32x64</a></li>
<li>4x <a href="https://github.com/carlossless/qwiic-hat">qwiic-hat</a></li>
</ul>
<h2 id="software">Software<a class="zola-anchor" href="#software" aria-label="Anchor link for: software">§</a>
</h2>
<p>The software driving the OLED screens is a small custom rust app using the userspace i2cdev interface. It shows node IPs, CPU temps and supports animated transitions, but it's not really finished and I haven't released it, <em>yet</em>...</p>
<p>I have tried using the <a href="https://github.com/torvalds/linux/blob/master/drivers/video/fbdev/ssd1307fb.c">ssd1307fb</a> driver to expose it as a linux framebuffer device, but I couldn't get it working perfectly and decided to drop it all together. I am looking it forward to trying <a href="https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/solomon/ssd130x-i2c.c">the drm rewrite of the driver</a> though.</p>
<h2 id="future-improvements-notes">Future Improvements & Notes<a class="zola-anchor" href="#future-improvements-notes" aria-label="Anchor link for: future-improvements-notes">§</a>
</h2>
<p>LEDs: In the future I would also like to mount RGB LEDs in those currently vacant holes. I have yet to design a board for them, but that's why I have a second unused qwiic/I2C port.</p>
<p>fans: There are mounting holes on the UM-SBC-209 case for 40mm fans, but I don't yet have a way of powering them. I am considering expanding the qwiic-hat to include a 4-pin PWM fan connector to power and control the fan.</p>
<h1 id="next">Next?<a class="zola-anchor" href="#next" aria-label="Anchor link for: next">§</a>
</h1>
<p>In future posts I'll write about my setup with nixos, <a href="https://github.com/NixOS/nixops">nixops</a> and k3s. Stay tuned!</p>
APFS Volumes for your git projects2019-06-10T15:02:00+00:002019-06-10T15:02:00+00:00https://carlossless.io/solving-that-pesky-file-rename-in-git-with-apfs-volumes/<p>I've been using this setup for over 2 years now and it saved me from a large number of small to medium headaches that used to haunt me every so often. Because of this, I think it's worth talking about in a blog post.</p>
<h1 id="so-what-am-i-talking-about">So what am I talking about?<a class="zola-anchor" href="#so-what-am-i-talking-about" aria-label="Anchor link for: so-what-am-i-talking-about">§</a>
</h1>
<p>Ever had to commit a file only to realize that you got the capitalization wrong? I've certainly been in that situation.</p>
<p>Well you'd think that you could just go back, edit the filename, <code>git commit --commit</code> and you're good, right? Wrong.</p>
<p><a href="https://asciinema.org/a/AXQ3HyaE4vz6G4HUUeN2HJvg7"><img src="https://asciinema.org/a/AXQ3HyaE4vz6G4HUUeN2HJvg7.svg" alt="asciicast" /></a></p>
<p>Well... Wrong for most users at least, because most of them will notice that the naming change wasn't picked up by git.</p>
<p>The reason why? It's probably because you're using a case-insensitive file system. It used to be the default option for HFS+, and it still is the default for APFS. Some applications rely on this to be the case, like the Adobe suite, so you don't want to change case-sensitivity for your whole system drive.</p>
<h1 id="volumes-to-the-rescue">Volumes to the rescue!<a class="zola-anchor" href="#volumes-to-the-rescue" aria-label="Anchor link for: volumes-to-the-rescue">§</a>
</h1>
<p>APFS redefines partitions with the introduction of <em>volumes</em>. Normal partitions and APFS volumes differ in many ways, but the two that we care about in this case are:</p>
<ul>
<li>Space sharing - volumes don't have predetermined sizes and will be able to "grow" until there's no space left in the container.</li>
<li>Independent configuration - different volumes can have different variants of APFS setup. In our case we can have a case-insensitive volume and a case-sensitive one.</li>
</ul>
<p>So, in my case I created a new volume APFS called <strong>Projects</strong> with case-sensitive filenames and put all of my code and repositories in it.</p>
<p><a href="/2019-06-10-solving-that-pesky-file-rename-in-git-with-apfs-volumes/hZ6ABYkF5ngLZ49NUt8qa10xspap.png"><img src="/2019-06-10-solving-that-pesky-file-rename-in-git-with-apfs-volumes/hZ6ABYkF5ngLZ49NUt8qa10xspap.png" alt="Screenshot 2019-06-10 at 15.53.17.png" /></a></p>
<p>Et Voilà! All filename changes are now getting picked up by <code>git status</code>.</p>
<p><a href="https://asciinema.org/a/j22jhjqBkIstyWy24LVT8blyg"><img src="https://asciinema.org/a/j22jhjqBkIstyWy24LVT8blyg.svg" alt="asciicast" /></a></p>
Xcode 9 and Carthage - stripping out llvm instrument symbols2017-09-17T03:32:00+00:002017-09-17T03:32:00+00:00https://carlossless.io/xcode-9-and-carthage-coverage-data/<p>Like any other year the new Xcode GM came out and everybody started rushing to submit their apps. This year, I was also one of these early adopters. Things were going relatively smoothly, except for a weird issue with <code>xattr</code> when trying to export archives. Regardless, I uploaded the build and was ready to see it processed... And then...</p>
<h1 id="the-problem">The Problem<a class="zola-anchor" href="#the-problem" aria-label="Anchor link for: the-problem">§</a>
</h1>
<p><a href="/2017-09-17-xcode-9-and-carthage-coverage-data/ic3junrykhonww.png"><img src="/2017-09-17-xcode-9-and-carthage-coverage-data/ic3junrykhonww.png" alt="Screen Shot 2017-09-14 at 12.42.56.png" /></a></p>
<blockquote>
<p><strong>Invalid Bundle</strong> - Disallowed LLVM instrumentation. Do not submit apps with LLVM profiling instrumentation or coverage collection enabled. Turn off LLVM profiling or code coverage, rebuild your app and resubmit the app.</p>
</blockquote>
<p>LLVM instrumentation? What? I thought that gets striped out on Archive?</p>
<p>Well it turns out, that it does get stripped out, but only for the main application. I use <a href="https://github.com/Carthage/Carthage">Carthage</a> for dependency management and Carthage doesn't build targets with the Archive action (<a href="https://github.com/Carthage/Carthage/issues/169#issuecomment-68624884">or rather it can't</a>) and Xcode 9 enables code coverage by default:</p>
<p><a href="/2017-09-17-xcode-9-and-carthage-coverage-data/3sxvt5m7mcmzfq.png"><img src="/2017-09-17-xcode-9-and-carthage-coverage-data/3sxvt5m7mcmzfq.png" alt="Screen Shot 2017-09-14 at 19.03.43.png" /></a></p>
<h1 id="the-solution">The Solution?<a class="zola-anchor" href="#the-solution" aria-label="Anchor link for: the-solution">§</a>
</h1>
<p><code>xcodebuild</code> flags don't seem to affect this issue, meaning that every framework developer that makes their libraries available through Carthage will have to manually change this setting.</p>
<p>For the time being you'll have to checkout all of the dependencies and manually change <code>CLANG_ENABLE_CODE_COVERAGE</code> to <code>NO</code> for every dependency before building them with <code>carthage build</code>.</p>
<h1 id="survival-through-tooling">Survival through Tooling<a class="zola-anchor" href="#survival-through-tooling" aria-label="Anchor link for: survival-through-tooling">§</a>
</h1>
<p>I've made <a href="https://gist.github.com/carlossless/9492d8e20938cfd1ee8163d7cdbfab9b">a little script</a> that streamlines checking for LLVM instrument symbols. Change your working directory to the root of your project and you can pipe this script straight into bash (if you dare):</p>
<pre data-lang="bash" style="background-color:#191919;color:#ffffff;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#cccccc;">curl</span><span style="font-style:italic;color:#8aa6c1;"> -fsSL</span><span style="color:#cccccc;"> https://gist.githubusercontent.com/carlossless/9492d8e20938cfd1ee8163d7cdbfab9b/raw </span><span>| </span><span style="color:#cccccc;">bash
</span></code></pre>
<p>Hopefully we'll see improvements in later versions of Xcode and <code>xcodebuild</code>, but for now we'll have to live with this.</p>
<h5 id="resources">Resources<a class="zola-anchor" href="#resources" aria-label="Anchor link for: resources">§</a>
</h5>
<ul>
<li><a href="https://developer.apple.com/library/content/qa/qa1964/_index.html#//apple_ref/doc/uid/DTS40017675-CH1-INSPECT">Apple Developer Docs - Technical Q&A QA1964: Resolving App Rejections for GCC and LLVM Instrumentation</a></li>
<li><a href="https://github.com/Carthage/Carthage/issues/2056">GitHub Issues - Carthage - Targets built with coverage data in Xcode 9 #2056</a></li>
</ul>
Reverse Hackintosh Pro2017-06-17T15:08:00+00:002017-06-17T15:08:00+00:00https://carlossless.io/reverse-hackintosh-pro/<p>Well it's been awhile, but I'm back to doing my own projects again.</p>
<h1 id="prelude">Prelude<a class="zola-anchor" href="#prelude" aria-label="Anchor link for: prelude">§</a>
</h1>
<p>So lately I've been feeling left out of the gaming world and thought to myself: "Hey why not build a sweet new gaming rig and jump right back into all of the fun?". Well, knowing myself I knew that after playing a couple of games, I would get bored and this rig won't see much use after that.</p>
<p>To counteract that I need to be able to do work on it. But I'm an iOS developer and practically there's only one platform that I can do my work on - macOS.</p>
<p>Alright, so it's a Hackintosh then!</p>
<p>Apple hasn't released significantly improved hardware for "pros" in years now, so this might actually be good timing to build one.</p>
<p>But let's not make things too simple. Remember those older Mac Pros? The cheese graters? Those cases look awesome and sleek, wouldn't it be awesome to build a pc in one of them? There's other people doing it also? SIGN ME UP!</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/vlfs0cslbsouw.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/vlfs0cslbsouw.jpg" alt="cheese-grater.JPG" /></a></p>
<h1 id="table-of-contents">Table of Contents<a class="zola-anchor" href="#table-of-contents" aria-label="Anchor link for: table-of-contents">§</a>
</h1>
<!-- toc -->
<h1 id="build">Build<a class="zola-anchor" href="#build" aria-label="Anchor link for: build">§</a>
</h1>
<p>After doing some research I found a guy in Berlin who sold me his broken 2016 Mac Pro for 50€. After taking it home I immediately stripped most of the parts from it and started looking for suitable components.</p>
<h2 id="bom">BOM<a class="zola-anchor" href="#bom" aria-label="Anchor link for: bom">§</a>
</h2>
<p>I had simple requirements for the motherboard:</p>
<ol>
<li>It had to be Micro ATX form factor. So I wouldn't have to cut the case to make room for a full ATX motherboard.</li>
<li>It had to have Thunderbolt compatibility, preferably Thunderbolt 2, so I could use my Thunderbolt display with it.</li>
</ol>
<p>This is what I ended up with:</p>
<table><thead><tr><th>Part</th><th>Brand</th><th>Name</th><th>Quantity</th></tr></thead><tbody>
<tr><td>Motherboard</td><td>GIGABYTE</td><td>GA-Z170MX-Gaming 5</td><td>1</td></tr>
<tr><td>CPU</td><td>Intel</td><td>Core™ i7-6700K</td><td>1</td></tr>
<tr><td>GPU</td><td>EVGA</td><td>GeForce GTX 980 Ti HYBRID GAMING</td><td>1</td></tr>
<tr><td>RAM</td><td>Corsair</td><td>Vengeance® LPX 32GB (4 x 8GB) DDR4 DRAM 2400MHz</td><td>1</td></tr>
<tr><td>M2</td><td>Samsung</td><td>950 PRO M.2 256GB</td><td>1</td></tr>
<tr><td>SATA</td><td>Samsung</td><td>850-EVO 500GB</td><td>4</td></tr>
<tr><td>PCIE</td><td>AsRock</td><td>Thunderbolt™ 2 AIC</td><td>1</td></tr>
<tr><td>PCIE</td><td>Wdxxfu Studio Design</td><td>BCM943602CS (WIFI+BT)</td><td>1</td></tr>
<tr><td>PSU</td><td>EVGA</td><td>850 GQ Power Supply</td><td>1</td></tr>
<tr><td>CPU Cooler</td><td>Alpenföhn</td><td>Ben Nevis</td><td>1</td></tr>
<tr><td>Case Fan</td><td>Noctua</td><td>NF-S12B redux-700</td><td>1</td></tr>
<tr><td>Case Fan</td><td>Noctua</td><td>NF-S12B redux-1200</td><td>1</td></tr>
<tr><td>MISC</td><td>NewerTech</td><td>AdaptaDrive</td><td>4</td></tr>
</tbody></table>
<p><a href="/2017-06-17-reverse-hackintosh-pro/irj7mosz2bjiea.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/irj7mosz2bjiea.jpg" alt="bom.jpg" /></a></p>
<h2 id="hardware">Hardware<a class="zola-anchor" href="#hardware" aria-label="Anchor link for: hardware">§</a>
</h2>
<h3 id="matx-motherboard-tray">mATX Motherboard Tray<a class="zola-anchor" href="#matx-motherboard-tray" aria-label="Anchor link for: matx-motherboard-tray">§</a>
</h3>
<p>I went and got the mATX kit from <a href="http://www.thelaserhive.com/product/mac-pro-matx-120-kit/">the laser hive</a> (plastic grill version). They provide pretty comprehensive instructions with the kit, so inserting and fastening the tray was a breeze. Cutting out and the back and attaching the back panel wasn't too hard either.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/2ixet7kyer79a.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/2ixet7kyer79a.jpg" alt="empty-case.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/yyrnypby6d6rq.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/yyrnypby6d6rq.jpg" alt="back-stripped.jpg" /></a></p>
<h3 id="power-supply">Power Supply<a class="zola-anchor" href="#power-supply" aria-label="Anchor link for: power-supply">§</a>
</h3>
<p>The PSU was probably one of the components that I had to do the most work on in order to get it inside the case. </p>
<p>At first I thought I could stick in the internals of a standard power supply into the case of the original Mac Pro PSU. However, that didn't work out because the PSU would overheat after a few minutes under intense load. I had to scrap the original PSU I had bought and get another one.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/m5qomtedsseow.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/m5qomtedsseow.jpg" alt="psu-oem.jpg" /></a></p>
<h4 id="cable">Cable<a class="zola-anchor" href="#cable" aria-label="Anchor link for: cable">§</a>
</h4>
<p>I wanted to reuse the original AC port, so I had to make a little low profile adapter to solve the different placement of the cable port.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/vjjlmpmygwoz1q.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/vjjlmpmygwoz1q.jpg" alt="psu-cable-front.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/rdmcatkv3z6sq.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/rdmcatkv3z6sq.jpg" alt="psu-cable-back.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/ickhzmms8il1q.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/ickhzmms8il1q.jpg" alt="psu-connection-closeup.jpg" /></a></p>
<h4 id="case">Case<a class="zola-anchor" href="#case" aria-label="Anchor link for: case">§</a>
</h4>
<p>I had to cut off one end of the original PSU case in order for it to house the new longer PSU. I also had to remove the PSU fan assembly from the case to fit the new PSU.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/adzbhnvjyubsw.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/adzbhnvjyubsw.jpg" alt="psu-case.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/lwiowvar0qzhyg.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/lwiowvar0qzhyg.jpg" alt="psu-tray-cutoff.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/vgfjnnyyvabsba.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/vgfjnnyyvabsba.jpg" alt="psu-connection.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/xtzoae7ocmcpgg.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/xtzoae7ocmcpgg.jpg" alt="psu-assembled.jpg" /></a></p>
<h3 id="front-panel">Front Panel<a class="zola-anchor" href="#front-panel" aria-label="Anchor link for: front-panel">§</a>
</h3>
<p>I wanted to reuse the Mac Pros front panel interface. To do that neatly I had to make a couple PCBs.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/3oikcvg9eybdq.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/3oikcvg9eybdq.jpg" alt="12pin-adapter-pcb.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/gc2g1vzdp4uhva.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/gc2g1vzdp4uhva.jpg" alt="usb-adapter-pcb.jpg" /></a></p>
<p>The designs for these PCBs are free and available on <a href="https://github.com/carlossless/mac-pro-conversion">GitHub</a>, you can use any PCB manufacturing service to make these, but I personally prefer <a href="https://oshpark.com/">OSH Park</a> for prototypes.</p>
<p>Here are the adapters in action:</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/it9goyyx18yfq.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/it9goyyx18yfq.jpg" alt="usb-adapter-in-action.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/9whphqhnbhaaw.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/9whphqhnbhaaw.jpg" alt="12pin-adapter-pcb-in-action.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/oscndcpxp67yq.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/oscndcpxp67yq.jpg" alt="front-panel-pcb.jpg" /></a></p>
<p><strong>One important note:</strong> the original 8 pin Micro-FIT cable that caries power for the panel from the original motherboard has it's pins mirrored on both ends. The pcb is designed for that cable, so you should be good if you use it. However, if you're making your own adapter, please check which pin on one end corresponds to what pin on the other end.</p>
<h3 id="sata">SATA<a class="zola-anchor" href="#sata" aria-label="Anchor link for: sata">§</a>
</h3>
<p>The SATA slots in the mac pro are pretty frigging cool, I wanted to make them functional with the new motherboard. Fortunately this was pretty easy (but pricey). I had to buy <a href="http://www.maxupgrades.com/istore/index.cfm?fuseaction=product.display&product_ID=330&ParentCat=332">this adapter</a>. Making one doesn't make sense as the parts themselves cost almost as much as this fully build adapter.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/ba9jkpmignshq.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/ba9jkpmignshq.jpg" alt="scsi-adapter.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/orzkkspssxgzcw.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/orzkkspssxgzcw.jpg" alt="scsi-adapter-with-sata.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/vofbqzldrzxw.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/vofbqzldrzxw.jpg" alt="scsi-adapter-in-action.jpg" /></a></p>
<p>The drawers obviously also need SATA power, so I had to make a little adapter from the PSU to the custom apple connector. Sadly, I did not take a picture of it, and it's pretty deep in the case to remove it.</p>
<p>As there's not too many reasons to go with a mechanical hard drive and SATA SSDs only come in 2.5" I had to buy a few 3.5" to 2.5" adapters. There are plenty of these available to buy on Amazon.</p>
<h3 id="front-fan-assembly">Front Fan Assembly<a class="zola-anchor" href="#front-fan-assembly" aria-label="Anchor link for: front-fan-assembly">§</a>
</h3>
<p>Because of a very nice deal, I got an air-cooled, water-cooled hybrid GPU. One problem is that it comes with a gigantic radiator that needs to go somewhere in the case. Fortunately the original fan assembly was ideal for this. Just after a few modifications to (with a handy dremel) it I could easily hold the radiator and fan on top of it.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/cworxxwnziszg.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/cworxxwnziszg.jpg" alt="fan-assembly-back.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/arnyygt280haqg.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/arnyygt280haqg.jpg" alt="fan-assembly-front.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/euisgplvzl6q.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/euisgplvzl6q.jpg" alt="gpu-fan-assembly.jpg" /></a></p>
<h3 id="wifi">Wifi<a class="zola-anchor" href="#wifi" aria-label="Anchor link for: wifi">§</a>
</h3>
<p>After some research, it became obvious that the best WIFI adapter for macOS is an original one. Fortunately for me, China if full of them. I got mine from <a href="https://world.taobao.com/item/38195333521.htm?fromSite=main&spm=a230r.1.0.0.M8souu">TaoBao</a>. No additional steps needed to get WI-FI working. Although iMessage is another story...</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/sfcoeatsoebc2g.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/sfcoeatsoebc2g.jpg" alt="wifi.jpg" /></a></p>
<h3 id="thunderbolt">Thunderbolt<a class="zola-anchor" href="#thunderbolt" aria-label="Anchor link for: thunderbolt">§</a>
</h3>
<p>I wanted to use my Apple Thunderbolt Display with this machine, so thunderbolt support was imperative.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/h2msvivladnqlg.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/h2msvivladnqlg.jpg" alt="thunderbolt.jpg" /></a></p>
<p>However macOS support for third party controllers is very... very... flaky. I had different levels of success, but nothing came close to being truly stable. Either the displays USB hub wouldn't work, or daisy chaining a hard drive wouldn't work, or the display wouldn't turn on in general. You can get it to work though and that's good enough for now.</p>
<p>The controller itself wouldn't ever get recognized by System Information, although it's children peripherals would show up as if they're hooked in directly in the system.</p>
<h3 id="back-fan">Back Fan<a class="zola-anchor" href="#back-fan" aria-label="Anchor link for: back-fan">§</a>
</h3>
<p>I had to cut off sides of the original backside fan grill in order to make it fit with the ATX motherboard backplate. But the amount of flat plastic surface left is enough to drill holes into the other side of the grill and attach the actual new fan to itself.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/7ofbcld3rk4bsg.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/7ofbcld3rk4bsg.jpg" alt="back-fan-back.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/bjgg7o3ampac2a.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/bjgg7o3ampac2a.jpg" alt="back-fan-front.jpg" /></a></p>
<h3 id="other-pictures">Other Pictures<a class="zola-anchor" href="#other-pictures" aria-label="Anchor link for: other-pictures">§</a>
</h3>
<p><a href="/2017-06-17-reverse-hackintosh-pro/pcrkonxob92j3g.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/pcrkonxob92j3g.jpg" alt="finished.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/jhwqlc8pszpnq.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/jhwqlc8pszpnq.jpg" alt="drawer-out.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/itibyi2498boew.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/itibyi2498boew.jpg" alt="case-backside.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/qn5kitdqf2nxla.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/qn5kitdqf2nxla.jpg" alt="items.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/fqffuoienz1yw.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/fqffuoienz1yw.jpg" alt="case-backside-front.jpg" /></a></p>
<h2 id="software">Software<a class="zola-anchor" href="#software" aria-label="Anchor link for: software">§</a>
</h2>
<h3 id="bios-options">BIOS Options<a class="zola-anchor" href="#bios-options" aria-label="Anchor link for: bios-options">§</a>
</h3>
<p>Before installing macOS it's important to change a few BIOS settings from their default values:</p>
<ul>
<li>Enable XHCI Handoff (important for USB to work)</li>
<li>Disable Serial IO</li>
<li>Enable Thunderbolt
<ul>
<li>Security: Legacy</li>
</ul>
</li>
</ul>
<h3 id="installation-clover">Installation, Clover<a class="zola-anchor" href="#installation-clover" aria-label="Anchor link for: installation-clover">§</a>
</h3>
<p>I used <a href="https://www.tonymacx86.com/resources/categories/tonymacx86-downloads.3/">UniBeast</a> to install macOS and <a href="https://www.tonymacx86.com/resources/categories/tonymacx86-downloads.3/">MultiBeast</a> to configure all the options, injected kexts and etc. There are a number of guides on the web that cover this hardware, and some of the options depends on taste, so I won't cover them here.</p>
<p>It's generally a good idea to have the latest version of <a href="https://sourceforge.net/projects/cloverefiboot/">Clover</a> installed. Multibeast usually comes with a version that's stable, but pretty outdated.</p>
<p>A very helpful tool if you don't want to deal with plists all the time when tweaking your Clover settings is the <a href="http://mackie100projects.altervista.org/download-clover-configurator/">Clover Configurator</a>.</p>
<h3 id="imessage-icloud-app-store">iMessage, iCloud, App Store<a class="zola-anchor" href="#imessage-icloud-app-store" aria-label="Anchor link for: imessage-icloud-app-store">§</a>
</h3>
<p>This is probably what gives people the most headaches in getting their hackintoshes fully working. I used a couple techniques to get this finally working.</p>
<p>I had success in following <a href="http://www.fitzweekly.com/2016/02/hackintosh-imessage-tutorial.html">this guide</a>. But before I got everything working, I had my Apple ID account locked multiple times, so beware! It's no big deal of course, you just need to come up with a new password every time, but it's SEVERELY ANNOYING.</p>
<h3 id="nvme-storage">NVMe Storage<a class="zola-anchor" href="#nvme-storage" aria-label="Anchor link for: nvme-storage">§</a>
</h3>
<p>To get the NVMe storage drive to work (including installing macOS on that drive) I just used RehabMan's wonderful <a href="https://github.com/RehabMan/patch-nvme">kext patches</a>. He has very comprehensive instructions on what needs to be done.</p>
<h3 id="gpu">GPU<a class="zola-anchor" href="#gpu" aria-label="Anchor link for: gpu">§</a>
</h3>
<p>Getting the GPU to work is pretty straightforward. All I had to do is install the latest <a href="https://www.tonymacx86.com/nvidia-drivers/">NVIDIA Web Drivers</a>. And making sure that the clover flag to use them is set "nvda_drv=1".</p>
<h1 id="other-stuff">Other Stuff<a class="zola-anchor" href="#other-stuff" aria-label="Anchor link for: other-stuff">§</a>
</h1>
<p>Like any project, this one has it's share of notes and fails. Here's a few of them.</p>
<h2 id="original-build">Original Build<a class="zola-anchor" href="#original-build" aria-label="Anchor link for: original-build">§</a>
</h2>
<p>This is what I had planned to use initially:</p>
<table><thead><tr><th>Part</th><th>Brand</th><th>Name</th></tr></thead><tbody>
<tr><td>Motherboard</td><td>AsRock</td><td>Fatal1ty X99M Killer/3.1</td></tr>
<tr><td>CPU</td><td>Intel</td><td>Core™ i7-6800K</td></tr>
<tr><td>GPU</td><td>EVGA</td><td>GeForce GTX 980 Ti HYBRID GAMING</td></tr>
<tr><td>RAM</td><td>Corsair</td><td>Vengeance® LPX 32GB (4 x 8GB) DDR4 DRAM 2400MHz</td></tr>
<tr><td>Drive</td><td>Samsung</td><td>950 PRO M.2 256GB</td></tr>
<tr><td>PCIE</td><td>AsRock</td><td>Thunderbolt™ 2 AIC</td></tr>
<tr><td>PSU</td><td>EVGA</td><td>850 GQ Power Supply</td></tr>
<tr><td>CPU Cooler</td><td>Alpenföhn</td><td>Ben Nevis</td></tr>
<tr><td>Case Fans</td><td>Noctua</td><td>2x NF-S12B redux-700 + 1x NF-S12B redux-1200</td></tr>
</tbody></table>
<h3 id="chipset-thunderbolt">Chipset & Thunderbolt<a class="zola-anchor" href="#chipset-thunderbolt" aria-label="Anchor link for: chipset-thunderbolt">§</a>
</h3>
<blockquote>
<p>Now I know what you're thinking. X99? That's going to be a pain to install macOS on, if possible at all. And, well you're right, but the reason I picked the Fatal1ty X99M Killer was because that was the only Micro ATX board with thunderbolt a capability and AsRock had it's AIC card for sale. In comparison Gigabyte had a Z170 Micro ATX motherboard with a Thunderbolt header, but Gigabytes AIC card wasn't being sold ANYWHERE. Only later did I find out that most of these thunderbolt cards are intercompatible between different brands...</p>
</blockquote>
<p>X99 support proved to be to difficult, and the interchangeability of the thunderbolt cards pushed me to use Z170 instead.</p>
<h3 id="standoffs">Standoffs<a class="zola-anchor" href="#standoffs" aria-label="Anchor link for: standoffs">§</a>
</h3>
<blockquote>
<p>In order to stuff some components in and connect others I had to make some modifications to the case. The first of these modifications was to remove the existing motherboard standoffs. This was fairly simple, you can remove the standoffs with pliers or a hammer. The next step was to to glue my own standoffs with epoxy, I did it by screwing in all of the standoffs to the motherboard and then covering their bottom ends with a small layer of epoxy, I put the motherboard into the case and aligned it, waited for some time and then undid the screws and took out the motherboard, I covered the base of the standoffs with more epoxy around them to secure them in place. You need to be careful when screwing your motherboard back in, because even though the epoxy has a pretty firm grip on the standoffs you can still break them off with enough force when screwing in the screws.</p>
</blockquote>
<p>After breaking a few of them, and ultimately needing the back facing IO ports more than I expected I got a ATX conversion kit from lazer hive.</p>
<h2 id="the-perfect-build">The Perfect Build<a class="zola-anchor" href="#the-perfect-build" aria-label="Anchor link for: the-perfect-build">§</a>
</h2>
<p>Before doing this project I did some research on already existing builds. One build I found was absolutely amazing.</p>
<p>Skin008 - a Chinese electrical engineer and serial mac pro modder, made a one of a kind mac pro retrofit kit that reuses the same ports on the original 2008 and 2010 macs.</p>
<p><a href="/2017-06-17-reverse-hackintosh-pro/jjqpu8ly9azjow.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/jjqpu8ly9azjow.jpg" alt="skin008-board.jpg" /></a>
<a href="/2017-06-17-reverse-hackintosh-pro/q0yltbzvuc0kw.jpg"><img src="/2017-06-17-reverse-hackintosh-pro/q0yltbzvuc0kw.jpg" alt="skin008-case.jpg" /></a></p>
<p>I reached out to him, but found out that he only did 10 of these boards, sold them and was too busy with his personal stuff to make new ones this year. He did mention however that he may do another batch next year. I hope that’s true and I’ll try to keep in touch with him. You can find more pictures of his boards showcased <a href="http://acidluna.tistory.com/295">here</a>.</p>
Convenient Dependency Injection in Swift2015-10-17T05:09:00+00:002015-10-17T05:09:00+00:00https://carlossless.io/convenient-di-in-swift/<p>Ever since Swift 1.0 was released, I have been struggling with finding a way to introduce some proper dependency injection into my code. The previous methods that were popular in objective-C like Swizzling or property overloading no longer works or require far too many changes to your code to make them actually worth it.</p>
<p><a href="https://twitter.com/natashatherobot">Natasha Murashev</a> posted some nice ideas about dependency injection through default property values in functions, you can read more about that <a href="http://natashatherobot.com/unit-testing-swift-dependency-injection/">here</a>.</p>
<p>But there's one problem with this solution, the default values require that the concrete implementation be dragged in and linked with your testing target, and that might be something that you don't want to do.</p>
<p>Today I bring you a way to solve these issues: by using default property values, (convenience) initilizers and type extensions to introduce some really convenient dependency injection.</p>
<h1 id="the-example">The Example<a class="zola-anchor" href="#the-example" aria-label="Anchor link for: the-example">§</a>
</h1>
<p>Let's start with the dependant type:</p>
<pre data-lang="swift" style="background-color:#191919;color:#ffffff;" class="language-swift "><code class="language-swift" data-lang="swift"><span>public </span><span style="color:#80d500;">struct</span><span style="color:#cccccc;"> Farm {
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> </span><span>private </span><span style="color:#80d500;">let</span><span style="color:#cccccc;"> animals: [Animal]
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> </span><span>init</span><span style="color:#cccccc;">(animals: [Animal]) {
</span><span style="color:#cccccc;"> </span><span>self.</span><span style="color:#cccccc;">animals </span><span>=</span><span style="color:#cccccc;"> animals
</span><span style="color:#cccccc;"> }
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> </span><span>public </span><span style="color:#80d500;">func </span><span style="color:#cccccc;">feedAnimals() </span><span>-></span><span style="color:#cccccc;"> [</span><span style="color:#8aa6c1;">String</span><span style="color:#cccccc;">] {
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">return</span><span style="color:#cccccc;"> animals</span><span>.</span><span style="color:#cccccc;">map { $</span><span style="color:#eddd5a;">0</span><span>.</span><span style="color:#cccccc;">feed() }
</span><span style="color:#cccccc;"> }
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;">}
</span></code></pre>
<p>The Farm houses a bunch of generic animals, <code>Animal</code> is just a protocol for our dependencies - the actual farm animals. Here's the protocol itself:</p>
<pre data-lang="swift" style="background-color:#191919;color:#ffffff;" class="language-swift "><code class="language-swift" data-lang="swift"><span>public </span><span style="color:#80d500;">protocol</span><span style="color:#cccccc;"> Animal {
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">func </span><span style="color:#cccccc;">feed() </span><span>-> </span><span style="color:#8aa6c1;">String
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;">}
</span></code></pre>
<p>Now let's add some concrete implementations of this protocol that we'll use in our production app:</p>
<pre data-lang="swift" style="background-color:#191919;color:#ffffff;" class="language-swift "><code class="language-swift" data-lang="swift"><span>public </span><span style="color:#80d500;">struct</span><span style="color:#cccccc;"> Cow: Animal {
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> </span><span>public </span><span style="color:#80d500;">func </span><span style="color:#cccccc;">feed() </span><span>-> </span><span style="color:#8aa6c1;">String </span><span style="color:#cccccc;">{
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">return </span><span style="color:#ffd700;">"Moooo!"
</span><span style="color:#cccccc;"> }
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;">}
</span><span style="color:#cccccc;">
</span><span>public </span><span style="color:#80d500;">class</span><span style="color:#cccccc;"> Duck: Animal {
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> </span><span>public </span><span style="color:#80d500;">func </span><span style="color:#cccccc;">feed() </span><span>-> </span><span style="color:#8aa6c1;">String </span><span style="color:#cccccc;">{
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">return </span><span style="color:#ffd700;">"Quack!"
</span><span style="color:#cccccc;"> }
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;">}
</span></code></pre>
<p>We ended up with a fully testable <code>Farm</code> type which we can use in our application by passing the right set of dependencies: </p>
<pre data-lang="swift" style="background-color:#191919;color:#ffffff;" class="language-swift "><code class="language-swift" data-lang="swift"><span style="color:#cccccc;">Farm(animals: [Cow(), Duck()]))
</span></code></pre>
<p>But <em>DI</em> isn't really <em>DI</em> unless you don't have to care about what you're passing to the constructor in your actual use case.</p>
<p>This is where class extensions come in. With Swift we can extend <em>classes</em> with convenience initializers and <em>structs</em> with just regular initializers wherever we like! So to do that create a separate swift file to house your DI initializers (you need to keep this in a different file to include it in your application and exclude it form your testing target, so you don't include the whole dependency tree for the type you're testing). In this file we would have:</p>
<pre data-lang="swift" style="background-color:#191919;color:#ffffff;" class="language-swift "><code class="language-swift" data-lang="swift"><span style="color:#80d500;">extension</span><span style="color:#cccccc;"> Farm {
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> </span><span>init</span><span style="color:#cccccc;">() {
</span><span style="color:#cccccc;"> </span><span>self.init</span><span style="color:#cccccc;">(animals: [Cow(), Duck()])
</span><span style="color:#cccccc;"> }
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;">}
</span></code></pre>
<p>Since this is a swift extension, we can have whatever we want here, even returning a singleton instance of the interface you want to use. To put it simply: you're only limited by Swift itself when it comes to deciding how you want your dependencies executed and your dependency tree handled. For the sake of this example I chose to use the most simple case.</p>
<h1 id="on-to-the-tests">On to the Tests!<a class="zola-anchor" href="#on-to-the-tests" aria-label="Anchor link for: on-to-the-tests">§</a>
</h1>
<p>Now we want to unit test the Farm struct. We didn't import the source file that contains conveniences and the dependency tree, so we don't have to import types for <code>Cow</code> and <code>Duck</code>. Instead let's create a new mock type for our <code>Animal</code> protocol and execute the test with that:</p>
<pre data-lang="swift" style="background-color:#191919;color:#ffffff;" class="language-swift "><code class="language-swift" data-lang="swift"><span style="color:#80d500;">struct</span><span style="color:#cccccc;"> TestAnimal: Animal {
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">func </span><span style="color:#cccccc;">feed() </span><span>-> </span><span style="color:#8aa6c1;">String </span><span style="color:#cccccc;">{
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">return </span><span style="color:#ffd700;">"This isn't an actual animal, it's just a test"
</span><span style="color:#cccccc;"> }
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;">}
</span><span style="color:#cccccc;">
</span><span style="color:#80d500;">class</span><span style="color:#cccccc;"> InjectTests: XCTestCase {
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">func </span><span style="color:#cccccc;">testFeeding() {
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">let</span><span style="color:#cccccc;"> farm </span><span>=</span><span style="color:#cccccc;"> Farm(animals: [TestAnimal()])
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">let</span><span style="color:#cccccc;"> result </span><span>=</span><span style="color:#cccccc;"> farm</span><span>.</span><span style="color:#cccccc;">feedAnimals()
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;"> XCTAssertEqual(result, [</span><span style="color:#ffd700;">"This is not an actual animal, it's just a test"</span><span style="color:#cccccc;">])
</span><span style="color:#cccccc;"> }
</span><span style="color:#cccccc;">
</span><span style="color:#cccccc;">}
</span></code></pre>
<p>And here you go, a fully contained and convenient dependency injection method, that works without the need of any framework, objective-c code, var's (instead of lets) or dynamism (instead of static dispatch).</p>
<h1 id="project-source">Project Source<a class="zola-anchor" href="#project-source" aria-label="Anchor link for: project-source">§</a>
</h1>
<p>~I've made a simple iOS project as a proof of concept for this: download~ the project is out of date and no longer hosted</p>
Linking OpenSSL for the iOS Simulator (1.0.2a)2015-04-26T13:56:00+00:002015-04-26T13:56:00+00:00https://carlossless.io/ios-openssl-support/<h1 id="intro">Intro<a class="zola-anchor" href="#intro" aria-label="Anchor link for: intro">§</a>
</h1>
<p>I've been doing some work with a fair amount of crypto for an my upcoming application. Now as you all probably know, the go-to for doing any crypto is with <a href="https://www.openssl.org/">OpenSSL</a>. I'm not much of a hipster, so I immediately went with that.</p>
<h1 id="the-good">The Good<a class="zola-anchor" href="#the-good" aria-label="Anchor link for: the-good">§</a>
</h1>
<p><a href="https://twitter.com/x2on">x2on</a>'s <a href="https://github.com/x2on/OpenSSL-for-iPhone">OpenSSL-for-iPhone</a> is an excellent tool of convenience. It downloads the latest version of OpenSSL, builds both libssl and libcrypto for all available architectures and glues all slices into one universal library each. It even comes with a script to generate <code>openssl.framework</code> from the resulting libraries.</p>
<h1 id="the-bad">The Bad<a class="zola-anchor" href="#the-bad" aria-label="Anchor link for: the-bad">§</a>
</h1>
<p>The resulting framework runs great on any device, sadly, the linker just didn't want to link for the simulator. The linker spewing:</p>
<pre style="background-color:#191919;color:#ffffff;"><code><span>Undefined symbols for architecture x86_64:
</span><span> "_OPENSSL_ia32cap_P", referenced from:
</span><span> _AES_cbc_encrypt in openssl(aes-x86_64.o)
</span><span>ld: symbol(s) not found for architecture x86_64
</span><span>clang: error: linker command failed with exit code 1 (use -v to see invocation)
</span></code></pre>
<p>I was at a complete loss, as I hadn't referenced anything of the like. In my code at least. But a bit more digging revealed the culprit.</p>
<h1 id="and-the-de-uglyfied">And the de-uglyfied<a class="zola-anchor" href="#and-the-de-uglyfied" aria-label="Anchor link for: and-the-de-uglyfied">§</a>
</h1>
<p>It turns out this is a bug in the generated code for x86_84. The linker doesn't know that the <a href="https://github.com/openssl/openssl/blob/master/crypto/aes/asm/aes-x86_64.pl#L1651">_OPENSSL_ia32cap_P</a> external symbol needs to be linked in from <a href="https://github.com/openssl/openssl/blob/e0fc7961c4fbd27577fb519d9aea2dc788742715/crypto/x86_64cpuid.pl#L26">x86_64cpuid.o</a>.</p>
<p>We can force this by referencing another method that's in <code>x86_64cpuid.o</code>, like <code>OPENSSL_cleanse(void *, size_t)</code>. I did like so:</p>
<pre data-lang="m" style="background-color:#191919;color:#ffffff;" class="language-m "><code class="language-m" data-lang="m"><span style="color:#80d500;">#if</span><span style="color:#cccccc;"> TARGET_IPHONE_SIMULATOR
</span><span style="color:#cccccc;"> </span><span style="background-color:#171717;color:#616161;">// this is just so openssl links properly.
</span><span style="color:#cccccc;"> </span><span style="color:#80d500;">extern int </span><span>OPENSSL_cleanse</span><span style="color:#cccccc;">(</span><span style="color:#80d500;">void </span><span>*</span><span style="font-style:italic;color:#8aa6c1;">ptr</span><span style="color:#cccccc;">, </span><span style="color:#8aa6c1;">size_t </span><span style="font-style:italic;color:#8aa6c1;">len</span><span style="color:#cccccc;">);
</span><span style="color:#cccccc;"> OPENSSL_cleanse(</span><span style="color:#80d500;">nil</span><span style="color:#cccccc;">, </span><span style="color:#eddd5a;">0</span><span style="color:#cccccc;">);
</span><span style="color:#80d500;">#endif
</span></code></pre>
<p>Pasting the following anywhere in your code (that won't be discarded by compiler optimizations) should work.</p>
<h1 id="the-end">The End?<a class="zola-anchor" href="#the-end" aria-label="Anchor link for: the-end">§</a>
</h1>
<p>I'm hoping that this will get resolved in the future. If not as a mainline release, then at least as a publicly available patch. But until then, I guess we're stuck with this.</p>