<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://oxide.computer/</id>
    <title>Oxide Computer Company Blog</title>
    <updated>2026-04-22T01:45:22.848Z</updated>
    <generator>Remix using Feed for Node.js</generator>
    <author>
        <name>Oxide Computer Company</name>
        <email>info@oxide.computer</email>
        <uri>https://oxide.computer</uri>
    </author>
    <link rel="alternate" href="https://oxide.computer/"/>
    <link rel="self" href="https://oxide.computer/blog/feed"/>
    <subtitle>The cloud you own</subtitle>
    <logo>https://oxide.computer/favicon-large.png</logo>
    <icon>https://oxide.computer/favicon-large.png</icon>
    <rights>Copyright © 2026 Oxide Computer Company</rights>
    <entry>
        <title type="html"><![CDATA[Our $200M Series C]]></title>
        <id>https://oxide.computer/blog/our-200m-series-c</id>
        <link href="https://oxide.computer/blog/our-200m-series-c"/>
        <link rel="enclosure" href="https://oxide.computer/img/blog/series-c/series-c-announcement-thumbnail.svg" type="image/svg"/>
        <updated>2026-02-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Raising our Series C round of financing]]></summary>
        <content type="html"><![CDATA[<link rel="preload" as="image" href="/img/blog/series-c/oxide-pitch-2019.svg"/><div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>We have raised a $200M Series C, and yes, you are permitted a double take:
didn&#8217;t we <em>just</em> raise a
<a href="https://oxide.computer/blog/our-100m-series-b">$100M Series B</a>?
And aren&#8217;t we the ones that are especially candid about the
<a href="https://www.youtube.com/watch?v=8ZgfTarNxdY">perils of raising too much money</a>?</p></div><div class="paragraph"><p>Well, yes, on both fronts, so let us explain a little.</p></div><div class="paragraph"><p>First, we have the luxury of having achieved real product-market fit:  we are
making <a href="https://oxide.computer/">a product</a> that people want to buy.  This takes
on additional dimensions when making something physical: with complexities like
manufacturing, inventory, cash-conversion, and shifting supply chains,
product-market fit implies getting the unit economics of the business right.
All of this is a long way of saying: we did not (and do not) need to raise
capital to support the business.</p></div><div class="paragraph"><p>So if we didn&#8217;t need to raise, why seek the capital?  Well, we weren&#8217;t seeking
it, really.  But our
investors, seeing the business take off, were eager to support it.  And we, in
turn, were eager to have them:  they were the ones, after all, who joined us in
taking a real leap when it felt like there was a lot more risk on the table.
They understood our vision for the company and shared our love for customers
and our desire to build a singular team.  They had been with us in some
difficult moments; they know and trust us, as do we them.  So being able to raise
a Series C purely from our existing investors presented a real opportunity.</p></div><div class="paragraph"><p>Still, even from investors that we trust and with a quick close, if the business
doesn&#8217;t need the money, does it make sense to raise?  We have always believed
that our biggest challenge at Oxide was time&#8201;&#8212;&#8201;and therefore capital.  We
spelled this out in our initial pitch deck from 2019:</p></div><div class="imageblock   "><div class="content"><img src="/img/blog/series-c/oxide-pitch-2019.svg" alt="Oxide pitch deck"/></div><div class="title">Challenges slide from Oxide original pitch deck ca. 2019</div></div><div class="paragraph"><p>Six years later, we stand by this, which is not to minimize any of those
challenges: the technical challenges were indeed hard; we feel fortunate to have
attracted an extraordinary team; and we certainly caught some
<a href="https://www.networkworld.com/article/4053783/broadcoms-vmware-strategy-pays-off-financially-but-customers-not-as-keen-as-wall-street.html">lucky breaks</a>
with respect to the market.  With this large Series C, we have entirely
de-risked capital going forward, which in turn assures our independence.</p></div><div class="paragraph"><p>This last bit is really important, because any buyer of infrastructure has
had their heart broken countless times by promising startups that succumbed to
acquisition by one of the established players that they were seeking to
disrupt.  The serial disappointments leave a refreshing bluntness in their
wake, and it&#8217;s not uncommon for us to be asked directly: "How do I know you
won&#8217;t be bought?"</p></div><div class="paragraph"><p>Our intent in starting Oxide was not to be an
acquisition target but rather build a generational company; this is our life&#8217;s
work, not a means to an end.  With our Series C, customers
don&#8217;t have to merely take our word for it:  we have the capital to assure our
survival into the indefinite future.  If our Series B left us with confidence
in achieving <a href="https://rfd.shared.oxide.computer/rfd/0002">our mission</a>, our
Series C leaves us with certainty: we&#8217;re going to kick butt, have fun, not
cheat (of course!), love our customers&#8201;&#8212;&#8201;and <strong>change computing forever</strong>.</p></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <author>
            <name>Steve Tuck</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
        <contributor>
            <name>Steve Tuck</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[A disappearing Service Processor]]></title>
        <id>https://oxide.computer/blog/cosmo-sp</id>
        <link href="https://oxide.computer/blog/cosmo-sp"/>
        <updated>2025-12-11T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[A disappearing Service Processor]]></summary>
        <content type="html"><![CDATA[<link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fcosmo_sp%2Fcosmo%2Bdebug.jpg&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fcosmo_sp%2Fcosmo%2Bdebug.jpg&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fcosmo_sp%2Fcosmo%2Bdebug.jpg&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>One of the considerations in designing our Oxide rack is asking which parts we
expect to be accessible and by what means. The Oxide rack is designed to live
in a data center with exclusive access via the network. The only reason an
engineer should ever need to physically visit a rack is to replace a failing
part, such as a disk. Our <a href="https://docs.oxide.computer/guides/architecture/service-processors">Service Processor (SP)</a> is accessible via the <a href="https://docs.oxide.computer/guides/architecture/networking#_management_network">management network</a>.</p></div><div class="paragraph"><p>During some of our first attempts at putting our next generation Cosmo sled
into an Oxide rack, we would see the Service Processor drop off the network.
This is a tricky situation to debug, as without network access we have limited
insight into the state of the SP itself. Debugging started based on the state
of the rest of the system (<a href="https://github.com/oxidecomputer/hubris/issues/2157">original Hubris bug</a> may contains spoilers for the blog post!):</p></div><div class="ulist"><ul class=""><li><p>The AMD host CPU was still alive, meaning the full system itself still had power</p></li><li><p>The SP itself was not broadcasting over the management network that it was alive</p></li><li><p>There were no increases in network data counters coming from the SP</p></li><li><p>The fans were spinning at a constant elevated rate. The service processor is
responsible for fan control, so this was an indication the fan controller may
have fallen back to emergency full power mode.</p></li><li><p>This was not reproducible on a sled outside a rack</p></li></ul></div><div class="paragraph"><p>The Service Processor runs our custom operating system, <a href="https://github.com/oxidecomputer/hubris">Hubris</a>. Each portion of the system (networking, thermal
control, update etc.) is written as a separate <a href="https://hubris.oxide.computer/reference/#tasks"><strong>task</strong></a>. Hubris is not a true Real
Time Operating System with deadline guarantees, but it does have the notion of
task priorities. One of our working theories was that we had a software bug
that was causing task starvation. If the networking task was unable to run due
to some other task eating up all the CPU time, it would not be able to respond
over the network. A likely culprit of task starvation could be a task that had
gotten into an infinite crash loop, with all CPU time being spent restarting the
task. We adjusted the task restart time to have a longer delay to catch this
case. We also wanted to be able to observe if the SP was still making progress
even if we lacked networking access, and so switched our chassis LED from
"always on" to blinking.</p></div><div class="paragraph"><p>We were fortunate to be able to reproduce the issue with these debug changes, but the
results were still confusing: in some cases we would see the LED stuck on, and
in other cases the LED was stuck off. The task responsible for LED blinking was
near the top of priorities, which limited the number of places we could have a
stuck task.</p></div><div class="paragraph"><p>One of the many advantages of writing Hubris in Rust is eliminating
bug classes such as buffer overflows. A category of issues Hubris is
still particularly prone to is stack overflows. This is because Hubris
requires manual sizing of stacks for tasks and calculating maximum stack
size has proven tricky. Our ability to detect undersized stacks has
improved with the addition of <a href="https://doc.rust-lang.org/beta/unstable-book/compiler-flags/emit-stack-sizes.html"><code>emit-stack-sizes</code> feature</a>
but we can still hit some edge cases.
When a stack overflow occurs, the task safely restarts. A stack overflow in
the kernel would potentially produce similar behavior of a system that looks
like it isn&#8217;t making progress. Unfortunately for us the stack margins on the
kernel were relatively large (512 bytes!) so this was an unlikely case.</p></div><div class="paragraph"><p>At this point, we really needed to get more debugging information out of the
system. For manufacturing purposes, we have SWD debug headers. These are not
expected to be used on a production system and <em>especially</em> not a system in a
running rack. We had to do some creative cable pulling to get them attached
with the assistance of coworkers in the Oxide office.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fcosmo_sp%2Fcosmo%2Bdebug.jpg&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fcosmo_sp%2Fcosmo%2Bdebug.jpg&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fcosmo_sp%2Fcosmo%2Bdebug.jpg&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fcosmo_sp%2Fcosmo%2Bdebug.jpg&amp;w=1440&amp;q=90" alt="a Cosmo sled with a debug probe precariously placed"/></div></div><div class="paragraph"><p>Fortunately, our cable attachment paid dividends: we reproduced the issue with
the probe attached! This was not immediately fruitful: the debug probe was
unable to actually halt the CPU via debug halt, which limited our ability to
extract diagnostic information. Our Service Processor uses a <a href="https://www.st.com/en/microcontrollers-microprocessors/stm32h7-series.html">Cortex-M7 STM32H7</a>,
and the number of ways to put the system in such a state is limited.</p></div><div class="paragraph"><p>This put our focus on identifying what parts of the system could cause such
behavior. A major
change from our first generation Gimlet system was the addition of an FPGA to
control more parts of our system such as host flash.
This FPGA is connected using a simple, old-school parallel bus, like the sort
you might use for RAM, and accessed via the STM32H7 Flexible Memory Controller.
As stated in the manual (Section 22.1 RM0433):</p></div><div class="listingblock"><div class="content"><pre class="highlight !block">Its main purposes are:
* to translate AXI transactions into the appropriate external device protocol
* to meet the access time requirements of the external memory devices</pre></div></div><div class="paragraph"><p>One way a CPU can potentially get stuck is if it never receives a bus
acknowledgement from an external device. A bug in the FPGA timing, for example,
could result in the CPU hanging forever when attempting to read a register.
To test this theory, we created an FPGA test image with a register that when
read would intentionally hang the FMC bus. This produced very similar behavior
to what we observed and was a strong indicator we were looking at the right
part of the system to find the issue.</p></div><div class="paragraph"><p>We typically rely on full system dumps to debug Hubris problems. This is not
possible unless we can halt the CPU. ARM CPUs do support <a href="https://developer.arm.com/documentation/ddi0406/c/Debug-Architecture/Debug-Events/Vector-catch-debug-events?lang=en"><strong>vector catch</strong></a> though:
it&#8217;s possible to configure the CPU so that on reset, it halts before executing the first instruction. Our
hope was that a vector catch reset would unstick the CPU sufficiently without
trampling over our existing state. This did work. We lost the running register
state with the program counter but the rest of the Hubris state in RAM was
preserved across reset and looked reasonably consistent. We could see what
Hubris task was running, but nothing there looked like it was accessing the FMC.</p></div><div class="paragraph"><p>Our hardware engineers did a review of FPGA timings and did find that we might
not have been meeting timing constraints required by the memory interface.
We merged the fix and figured that the vector
catch dumps were just inconsistent, most likely due to the cache. When we
ran experiments to turn off the cache the dumps were consistent but we never
reproduced the actual issue.</p></div><div class="paragraph"><p>We continued hubris development as usual over the next several weeks. One
of the changes we worked on during this period was related to our
measured boot work. Our Root of Trust (RoT) is responsible for taking
a hash of the SP flash at bootup which eventually gets used by higher
level software. To acheive the security properties we need, the SP may
reset itself multiple times in a row at first bootup. While testing
this change, we saw the same symptoms come back: the Cosmo SP would disappear
from the network and appear dead. This change turned out to be incredibly good
at reproducing the issue, turning a potentially 24+ hour reproduction rate
to approximately 10-20 minutes. The initial dumps still didn&#8217;t show a significant smoking gun,
but we were still highly suspicious of the FMC bus since there were still
limited cases that could produce such symptoms.</p></div><div class="paragraph"><p>The high reproduction rate gave us a chance to try many experiments, none of
which were fruitful:</p></div><div class="ulist"><ul class=""><li><p>Adjusting the rate at which we reset and the number of resets before normally booting</p></li><li><p>Clearing the FPGA bit stream an extra time</p></li><li><p>Restricting tasks from accessing the FMC bus</p></li><li><p>Removing whole tasks that seemed to be unrelated</p></li></ul></div><div class="paragraph"><p>Finally, staring at the STM32H7 manual provided an insight: maybe the processor
itself was performing accesses on the FMC bus that we weren&#8217;t expecting!
Modern processors hold a large amount of internal state that isn&#8217;t directly
visible to the programmer. It is not possible for a programmer to know when
a CPU will pull data into or out of the cache outside of certain
synchronization points or cache instructions. A CPU writing data from the
cache to memory is considered a memory access so it&#8217;s possible for the CPU
to be making memory accesses to addresses unrelated to the current program
counter.</p></div><div class="paragraph"><p>Hubris utilizes the Memory Protection Unit (MPU) to provide isolation between
tasks and enforce privilege levels. Our configuration uses the MPU for the
unprivileged tasks but uses the default memory map for the (privileged) kernel.
In the tasks, the FMC is mapped as Uncached Device Memory. Based on our reading
of the STM32H7 manual, it turned out our chosen base address for the FMC bus
had a default memory type of Normal Cached. This means the FMC has different
attributes depending on whether it&#8217;s being accessed from a task or the kernel.</p></div><div class="paragraph"><p>Section A3.5.7 of the ARMv7-m reference manual has an entire section about
mismatched memory attributes and what properties are lost in this situation.
Based on discussion with our hardware engineers, the line "Preservation of the
size of accesses" was the most suspicious. Our FPGA interface was designed for
32-bit accesses, and 16-bit or 8-bit accesses could potentially cause problems.</p></div><div class="paragraph"><p>It&#8217;s important to note that the kernel was never <strong>intentionally</strong> accessing the
FMC through the Normal Cached mapping. The most likely scenario was:</p></div><div class="ulist"><ul class=""><li><p>The CPU running an unprivileged task accessing the FMC issues a store that makes it to the processor&#8217;s store buffer</p></li><li><p>An interrupt occurs, switching us into privileged mode which uses the default memory map</p></li><li><p>The store hits the cache because the default memory map said that address is cached</p></li><li><p>The cache attempted to write to memory in ways outside the expected Device Memory attributes</p></li></ul></div><div class="paragraph"><p>One of the last lines of section A3.5.7 is "Arm strongly recommends that
software does not use mismatched attributes for aliases of the same location."
The default ARM memory map (which the kernel relies on) assigns different
attributes to different sections of the address space, and one of the
sections is set up the way we want: device memory, no caching. It turns
out the STM32H7 FMC supports changing its base address to appear in this
section of address space, likely to avoid the specific problem we were facing.
The final fix was changing the base address to the section with
matching attributes. We&#8217;ve seen no instances of this issue since that fix was merged.</p></div><div class="paragraph"><p><a href="https://rfd.shared.oxide.computer/rfd/0552">Transparency</a> continues to be an Oxide value. Debugging modern CPUs often
involves diving into areas with little transparency. "Under what circumstances
will you be unable to access your memory bus" is a tricky question to answer.
Our debugging efforts this time were aided by documentation from ARM and STM
that eventually explained our problem. Given the difficulty in debugging this
issue, highlighting this potential problem in vendor documentation would be
beneficial to all customers. Oxide hopes all hardware vendors continue to
document as much of their part as possible for the benefit of their customers.</p></div></div>]]></content>
        <author>
            <name>Laura Abbott</name>
        </author>
        <contributor>
            <name>Laura Abbott</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Systems Software in the Large]]></title>
        <id>https://oxide.computer/blog/systems-software-in-the-large</id>
        <link href="https://oxide.computer/blog/systems-software-in-the-large"/>
        <updated>2025-09-18T13:00:00.000Z</updated>
        <summary type="html"><![CDATA[An extraordinary talk on developing systems software in the large]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>Software is hard (yes, even in an era of
<a href="https://www.pcmag.com/news/vibe-coding-fiasco-replite-ai-agent-goes-rogue-deletes-company-database">vibe
coding</a>), and systems software&#8201;&#8212;&#8201;the silent engine room of modern
infrastructure&#8201;&#8212;&#8201;is especially so.  By design, systems software provides an
abstraction for programs, insulating programmers from the filthy details that
lie beneath; piercing that abstraction to implement the underlying system is
to embrace those details and their gnarly implications.  Moreover, the
expectation for systems software is (rightly) perfection; a system that is
merely functional can be deceptively distant from the robustness required of
foundational software.  Systems software isn&#8217;t the only kind of hard software,
of course, and indeed software can be difficult just by nature of its scope
and composition:  it is hard to build software that is just&#8230;&#8203; big.  Software
that consists of many different modules and components built by multiple
people over an extended period of time is known as
<a href="https://en.wikipedia.org/wiki/Programming_in_the_large_and_programming_in_the_small#Programming_in_the_large">programming
in the large</a>, and its difficulties extend beyond the mere implementation
challenges of systems software.</p></div><div class="paragraph"><p>Because the difficulties with developing systems software are broadly
orthogonal to those of programming in the large, intersecting these two
challenges&#8201;&#8212;&#8201;that is, developing systems software in the large&#8201;&#8212;&#8201;is to take
on the most grueling of projects: it is the stuff of which
<a href="https://en.wikipedia.org/wiki/The_Mythical_Man-Month">mythical man months</a> are
literally made.  Why would anyone ever develop such a system?  Because they
are often necessary to tackle software&#8217;s equivalents of the
<a href="https://en.wikipedia.org/wiki/Wicked_problem">wicked problem</a>: problems that
are not only never completely solved, but also not even really understood
until implementation is well underway.  There are not pat answers for
developing these systems&#8201;&#8212;&#8201;nor, infamously,
<a href="https://oxide-and-friends.transistor.fm/episodes/no-silver-bullets">silver
bullets</a>&#8201;&#8212;&#8201;they&#8217;re just&#8230;&#8203;  brutal.</p></div><div class="paragraph"><p>This is on my mind because of a talk that we had at OxCon last week.  OxCon is
our affectionate name for the annual Oxide meetup here in Emeryville, and it&#8217;s
a highlight of the year for everyone at Oxide.  This year more than lived up
to our high expectations, replete with cameos from the extraordinary
<a href="https://www.youtube.com/watch?v=2_A_PfLSYOM">IBM 26 Interpreting Card Punch</a>
and <a href="https://bsky.app/profile/bcantrill.bsky.social/post/3lymmhpuoek2s">the
Oakland Ballers</a>.  At OxCon we like to both reflect back and look forward, so
in that spirit, we asked Oxide engineer Dave Pacheco if he might be willing to
present on the project he&#8217;s been leading the charge on for the past two years:
software update.</p></div><div class="paragraph"><p>When we shipped the first Oxide rack two years ago, it had the minimum
functionality necessary to update all its software in the field.  Our priority
was to make this update mechanism robust over all else, and we succeeded in
the sense that it is indeed robust&#8201;&#8212;&#8201;but the experience is not yet
the seamless, self-service facility that we have envisioned.  Software
update for the Oxide rack is exactly the kind of wicked problem that
necessitates systems software in the large: it is not merely dynamically
overhauling a distributed system, but doing so while remaining operable in the
liminal state between the old software and the new.  Compounding this was the
urgency we felt:  delivering self-service update is essential to realize our
vision of the cloud experience on premises, and our customers needed it as
soon as we could deliver it.  As if this weren&#8217;t enough, the Oxide update
problem has an acute constraint not faced by the public clouds:  we need to be
able to deliver updates across an
<a href="https://en.wikipedia.org/wiki/Air_gap_(networking)">air gap</a>&#8201;&#8212;&#8201;we cannot rely
on the public cloud&#8217;s hidden crutch of operators and runbooks.  It is a
problem so wicked, you can practically hear it cackle.</p></div><div class="paragraph"><p>Despite the thorniness of the problem, Dave and team had managed to achieve the
ambitious milestones that they had set for themselves at OxCon last year, and I
was naturally excited for his presentation this year.  That said, I wasn&#8217;t
ready for what was coming:  Dave not only described the tremendous work on
software update (delving into both the multi-year history of the project and
the significant progress since the last OxCon), but also reflected on leading
the software update project itself.  The result was an absolutely extraordinary
talk, not just on the mechanics of software essential to Oxide, but on the
unique challenges of systems software in the large.</p></div><div class="paragraph"><p>Dave&#8217;s talk dripped with hard-won wisdom, running the gamut from maintaining
focus (and the looming specter of what Dave calls "organizational
procrastination") to fighting scope creep and the mechanics of specific
technical decisions.  We felt Dave&#8217;s talk to be too good to be kept to
ourselves&#8201;&#8212;&#8201;and thanks to our transparency, nothing in it needs to be secret;
we are thrilled to be able to make it generally available:</p></div><div class="youtube-embed">
  <iframe width="560" height="315" src="https://www.youtube.com/embed/M-ZLz8Wg34s" title="Update on Update" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen=""></iframe>
</div><div class="paragraph"><p>This talk is a <strong>must watch</strong> for anyone doing systems software in the large,
containing within it the kind of lessons that are often only
<a href="https://speakerdeck.com/bcantrill/things-i-learned-the-hard-way">learned the
hard way</a>.  While we think it&#8217;s valuable for everyone, should you be the kind
of sicko inexplicably drawn to exactly the kind of nasty problems that Dave
describes, consider <a href="/careers/sw-control-plane">joining us</a>&#8201;&#8212;&#8201;there is more
systems software in the large to be done at Oxide!</p></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Our $100M Series B]]></title>
        <id>https://oxide.computer/blog/our-100m-series-b</id>
        <link href="https://oxide.computer/blog/our-100m-series-b"/>
        <link rel="enclosure" href="https://oxide.computer/img/blog/series-b/series-b-announcement-thumbnail.svg" type="image/svg"/>
        <updated>2025-07-30T13:00:00.000Z</updated>
        <summary type="html"><![CDATA[Raising our Series B round of financing]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>We don&#8217;t want to bury the lede:  we have raised a $100M Series B, led by a new
strategic partner in <a href="https://usitfund.com/">USIT</a> with participation from all
existing Oxide investors.  To put that number in perspective: over the nearly
six year lifetime of the company, we have raised $89M; our $100M Series B more
than doubles our total capital raised to date&#8201;&#8212;&#8201;and positions us to make
Oxide the generational company that we have always aspired it to be.</p></div><div class="paragraph"><p>If this aspiration seems heady now, it seemed absolutely outlandish when we
were first raising venture capital in 2019.  Our thesis was that cloud
computing was the future of all computing; that running on-premises would
remain (or become!) strategically important for many; that the entire stack&#8201;&#8212;&#8201;hardware <em>and</em> software&#8201;&#8212;&#8201;needed to be rethought from first principles to
serve this market; and that a large, durable, public company could be built by
whomever pulled it off.</p></div><div class="paragraph"><p>This scope wasn&#8217;t immediately clear to all potential investors, some of whom
seemed to latch on to one aspect or another without understanding the whole.
Their objections were revealing: "We know you can build this," began more than
one venture capitalist (at which we bit our tongue; were we not properly
explaining what we intended to build?!), "but we don&#8217;t think that there is a
market."</p></div><div class="paragraph"><p>Entrepreneurs must become accustomed to rejection, but this flavor was
particularly frustrating because it was exactly backwards: we felt that there
was in fact substantial technical risk in the enormity of the task we put
before ourselves&#8201;&#8212;&#8201;but we also knew that if we <strong>could</strong> build it (a huge if!)
there was a huge market, desperate for cloud computing on-premises.</p></div><div class="paragraph"><p>Fortunately, in <a href="https://eclipse.capital/">Eclipse Ventures</a> we found investors
who <a href="https://oxide-and-friends.transistor.fm/episodes/deep-tech-investing">saw
what we saw</a>:  that the most important products come when we co-design
hardware and software together, and that the on-premises market was sick of
being told that they either don&#8217;t exist or that they don&#8217;t deserve modernity.
These bold investors&#8201;&#8212;&#8201;like the customers we sought to serve&#8201;&#8212;&#8201;had been
waiting for this company to come along; we raised seed capital, and started
building.</p></div><div class="paragraph"><p>And build it we did, making good on our
<a href="https://www.youtube.com/watch?v=vvZA9n3e5pc">initial technical vision</a>:</p></div><div class="ulist"><ul class=""><li><p>We did
<a href="https://oxide-and-friends.transistor.fm/episodes/the-power-of-proto-boards">our
own board designs</a>, allowing for essential system foundation like a true
<a href="https://oxide.computer/blog/lpc55s69-tzpreset">hardware root-of-trust</a> and
<a href="https://oxide.computer/blog/how-oxide-cuts-data-center-power-consumption-in-half">end-to-end
power observability</a>.</p></li><li><p>We did
<a href="https://oxide.computer/blog/hubris-and-humility">our own microcontroller
operating system</a>, and used it to
<a href="https://www.linkedin.com/posts/oxidecomputer_is-the-oxide-service-processor-a-bmc-faq-activity-7346915711233007617-s9Az">replace the traditional BMC</a>.</p></li><li><p>We did
<a href="https://rfd.shared.oxide.computer/rfd/0241">our own platform enablement
software</a>, eliminating the traditional UEFI BIOS and its accompanying
<a href="https://arstechnica.com/security/2024/01/new-uefi-vulnerabilities-send-firmware-devs-across-an-entire-ecosystem-scrambling/">flotilla
of vulnerabilities</a>.</p></li><li><p>We did
<a href="https://rfd.shared.oxide.computer/rfd/0026">our own host hypervisor</a>, assuring
an integrated and seamless user experience&#8201;&#8212;&#8201;and eliminating the need for a
third-party hypervisor and its concomitant
<a href="https://oxide.computer/blog/moores-scofflaws">rapacious software licensing</a>.</p></li><li><p>We did
<a href="https://rfd.shared.oxide.computer/rfd/0058">our own switch</a>&#8201;&#8212;&#8201;and
<a href="https://github.com/oxidecomputer/dendrite">our own switch runtime</a>&#8201;&#8212;&#8201;eliminating entire universes of integration complexity and operational
nightmares.</p></li><li><p>We did
<a href="https://rfd.shared.oxide.computer/rfd/0177">our own integrated storage
service</a>, allowing the rack-scale system to have reliable, available, durable,
elastic instance storage without necessitating a dependency on a third party.</p></li><li><p>We did
<a href="https://github.com/oxidecomputer/omicron/blob/main/docs/control-plane-architecture.adoc">our
own control plane</a>, a sophisticated distributed system building on the
foundation of our hardware and software components to deliver the API-driven
services that modernity demands: elastic compute, virtual networking, and
virtual storage.</p></li></ul></div><div class="paragraph"><p>While these technological components are each very important (and each
is in service to specific customer problems when deploying infrastructure
on-premises), the objective
is the product, not its parts.  The journey to a product was long, but we ticked
off the milestones.
We got the boards brought up.
We got the switch transiting packets.
We got the control plane working.
We got the rack manufactured.
We passed FCC compliance.</p></div><div class="paragraph"><p>And finally, two years ago, we shipped our first system!</p></div><div class="paragraph"><p>Shortly thereafter, more milestones of the variety you can only get after
shipping:  our first update of the software in the field; our first
update-delivered performance improvements; our first customer-requested
features added as part of an update.</p></div><div class="paragraph"><p>Later that year, we hit
<a href="https://oxide.computer/blog/the-cloud-computer">general
commercial availability</a>, and things started accelerating.  We had more
customers&#8201;&#8212;&#8201;and our first multi-rack customer.  We had
<a href="https://www.theregister.com/2024/11/18/llnl_oxide_compute/">customers go on the
record about why they had selected Oxide</a>&#8201;&#8212;&#8201;and
<a href="https://www.suse.com/success/switch/">customers describing the wins that they
had seen deploying Oxide</a>.</p></div><div class="paragraph"><p>Customers started landing faster now: enterprise sales cycles are infamously
long, but we were finding that we were going from first conversations to a
delivered product surprisingly quickly.  The quickening pace always seemed to
be due in some way to our transparency:  new customers were listeners to
<a href="https://oxide-and-friends.transistor.fm">our podcast</a>, or they had read
<a href="https://rfd.shared.oxide.computer/">our RFDs</a>, or they had perused
<a href="https://docs.oxide.computer/">our documentation</a>, or they had looked at
<a href="https://github.com/oxidecomputer">the source code itself</a>.</p></div><div class="paragraph"><p>With growing customer enthusiasm, we were increasingly getting questions
about what it would look like to buy a large number of Oxide racks.  Could we
manufacture them?  Could we support them?  Could we make them easy to
operate together?</p></div><div class="paragraph"><p>Into this excitement, a new potential investor, USIT, got to know us.  They
asked terrific questions, and we found a shared disposition towards building
lasting value and doing it the right way.  We learned more about them, too,
and especially USIT&#8217;s founder,
<a href="https://fs.blog/knowledge-project-podcast/thomas-tull/">Thomas Tull</a>.  The more
we each learned about the other, the more there was to like.  And importantly,
USIT had the vision for us that we had for ourselves:  that there was a big,
important market here&#8201;&#8212;&#8201;and that it was uniquely served by Oxide.</p></div><div class="paragraph"><p>We are elated to announce this new, exciting phase of the company.  It&#8217;s not
necessarily in our nature to celebrate fundraising, but this is a big
milestone, because it will allow us to address our customers' most pressing
questions around scale (manufacturing scale, system scale, operations scale)
and roadmap scope.  We have always believed in
<a href="https://rfd.shared.oxide.computer/rfd/0002">our mission</a>, but this raise gives
us a new sense of confidence when we say it: we&#8217;re going to kick butt, have
fun, not cheat (of course!), love our customers&#8201;&#8212;&#8201;and <strong>change computing
forever</strong>.</p></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <author>
            <name>Steve Tuck</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
        <contributor>
            <name>Steve Tuck</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxide’s Compensation Model: How is it Going?]]></title>
        <id>https://oxide.computer/blog/oxides-compensation-model-how-is-it-going</id>
        <link href="https://oxide.computer/blog/oxides-compensation-model-how-is-it-going"/>
        <updated>2025-05-01T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Reflecting on how our compensation model is going]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_how_it_started" aria-hidden="true"></span><a class="link group" href="#_how_it_started">How it started<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Four years ago, we were struggling to hire. Our team was small (~23
employees), and we knew that we needed many more people to execute on our
<a href="https://www.youtube.com/watch?v=ikn7ovpjdIg">audacious vision</a>.  While we had
had success hiring in our personal networks, those networks now felt tapped;
we needed to get further afield.  As is our wont, we got together as a team
and brainstormed: how could we get a bigger and broader applicant pool?  One
of our engineers, Sean, shared some personal experience: that
<a href="https://oxide.computer/principles">Oxide&#8217;s principles and values</a> were very
personally important to him&#8201;&#8212;&#8201;but that when he explained them to people
unfamiliar with the company, they were (understandably?) dismissed as
corporate claptrap.  Sean had found, however, that there was one surefire way
to cut through the skepticism:  to explain our approach to compensation.
Maybe, Sean wondered, we should talk about it publicly?</p></div><div class="paragraph"><p>"I could certainly write a blog entry explaining it," I offered.  At this
suggestion, the team practically lunged with enthusiasm: the reaction was so
uniformly positive that I have to assume that everyone was sick of explaining
this most idiosyncratic aspect of Oxide to friends and family.  So what was
the big deal about our compensation?  Well, as a I wrote in the resulting
piece,
<a href="https://oxide.computer/blog/compensation-as-a-reflection-of-values">Compensation
as a Reflection of Values</a>, our compensation is not merely transparent, but
uniform.  The piece&#8201;&#8212;&#8201;unsurprisingly, given the evergreen hot topic that is
compensation&#8201;&#8212;&#8201;got a ton of attention.  While some of that attention was
negative (despite the piece trying to frontrun every HN hater!), much of it was
positive&#8201;&#8212;&#8201;and everyone seemed to be at least intrigued.</p></div><div class="paragraph"><p>And in terms of its initial purpose, the piece succeeded beyond our wildest
imagination: it brought a surge of new folks interested in the company.  Best
of all, the people new to Oxide were interested for all of the right reasons:
not the compensation <em>per se</em>, but for the values that the compensation
represents.  The deeper they dug, the more they found to like&#8201;&#8212;&#8201;and many who
learned about Oxide for the first time through that blog entry we now count as
long-time, cherished colleagues.</p></div><div class="paragraph"><p>That blog entry was a long time ago now, and today we have ~75 employees
(and a <a href="https://oxide.computer/blog/the-cloud-computer">shipping product</a>!);
how is our compensation model working out for us?</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_how_its_going" aria-hidden="true"></span><a class="link group" href="#_how_its_going">How it’s going<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Before we get into our deeper findings, two updates that are so important that
we have updated the blog entry itself.  First, the dollar figure itself
continues to increase over time (now at $250,000);
things definitely haven&#8217;t gotten (and aren&#8217;t
getting!) any cheaper.  And second, we <em>did</em> introduce variable compensation for
some sales roles.  Yes, those roles can make more than the rest of us&#8201;&#8212;&#8201;but
they can also make less, too.  And, importantly:  if/when those folks are
making more than the rest of us, it&#8217;s because they&#8217;re selling a lot&#8201;&#8212;&#8201;a
result that can be celebrated by everyone!</p></div><div class="paragraph"><p>Those critical updates out of the way, how is it working?  There have been a
lot of surprises along the way, mostly (all?) of the positive variety.  A
couple of things that we have learned:</p></div><div class="paragraph"><p><strong>People take their own performance really seriously.</strong>  When some outsiders
hear about our compensation model, they insist that it can&#8217;t possibly work
because "everyone will slack off." I have come to find this concern to be more
revealing of the person making the objection than of our model, as our
experience has been in fact the opposite: in my one-on-one conversations with
team members, a frequent subject of conversation is people who are concerned
that they aren&#8217;t doing enough (or that they aren&#8217;t doing the right thing, or
that their work is progressing slower than they would like).  I find my job is
often to help quiet this inner critic while at the same time stoking what I
feel is a healthy urge:  when one holds one&#8217;s colleagues in high regard, there
is an especially strong desire to help contribute&#8201;&#8212;&#8201;to prove oneself worthy
of a superlative team.  Our model allows people to focus on their own
contribution (whatever it might be).</p></div><div class="paragraph"><p><strong>People take hiring <em>really</em> seriously.</strong>  When evaluating a peer (rather
than a subordinate), one naturally has high expectations&#8201;&#8212;&#8201;and because (in
the sense of our wages, anyway) everyone at Oxide is a peer, it shouldn&#8217;t be
surprising that folks have very high expectations for potential future
colleagues.  And because the
<a href="https://rfd.shared.oxide.computer/rfd/3">Oxide hiring process</a> is writing
intensive, it allows for candidates to be thoroughly reviewed by Oxide
employees&#8201;&#8212;&#8201;who are tough graders!  It is, bluntly, really hard to get
a job at Oxide.</p></div><div class="paragraph"><p><strong>It allows us to internalize the importance of different roles.</strong>  One of the
more incredible (and disturbingly frequent) objections I have heard is: "But
is that what you’ll pay support folks?" I continue to find this question
offensive, but I no longer find it surprising: the specific dismissal of
support roles reveals a widespread and corrosive devaluation of those closest
to customers. My rejoinder is simple: think of the best support engineers
you&#8217;ve worked with; what were they worth? Anyone who has shipped complex
systems knows these extraordinary people&#8201;&#8212;&#8201;calm under fire, deeply technical,
brilliantly resourceful, profoundly empathetic&#8201;&#8212;&#8201;are invaluable to the
business. So what if you built a team entirely of folks like that? The
response has usually been: well, sure, if you&#8217;re going to only hire <em>those</em>
folks. Yeah, we are&#8201;&#8212;&#8201;and we have!</p></div><div class="paragraph"><p><strong>It allows for fearless versatility.</strong> A bit of a corollary to the
above, but subtly different: even though we (certainly!) hire and select for
certain roles, our uniform compensation means we can in fact think primarily
in terms of <em>people</em> unconfined by those roles.  That is, we can be very fluid
about what we&#8217;re working on, without fear of how it will affect a perceived
career trajectory.  As a concrete example: we had a large customer that wanted
to put in place a program for some of the additional work they wanted to see
in the product.  The complexity of their needs required dedicated program
management resources that we couldn&#8217;t spare, and in another more static
company we would have perhaps looked to hire.  But in our case, two folks came
together&#8201;&#8212;&#8201;CJ from operations, and Izzy from support&#8201;&#8212;&#8201;and did something
together that was in some regards new to both of them (and was neither of
their putative full-time jobs!)  The result was indisputably successful:  the
customer loved the results, and two terrific people got a chance to work
closely together without worrying about who was dotted-lined to whom.</p></div><div class="paragraph"><p><strong>It has allowed us to organizationally scale.</strong> Many organizations describe
themselves as flat, and a reasonable rebuttal to this are the "shadow
hierarchies" created by the
<a href="https://en.wikipedia.org/wiki/The_Tyranny_of_Structurelessness">tyranny of
structurelessness</a>.  And indeed, if one were to read (say)
<a href="https://cdn.fastly.steamstatic.com/apps/valve/Valve_NewEmployeeHandbook.pdf">Valve&#8217;s
(in)famous handbook</a>, the autonomy seems great&#8201;&#8212;&#8201;but the stack ranking
decidedly less so, especially because the handbook is conspicuously silent on
the subject of compensation.  (Unsurprisingly,
<a href="https://www.pcgamer.com/ex-valve-employee-describes-ruthless-industry-politics/">compensation
was weaponized at Valve</a>, which descended into
<a href="https://www.wired.com/2013/07/wireduk-valve-jeri-ellsworth/">toxic
cliquishness</a>.) While we believe that autonomy <em>is</em> important to do one&#8217;s best
work, we also have a clear structure at Oxide in that Steve Tuck (Oxide
co-founder and CEO) is
in charge.  He has to be:  he is held accountable to our investors&#8201;&#8212;&#8201;and he
must have the latitude to make decisions.  Under Steve, it is true that
we <em>don&#8217;t</em> have layers of middle management.  Might we need some in the
future?  Perhaps, but what fraction of middle management in a company is
dedicated to&#8201;&#8212;&#8201;at some level&#8201;&#8212;&#8201;determining who gets what in terms of
compensation?  What happens when you eliminate that burden completely?</p></div><div class="paragraph"><p><strong>It frees us to both lead and follow.</strong> We expect that
every Oxide employee has the capacity to lead others&#8201;&#8212;&#8201;and we tap this
capacity frequently.  Of course, a company in which everyone is trying to
direct all traffic all the time would be a madhouse, so we also very much rely
on following one another too!  Just as our compensation model allows us to
internalize the values of different roles, it allows us to appreciate the
value of <strong>both</strong> leading and following, and empowers us each with the judgement
to know when to do which.  This isn&#8217;t always easy or free of ambiguity, but
this particular dimension of our versatility has been essential&#8201;&#8212;&#8201;and
our compensation model serves to encourage it.</p></div><div class="paragraph"><p><strong>It causes us to hire carefully and deliberately.</strong> Of course, one should
<em>always</em> hire carefully and deliberately, but this often isn&#8217;t the case&#8201;&#8212;&#8201;and
many a startup has been ruined by reckless expansion of headcount.  One of the
roots of this can be found in a dirty open secret of Silicon Valley middle
management: its ranks are taught to grade their career by the number of
reports in their organization.  Just as if you were to compensate software
engineers based on the number of lines of code they wrote, this results in
perverse incentives and predictable disasters&#8201;&#8212;&#8201;and any Silicon Valley vet
will have plenty of horror stories of middle management jockeying for reqs or
reorgs when they should have been focusing on product and customers.  When
you can eliminate middle management, you eliminate this incentive.  We grow
the team not because of someone&#8217;s animal urges to have the largest possible
organization, but rather because we are at a point where adding people will
allow us to better serve our market and customers.</p></div><div class="paragraph"><p><strong>It liberates feedback from compensation.</strong> Feedback is, of course, very
important:  we all want to know when and where we&#8217;re doing the right thing!
And of course, we want to know too where there is opportunity for improvement.
However, Silicon Valley has historically tied feedback so tightly to
compensation that it has ceased to even pretend to be constructive:  if it
needs to be said, performance review processes aren&#8217;t, in fact, about
improving the performance of the team, but rather quantifying and
stack-ranking that performance for purposes of compensation.  When
compensation is moved aside, there is a kind of liberation for feedback
itself:  because feedback is now entirely earnest, it can be expressed and
received thoughtfully.</p></div><div class="paragraph"><p><strong>It allows people to focus on doing the right thing.</strong>  In a world of
traditional, compensation-tied performance review, the organizational priority
is around those things that affect compensation&#8201;&#8212;&#8201;even at the expense of
activity that clearly benefits the company.  This leads to all sorts of wild
phenomena, and most technology workers will be able to tell stories of doing
things that were clearly right for the company, but having to hide it from
management that thought only narrowly in terms of their own stated KPIs and
MBOs.  By contrast, over and over (and over!) again, we have found that people
do the right thing at Oxide&#8201;&#8212;&#8201;even if (especially if?) no one is looking.
The beneficiary of that right thing?  More often than not, it&#8217;s our customers,
who have uniformly praised the team for going above and beyond.</p></div><div class="paragraph"><p><strong>It allows us to focus on the work that matters.</strong>  Relatedly, when
compensation is non-uniform, the process to figure out (and maintain) that
non-uniformity is laborious.  All of that work&#8201;&#8212;&#8201;of line workers assembling
packets explaining themselves, of managers arming themselves with those
packets to fight in the arena of organizational combat, and then of those same
packets ultimately being regurgitated back onto something called a review&#8201;&#8212;&#8201;is <em>work</em>. Assuming such a process is executed perfectly (something which I
suppose is possible in the abstract, even though I personally have never seen
it), this is work that does not in fact advance the mission of the company.
Not having variable compensation gives us all of that time and energy back to
do the <em>actual</em> work&#8201;&#8212;&#8201;the stuff that matters.</p></div><div class="paragraph"><p><strong>It has stoked an extraordinary sense of teamwork.</strong> For me personally&#8201;&#8212;&#8201;and
as <a href="https://www.youtube.com/watch?v=cAFD2bq1_tU&amp;t=2854s">I relayed on an episode
of <em>Software Misadventures</em></a>&#8201;&#8212;&#8201;the highlights of my career have been being a
part of an extraordinary team.  The currency of a team is mutual trust, and
while uniform compensation certainly isn&#8217;t the only way to achieve that trust,
boy does it ever help!  As Steve and I have told one another more times that
we can count:  we are so lucky to work on this team, with its extraordinary
depth and breadth.</p></div><div class="paragraph"><p>While our findings have been very positive, I would still reiterate what we
said four years ago:  we don&#8217;t know what the future holds, and it&#8217;s easier to
make an unwavering commitment to the transparency rather than the uniformity.
That said, the uniformity has had so many positive ramifications that the model
feels more important than ever.  We are beyond the point of this being a
curiosity; it&#8217;s been essential for building a mission-focused team taking on
a problem larger than ourselves.  So it&#8217;s not a fit for everyone&#8201;&#8212;&#8201;but if
you are seeking an extraordinary team solving hard problems in service to
customers, <a href="https://oxide.computer/careers">consider Oxide</a>!</p></div></div></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[dtrace.conf(24)]]></title>
        <id>https://oxide.computer/blog/dtrace-conf24</id>
        <link href="https://oxide.computer/blog/dtrace-conf24"/>
        <updated>2024-12-05T08:00:00.000Z</updated>
        <summary type="html"><![CDATA[A new conference and a new approach for the DTrace Olympiad!]]></summary>
        <content type="html"><![CDATA[<link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fdtrace-conf24%2Fdtrace-conf24-shirt.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fdtrace-conf24%2Fdtrace-conf24-shirt.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fdtrace-conf24%2Fdtrace-conf24-shirt.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><div id="content" class="asciidoc-body w-full"><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fdtrace-conf24%2Fdtrace-conf24-shirt.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fdtrace-conf24%2Fdtrace-conf24-shirt.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fdtrace-conf24%2Fdtrace-conf24-shirt.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fdtrace-conf24%2Fdtrace-conf24-shirt.png&amp;w=1440&amp;q=90" alt="shirt"/></div></div><div class="paragraph"><p>Sometime in late 2007, we had the idea of a DTrace conference.
Or really, more of a meetup; from the primordial e-mail I sent:</p></div><div class="quoteblock"><div class="paragraph"><p>The goal here, by the way, is not a DTrace user group, but more of a
face-to-face meeting with people actively involved in DTrace&#8201;&#8212;&#8201;either by
porting it to another system, by integrating probes into higher level
environments, by building higher-level tools on top of DTrace or by using it
heavily and/or in a critical role.  That said, we also don&#8217;t want to be
exclusionary, so our thinking is that the only true requirement for attending
is that everyone must be prepared to speak informally for 15 mins or so on
what they are doing with DTrace, any limitations that they have encountered,
and some ideas for the future.  We&#8217;re thinking that this is going to be on
the order of 15-30 people (though more would be a good problem to have&#8201;&#8212;&#8201;we&#8217;ll track it if necessary), that it will be one full day (breakfast in the
morning through drinks into the evening), and that we&#8217;re going to host it
here at our offices in San Francisco sometime in March 2008.</p></div></div><div class="paragraph"><p>This same note also included some suggested names for the gathering,
including what in hindsight seems a clear winner:
<a href="/img/blog/dtrace-conf24/bi-mon-sci-fi-con.gif">DTrace Bi-Mon-Sci-Fi-Con</a>.
As if knowing that I should leave an explanatory note to my future self as to
why this name was not selected, my past self
fortunately clarified:
"before everyone clamors for the obvious Bi-Mon-Sci-Fi-Con, you should know
that most Millennials don&#8217;t (sadly) get the reference."  (While I disagree
with the judgement of my past self, it at least indicates that at some
point I cared if anyone got the reference.)</p></div><div class="paragraph"><p>We settled on a <a href="https://illumos.org/books/dtrace/chp-anon.html#chp-anon">much more obscure reference</a>,
and had <a href="https://bcantrill.dtrace.org/2008/03/16/dtrace.conf08/">the first dtrace.conf in March 2008</a>.
Befitting the style of the time, it was an <a href="https://en.wikipedia.org/wiki/Unconference">unconference</a> (a term that may well have hit its apogee in 2008) that
you signed up to attend by
<a href="/img/blog/dtrace-conf24/wiki.jpg">editing a wiki</a>.
More surprising given the year (and thanks entirely to attendee Ben Rockwood),
it was recorded&#8201;&#8212;&#8201;though this is so long ago that
<a href="https://www.youtube.com/watch?v=FZ4Z22AGj5s#t=38s">I referred to it as video taping</a>
(and with none of the participants mic&#8217;d, I&#8217;m afraid the quality isn&#8217;t very good).
The conference, however, was terrific, viz. the reports of
<a href="https://ahl.dtrace.org/2008/05/05/dtrace-conf-post-post-mortem/">Adam</a>,
<a href="https://x86vmm.blogspot.com/2008/03/dtraceconf08.html">Keith</a> and
<a href="https://redmonk.com/sogrady/2008/03/16/dtraceconf-and-the-dumbest-guy-in-the-room/">Stephen</a> (all somehow still online nearly two decades later).
If anything, it was a little <em>too</em> good:
<a href="https://www.youtube.com/watch?v=2PU0WkMJNGU#t=4m0s">we realized that we couldn&#8217;t recreate the magic</a>, and we
demurred on making it an annual event.</p></div><div class="paragraph"><p>Years passed, and memories faded.  By 2012, it felt like we wanted to get
folks together again, now under a post-lawnmower corporate aegis in Joyent.
The resulting
<a href="https://ahl.dtrace.org/2012/04/09/dtrace-conf12-wrap-up/">dtrace.conf(12)</a> was
a success, and
the Olympiad cadence felt like the right one; we did it again four years
later at
<a href="https://bcantrill.dtrace.org/2016/07/29/dtrace-conf16-wrap-up/">dtrace.conf(16)</a>.</p></div><div class="paragraph"><p>In 2020, we came back together for
<a href="https://bcantrill.dtrace.org/2019/12/02/the-soul-of-a-new-computer-company/">a
new adventure</a>&#8201;&#8212;&#8201;and the DTrace Olympiad was
<a href="https://www.youtube.com/watch?v=IeUFzBBRilM#t=1h30m36s">not lost on Adam</a>.
Alas, dtrace.conf(20)&#8201;&#8212;&#8201;like the Olympics themselves&#8201;&#8212;&#8201;was cancelled, if
implicitly.
Unlike the Olympics, however, it was not to be rescheduled.</p></div><div class="paragraph"><p>More years passed and DTrace continued to prove its utility at Oxide;
last year when Adam and I did our
<a href="https://oxide-and-friends.transistor.fm/episodes/dtrace-at-20">"DTrace at 20" episode of
<em>Oxide and Friends</em></a>,
we vowed to hold dtrace.conf(24)&#8201;&#8212;&#8201;and a few months ago, we set our date to be December 11th.</p></div><div class="paragraph"><p>At first we assumed we would do something similar to our earlier conferences:
a one-day participant-run conference, at the Oxide office in Emeryville.
But times have changed: thanks to
<a href="https://oxide-and-friends.transistor.fm/episodes/the-future-of-work-2022-03-07">the
rise of remote work</a>, technologists are
much more dispersed&#8201;&#8212;&#8201;and many more people would need to travel for
dtrace.conf(24) than in previous DTrace Olympiads.
Travel hasn&#8217;t become any cheaper since 2008, and the cost (and inconvenience) was
clearly going to limit attendance.</p></div><div class="paragraph"><p>The dilemma for our small meetup
 highlights the
changing dynamics in tech conferences in general: with talks all recorded and made
publicly available after the conference, how does one justify attending
a conference in person?
There can be reasonable answers to that question, of course:  it may be the hallway
track, or the expo hall, or the after-hours socializing, or perhaps some
other
<a href="https://www.youtube.com/watch?v=oHeqakyWQT0">special conference experience</a>.
But it&#8217;s also not surprising that some conferences&#8201;&#8212;&#8201;especially ones
really focused on technical content&#8201;&#8212;&#8201;have decided that they are better
off doing as
<a href="https://www.oreilly.com/conferences/">conference giant O&#8217;Reilly Media did</a>, and
going exclusively online.
And without the need to feed and shelter participants, the
logistics for running a conference become much more tenable&#8201;&#8212;&#8201;and the
price point can be lowered to the point that even highly produced
conferences like
<a href="https://www.p99conf.io/">P99 CONF</a>
can be made freely available.
This, in turn, leads to much greater attendance&#8201;&#8212;&#8201;and a network effect that
can get back some of what one might lose going online.  In particular,
using chat as the hallway track can be more much effective (and is
certainly more scalable!) than the <strong>actual</strong> physical hallways at a conference.</p></div><div class="paragraph"><p>For conferences in general, there is a conversation to be had here
(and as a teaser,
Adam and I are going to
<a href="https://discord.gg/QrcKGTTPrF?event=1313157996645322784">talk about it with
Stephen O&#8217;Grady and Theo Schlossnagle on <em>Oxide and Friends</em> next week</a>, but
for our quirky, one-day, Olympiad-cadence dtrace.conf, the decision was
pretty easy:  there was much more to be gained than lost by going
exclusively on-line.</p></div><div class="paragraph"><p>So dtrace.conf(24) is coming up next week, and
<a href="https://www.eventbrite.com/e/dtraceconf24-tickets-1044402936297?aff=oddtdtcreator">it&#8217;s available to everyone</a>.
In terms of platform, we&#8217;re going to try to keep that pretty simple:
we&#8217;re going to use Google Meet for the actual presenters, which we will
stream in real-time to YouTube&#8201;&#8212;&#8201;and we&#8217;ll use
<a href="https://discord.gg/QrcKGTTPrF?event=1313617352541208747">the Oxide Discord</a>
for all chat.
We&#8217;re hoping you&#8217;ll join us on December 11th&#8201;&#8212;&#8201;and if you want to talk
about DTrace or a DTrace-adjacent topic, we&#8217;d love for you to present!
Keeping to the
unconference style, if you would like to present, please indicate your
topic in
<a href="https://discord.gg/tTECbxDf88">the #session-topics Discord channel</a> so
we can get the agenda fleshed out.</p></div><div class="paragraph"><p>While we&#8217;re excited to be online, there <strong>are</strong> some historical
accoutrements of conferences
that we didn&#8217;t want to give up.
First, we have a tradition of t-shirts with dtrace.conf.
Thanks to our designer
<a href="https://bsky.app/profile/benleonard.bsky.social">Ben Leonard</a>, we have
<a href="/img/blog/dtrace-conf24/dtrace-conf24-shirt.png">a banger of a t-shirt</a>,
capturing the spirit of our original dtrace.conf(08) shirt but
with an Oxide twist.
It&#8217;s (obviously) harder to make those free but we have tried to
price them reasonably.  You can get your t-shirt by adding it to your
(free)
<a href="https://www.eventbrite.com/e/dtraceconf24-tickets-1044402936297?aff=oddtdtcreator">dtrace.conf ticket</a>.
(And for those who present at dtrace.conf, your shirt is on us&#8201;&#8212;&#8201;we&#8217;ll send
you a coupon code!)</p></div><div class="paragraph"><p>Second, for those who can make their way to the East Bay and
want some hangout time, we are
going to have an après conference social event at the Oxide office starting
at 5p.  We&#8217;re charging something nominal for that too
(and like the t-shirt, you pay for that via your
<a href="https://www.eventbrite.com/e/dtraceconf24-tickets-1044402936297?aff=oddtdtcreator">dtrace.conf ticket</a>);
we&#8217;ll have
some food and drinks and an Oxide hardware tour for the curious&#8201;&#8212;&#8201;and
(of course?) there will be <a href="https://github.com/fishpong/docs/wiki/Primer">Fishpong</a>.</p></div><div class="paragraph"><p>Much has changed since I sent that e-mail 17 years ago&#8201;&#8212;&#8201;but the shared
values and disposition that brought together our small community continue
to endure; we look forward to seeing everyone (virtually) at dtrace.conf(24)!</p></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[A New Standard in National Security and Innovation]]></title>
        <id>https://oxide.computer/blog/oxide-computer-company-and-lawrence-livermore-national-laboratory</id>
        <link href="https://oxide.computer/blog/oxide-computer-company-and-lawrence-livermore-national-laboratory"/>
        <link rel="enclosure" href="https://oxide.computer/img/blog/llnl/llnl-logo-thumbnail.svg" type="image/svg"/>
        <updated>2024-11-18T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[Modernizing on-premises cloud computing capabilities for general-purpose workloads.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_oxide_computer_company_and_lawrence_livermore_national_laboratory_work_together_to_advance_cloud_and_hpc_convergence" aria-hidden="true"></span><a class="link group" href="#_oxide_computer_company_and_lawrence_livermore_national_laboratory_work_together_to_advance_cloud_and_hpc_convergence">Oxide Computer Company and Lawrence Livermore National Laboratory Work Together to Advance Cloud and HPC Convergence<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p><a href="https://oxide.computer/">Oxide Computer Company</a> and <a href="https://www.llnl.gov/">Lawrence Livermore National Laboratory</a> (LLNL) today announced a plan to bring on-premises cloud computing capabilities to the Livermore Computing (LC) high-performance computing (HPC) center. The rack-scale Oxide Cloud Computer allows LLNL to improve the efficiency of operational workloads and will provide users in the National Nuclear Security Administration (NNSA) with new capabilities for provisioning secure, virtualized services alongside HPC workloads.</p></div><div class="paragraph"><p>HPC centers have traditionally run batch workloads for large-scale scientific simulations and other compute-heavy applications. HPC workloads do not exist in isolation—there are a multitude of persistent, operational services that keep the HPC center running. Meanwhile, HPC users also want to deploy cloud-like persistent services—databases, Jupyter notebooks, orchestration tools, Kubernetes clusters. Clouds have developed extensive APIs, security layers, and automation to enable these capabilities, but few options exist to deploy fully virtualized, automated cloud environments on-premises. The <a href="https://oxide.computer/">Oxide Cloud Computer</a> allows organizations to deliver secure cloud computing capabilities within an on-premises environment.</p></div><div class="quoteblock"><blockquote>On-premises environments are the next frontier for cloud computing. LLNL is tackling some of the hardest and most important problems in science and technology, requiring advanced hardware, software, and cloud capabilities. We are thrilled to be working with their exceptional team to help advance those efforts, delivering an integrated system that meets their rigorous requirements for performance, efficiency, and security.</blockquote><div class="attribution">— <!-- -->Steve Tuck<cite>CEO at Oxide Computer Company</cite></div></div><div class="paragraph"><p>Leveraging the new Oxide Cloud Computer, LLNL will enable staff to provision virtual machines (VMs) and services via self-service APIs, improving operations and modernizing aspects of system management. In addition, LLNL will use the Oxide rack as a proving ground for secure multi-tenancy and for smooth integration with the LLNL-developed <a href="https://flux-framework.org/">Flux</a> resource manager. LLNL plans to bring its users cloud-like Infrastructure-as-a-Service (IaaS) capabilities that work seamlessly with their HPC jobs, while maintaining security and isolation from other users. Beyond LLNL personnel, researchers at the Los Alamos National Laboratory and Sandia National Laboratories will also partner in many of the activities on the Oxide Cloud Computer.</p></div><div class="quoteblock"><div class="paragraph"><p>We look forward to working with Oxide to integrate this machine within our HPC center. Oxide’s Cloud Computer will allow us to securely support new types of workloads for users, and it will be a proving ground for introducing cloud-like features to operational processes and user workflows. We expect Oxide’s open-source software stack and their transparent and open approach to development to help us work closely together.</p></div><div class="attribution">— <!-- -->Todd Gamblin<cite>Distinguished Member of Technical Staff at LLNL</cite></div></div><div class="quoteblock"><div class="paragraph"><p>Sandia is excited to explore the Oxide platform as we work to integrate on-premises cloud technologies into our HPC environment. This advancement has the potential to enable new classes of interactive and on-demand modeling and simulation capabilities.</p></div><div class="attribution">— <!-- -->Kevin Pedretti<cite>Distinguished Member of Technical Staff at Sandia National Laboratories</cite></div></div><div class="paragraph"><p>LLNL plans to work with Oxide on additional capabilities, including the deployment of additional Cloud Computers in its environment. Of particular interest are scale-out capabilities and disaster recovery. The latest installation underscores Oxide Computer’s momentum in the federal technology ecosystem, providing reliable, state-of-the-art Cloud Computers to support critical IT infrastructure.</p></div><div class="paragraph"><p>To learn more about Oxide Computer, visit <a href="https://oxide.computer" class="bare">https://oxide.computer</a>.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_about_oxide_computer" aria-hidden="true"></span><a class="link group" href="#_about_oxide_computer">About Oxide Computer<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Oxide Computer Company is the creator of the world’s first commercial Cloud Computer, a true rack-scale system with fully unified hardware and software, purpose-built to deliver hyperscale cloud computing to on-premises data centers. With Oxide, organizations can fully realize the economic and operational benefits of cloud ownership, with access to the same self-service development experience of public cloud, without the public cloud cost. Oxide empowers developers to build, run, and operate any application with enhanced security, latency, and control, and frees organizations to elevate IT operations to accelerate strategic initiatives. To learn more about Oxide’s Cloud Computer, visit oxide.computer.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_about_llnl" aria-hidden="true"></span><a class="link group" href="#_about_llnl">About LLNL<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Founded in 1952, <a href="https://www.llnl.gov/">Lawrence Livermore National Laboratory</a> provides solutions to our nation’s most important national security challenges through innovative science, engineering, and technology. Lawrence Livermore National Laboratory is managed by Lawrence Livermore National Security, LLC for the U.S. Department of Energy’s National Nuclear Security Administration.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_media_contact" aria-hidden="true"></span><a class="link group" href="#_media_contact">Media Contact<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>LaunchSquad for Oxide Computer
<a href="mailto:oxide@launchsquad.com">oxide@launchsquad.com</a></p></div></div></div></div>]]></content>
        <author>
            <name>Kevin Spring</name>
        </author>
        <contributor>
            <name>Kevin Spring</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Remembering Charles Beeler]]></title>
        <id>https://oxide.computer/blog/remembering-charles-beeler</id>
        <link href="https://oxide.computer/blog/remembering-charles-beeler"/>
        <updated>2024-11-12T08:00:00.000Z</updated>
        <summary type="html"><![CDATA[Remembering Oxide investor Charles Beeler, who passed away in September.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>We are heartbroken to relay that Charles Beeler, a friend and early investor
in Oxide, <a href="https://www.rallyventures.com/in-memoriam-charles-beeler/">passed
away in September after a battle with cancer</a>.  We lost Charles far too soon;
he had a tremendous influence on the careers of us both.</p></div><div class="paragraph"><p>Our relationship with Charles dates back nearly two decades, to his
involvement with the ACM Queue board where he met Bryan.  It was unprecedented
to have a venture capitalist serve in this capacity with ACM, and Charles
brought an entirely different perspective on the practitioner content.  A
computer science pioneer who also served on the board took Bryan aside at one
point:  "Charles is one of the good ones, you know."</p></div><div class="paragraph"><p>When Bryan joined Joyent a few years later, Charles also got to know Steve
well.  Seeing the promise in both node.js and cloud computing, Charles became
an investor in the company.  When companies hit challenging times, some
investors will hide&#8201;&#8212;&#8201;but Charles was the kind of investor to figure out how
to fix what was broken.  When Joyent needed a change in executive leadership,
it was Charles who not only had the tough conversations, but led the search
for the leader the company needed, ultimately positioning the company for
success.</p></div><div class="paragraph"><p>Aside from his investment in Joyent, Charles was an outspoken proponent of
node.js, becoming an organizer of the Node Summit conference.  In 2017, he
asked Bryan to deliver the conference&#8217;s keynote, but by then, the relationship
between Joyent and node.js had become&#8230;&#8203; complicated, and Bryan felt that it
probably wouldn&#8217;t be a good idea.  Any rational person would have dropped it,
but Charles persisted, with characteristic zeal:  if the Joyent relationship
with node.js had become strained, so much more the reason to speak candidly
about it!  Charles prevailed, and the resulting talk,
<a href="https://www.youtube.com/watch?v=Xhx970_JKX4">Platform as Reflection of Values</a>,
became one of Bryan&#8217;s most personally meaningful talks.</p></div><div class="paragraph"><p>Charles&#8217;s persistence was emblematic:  he worked behind the scenes to
encourage people to do their best work, always with an enthusiasm for the
innovators and the creators.  As we were contemplating Oxide, we told Charles
what we wanted to do long before we had a company.  Charles laughed with
delight: "I hoped that you two would do something big, and I am just so happy
for you that you&#8217;re doing something so ambitious!"</p></div><div class="paragraph"><p>As we raised seed capital, we knew that we were likely a poor fit for Charles
and his fund.  But we also knew that we deeply appreciated his wisdom and
enthusiasm; we couldn&#8217;t resist pitching him on Oxide.  Charles approached the
investment in Oxide as he did with so many other aspects:  with curiosity,
diligence, empathy, and candor.  He was direct with us that despite his
enthusiasm for us personally, Oxide would be a challenging investment for his
firm.  But he also worked with us to address specific objections, and
ultimately he won over his partnership.  We were thrilled when he not only
invested, but pulled together a syndicate of like-minded technologists and
entrepreneurs to join him.</p></div><div class="paragraph"><p>Ever since, he has been a huge Oxide fan.  Befitting his enthusiasm, one of
his final posts expressed his enthusiasm and pride in what the Oxide team has
built.</p></div><div class="paragraph"><p>Charles, thank you.  You told us you were proud of us&#8201;&#8212;&#8201;and it meant the
world.  We are gutted to no longer have you with us; your influence lives on
not just in Oxide, but also in the many people that you have inspired.  You
were the best of venture capital.  Closer to the heart, you were a terrific
friend to us both; thank you.</p></div></div>]]></content>
        <author>
            <name>Steve Tuck</name>
        </author>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Steve Tuck</name>
        </contributor>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[How Oxide Cuts Data Center Power Consumption in Half]]></title>
        <id>https://oxide.computer/blog/how-oxide-cuts-data-center-power-consumption-in-half</id>
        <link href="https://oxide.computer/blog/how-oxide-cuts-data-center-power-consumption-in-half"/>
        <updated>2024-11-08T12:00:00.000Z</updated>
        <summary type="html"><![CDATA[A rack-scale design that drives data center power efficiency.]]></summary>
        <content type="html"><![CDATA[<link rel="preload" as="image" href="/img/blog/power-consumption/goldman-datacenter-chart.svg"/><link rel="preload" as="image" href="/img/blog/power-consumption/oxide-power-efficiency-illustration.svg"/><div id="content" class="asciidoc-body w-full"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>Here&#8217;s a sobering thought: today, data centers already consume <strong>1-2% of the world&#8217;s power</strong>, and that percentage will likely rise to <strong>3-4% by the end of the decade</strong>. According to <a href="https://www.goldmansachs.com/insights/articles/AI-poised-to-drive-160-increase-in-power-demand">Goldman Sachs research</a>, that rise will include a doubling in data center carbon dioxide emissions. As the data and AI boom progresses, this thirst for power shows no signs of slowing down anytime soon. Two key challenges quickly become evident for the <a href="https://www.crn.com/news/cloud/2024/amazon-ceo-85-percent-of-it-spend-remains-on-premises-gen-ai-will-fuel-aws-cloud-sales">85% of IT</a> that currently lives on-premises.</p></div><div class="olist arabic"><ol class="arabic"><li class=""><p><em>How can organizations reduce power consumption and corresponding carbon emissions?</em></p></li><li class=""><p><em>How can organizations keep pace with AI innovation as existing data centers run out of available power?</em></p></li></ol></div><div class="imageblock   noborder"><div class="content"><img src="/img/blog/power-consumption/goldman-datacenter-chart.svg" alt="Graph of AI &amp; Data Center Growth Boosting Electricity Demand"/></div><div class="title">Masanet et al. (2020), Cisco, IEA, Goldman Sachs Research</div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_rack_scale_design_is_critical_to_improved_data_center_efficiency" aria-hidden="true"></span><a class="link group" href="#_rack_scale_design_is_critical_to_improved_data_center_efficiency">Rack-scale design is critical to improved data center efficiency<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Traditional data center IT consumes so much power because the fundamental unit of compute is <em>an individual server</em>; like a house where rooms were built one at a time, with each room having its own central AC unit, gas furnace, and electrical panel. Individual rackmount servers are stacked together, each with their own AC power supplies, cooling fans, and power management. They are then paired with storage appliances and network switches that communicate at arm&#8217;s length, not designed as a cohesive whole. This approach fundamentally limits organizations' ability to maintain sustainable, high-efficiency computing systems.</p></div><div class="paragraph"><p>Of course, hyperscale public cloud providers did not design their data center systems this way. Instead, they operate like a carefully planned smart home where everything is designed to work together cohesively and is operated by software that understands the home&#8217;s systems end-to-end. High-efficiency, rack-scale computers are deployed at scale and operate as a single unit with integrated storage and networking to support elastic cloud computing services. This modern architecture is made available to the market as public cloud, but that rental-only model is ill-fit for many business needs.</p></div><div class="imageblock   noborder"><div class="content"><img src="/img/blog/power-consumption/oxide-power-efficiency-illustration.svg" alt="Illustration of Oxide racks at a higher density (2x) than conventional ones"/></div></div><div class="sidebarblock"><div class="content"><div class="paragraph"><p>Compared to a popular rackmount server vendor, Oxide is able to fill our specialized racks with 32 AMD Milan sleds and highly-available network switches using less than 15kW per rack, doubling the compute density in a typical data center. With just 16 of the alternative 1U servers and equivalent network switches, over 16kW of power is required per rack, leading to only 1,024 CPU cores vs Oxide&#8217;s 2,048.</p></div><div class="paragraph"><p><strong>Extracting more useful compute from each kW of power and square foot of data center space is key to the future effectiveness of on-premises computing.</strong></p></div></div></div><div class="paragraph"><p>At Oxide, we&#8217;ve taken this lesson in advancing rack-scale design, improved upon it in several ways, and made it available for every organization to purchase and operate anywhere in the world without a tether back to the public cloud. Our Cloud Computer treats the entire rack as a <strong>single, unified computer</strong> rather than a collection of independent parts, achieving unprecedented power efficiency.</p></div><div class="paragraph"><p>By designing the hardware and software together, we&#8217;ve eliminated unnecessary components and optimized every aspect of system operation through a control plane with visibility to end-to-end operations.</p></div><div class="quoteblock"><div class="paragraph"><p>When we started Oxide, the DC bus bar stood as one of the most glaring differences between the rack-scale machines at the hyperscalers and the rack-and-stack servers that the rest of the market was stuck with. That a relatively simple piece of copper was unavailable to commercial buyers&#8201;&#8212;&#8201;despite being unequivocally the right way to build it!&#8201;&#8212;&#8201;represented everything wrong with the legacy approach.</p></div><div class="paragraph"><p>The bus bar in the Oxide Cloud Computer is not merely more efficient, it is a concrete embodiment of the tremendous gains from designing at rack-scale, and by integrating hardware with software.</p></div><div class="attribution">— <!-- -->Bryan Cantrill</div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_the_improvements_were_seeing_are_rooted_in_technical_innovation" aria-hidden="true"></span><a class="link group" href="#_the_improvements_were_seeing_are_rooted_in_technical_innovation">The improvements we’re seeing are rooted in technical innovation<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="ulist"><ul class=""><li><p><strong>Replacing low-efficiency AC power supplies with a high-efficiency DC Bus Bar</strong><br>
Power conversion is performed once AC power is fed from the data center to the Oxide universal power shelf with a customized power shelf controller (PSC). The power shelf distributes DC power up and down the rack via a bus bar. <em>This eliminates the 70 total AC power supplies</em> found in an equivalent legacy server rack within 32 servers, two top-of-rack switches, and one out-of-band switch, each with two AC power supplies. This power shelf also ensures the load is balanced across phases, something that’s impossible with traditional power distribution units found in legacy server racks.</p></li><li><p><strong>Bigger fans = bigger efficiency gains</strong><br>
Oxide server sleds are designed to a custom form factor to accommodate larger fans than legacy servers typically use. These fans can move more air more efficiently, cooling the systems <em>using 12x less energy</em> than legacy servers, which each contain as many as 7 fans, which must work much harder to move air over system components.</p></li><li><p><strong>Purpose-built for power efficiency</strong><br>
Oxide server sleds have <em>less restrictive airflow</em> than legacy servers by eliminating extraneous components like PCIe risers, storage backplanes, and more. Legacy servers need many optional components like these because they could be used for any number of tasks, such as point-of-sale systems, data center servers, or network-attached-storage (NAS) systems. Still, they were never designed optimally for any one of those tasks. The Oxide Cloud Computer was designed from the ground up to be a rack-scale cloud computing powerhouse, and so it&#8217;s optimized for exactly that task.</p></li><li><p><strong>Hardware + Software designed together</strong><br>
The Oxide Cloud Computer includes a robust cloud control plane with deep observability to the full system. <em>By designing the hardware and software together</em>, we can make hardware choices like more intelligent DC-DC power converters that can provide rich telemetry to our control plane, enabling future feature enhancements such as dynamic power capping and efficiency-based workload placement that are impossible with legacy servers and software systems.</p></li></ul></div><div class="title">Learn more about Oxide’s intelligent Power Shelf Controller</div>
<div class="youtube-embed">
  <iframe width="560" height="315" src="https://www.youtube.com/embed/qzK4qbb8-Ts" title="Learn more about Oxide’s intelligent Power Shelf Controller" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen=""></iframe>
</div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_the_bottom_line_customers_and_the_environment_both_benefit" aria-hidden="true"></span><a class="link group" href="#_the_bottom_line_customers_and_the_environment_both_benefit">The Bottom Line: Customers and the Environment Both Benefit<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Reducing data center power demands and achieving more useful computing per kilowatt requires <strong>fundamentally rethinking</strong> traditional data center utilization and compute design. At Oxide, we&#8217;ve proven that dramatic efficiency gains are possible when you rethink the computer at rack-scale with hardware and software designed thoughtfully and rigorously together.</p></div><div class="paragraph"><p>Ready to learn how your organization can achieve these results? <strong>Schedule time with our team <a href="https://oxide.computer/sales">here</a>.</strong></p></div><div class="paragraph"><p>Together, we can reclaim on-premises computing efficiency to achieve both business and sustainability goals.</p></div></div></div></div>]]></content>
        <author>
            <name>Kevin Spring</name>
        </author>
        <contributor>
            <name>Kevin Spring</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Reflections on Founder Mode]]></title>
        <id>https://oxide.computer/blog/reflections-on-founder-mode</id>
        <link href="https://oxide.computer/blog/reflections-on-founder-mode"/>
        <updated>2024-09-02T17:00:00.000Z</updated>
        <summary type="html"><![CDATA[Reflections on a recent Paul Graham piece – and on the culture at Oxide.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>Paul Graham&#8217;s <a href="https://paulgraham.com/foundermode.html">Founder
Mode</a> is an important piece, and you should read it if for no other reason
that "founder mode" will surely enter the lexicon (and as Graham grimly
predicts: "as soon as the concept of founder mode becomes established, people
will start misusing it"). When building a
company, founders are engaged in several different acts at once:  raising
capital; building a product; connecting that product to a market; building an
organization to do all of these.  Founders make lots of mistakes in all of
these activities, and Graham&#8217;s essay highlights a particular kind of mistake
in which founders are overly deferential to expertise or convention.
Pejoratively referring to this as "Management Mode", Graham frames this in the
Silicon Valley
<a href="https://frinkiac.com/meme/S08E14/341123.jpg?b64lines=IEkgRE9OJ1QgV0FOVCBUTyBTT1VORAogUFJFVEVOVElPVVMgSEVSRSwgQlVUCiBJVENIWSAmIFNDUkFUQ0hZIENPTVBSSVNFCiBBIERSQU1BVFVSR0lDQUwgRFlBRC4=">dramaturgical
dyad</a> of Steve Jobs and John Scully. While that&#8217;s a little too reductive
(anyone seeking to understand Jobs needs to read Randall Stross&#8217;s superlative
<a href="https://www.goodreads.com/en/book/show/226316">Steve Jobs and the NeXT Big
Thing</a>, highlighting Jobs&#8217;s many post-Scully failures at NeXT), Graham has
identified a real issue here, albeit without much specificity.</p></div><div class="paragraph"><p>For a treatment of the same themes but with much more supporting detail, one
should read the (decade-old) piece from Tim O&#8217;Reilly,
<a href="https://www.oreilly.com/radar/how-i-failed/">How I failed</a>.  (Speaking
personally, O&#8217;Reilly&#8217;s piece had a profound influence on me, as it encouraged
me to stand my ground on an issue on which I had
<a href="https://x.com/bcantrill/status/1216491216356823040">my own beliefs</a>
but was being told to defer to
convention.)
But as terrific as it is,
O&#8217;Reilly&#8217;s piece also doesn&#8217;t answer the question that Graham poses:  how do
founders prevent their companies from losing their way?</p></div><div class="paragraph"><p>Graham says that founder mode is a complete mystery ("There are as far as I
know no books specifically about founder mode"), and while there is a danger
in being too pat or prescriptive, there does seem to be a clear component for
keeping companies true to themselves:  <strong>the written word</strong>.  That is, a
writing- (and reading-!) intensive company culture does, in fact, allow for
scaling the kind of responsibility that Graham thinks of as founder mode.  At
Oxide, our writing-intensive culture has been absolutely essential: our RFD
process is the
<a href="https://oxide-and-friends.transistor.fm/episodes/rfds-the-backbone-of-oxide">backbone
of Oxide</a>, and has given us the structure to formalize, share, and refine our
thinking.  First among this formalized thinking – and captured in our first
real RFD – is <a href="https://2.rfd.oxide.computer">RFD 2 Mission, Principles, and
Values</a>.  Immediately behind that (and frankly, the most important process for
<strong>any</strong> company) is <a href="https://3.rfd.oxide.computer">RFD 3 Oxide Hiring Process</a>.
These first three RFDs – on the process itself, on what we value, and on how
we hire – were written in the earliest days of the company, and they have
proven essential to scale the company: they are the foundation upon which we
attract <strong>people who share our values</strong>.</p></div><div class="paragraph"><p>While the shared values have proven necessary, they haven&#8217;t been sufficient to
eliminate the kind of quandaries that Graham and O&#8217;Reilly describe.  For
example, there have been some who have told us that we can&#8217;t possibly hire
non-engineering roles using our hiring process – or told us that
<a href="https://oxide.computer/blog/compensation-as-a-reflection-of-values">our
approach to compensation</a> can&#8217;t possibly work.  To the degree that we have
had a need for Graham&#8217;s founder mode, it has been in those moments: to stay
true to the course we have set for the company.  But because we have written
down so much, there is less occasion for this than one might think.  And when
it does occur – when there <strong>is</strong> a need for further elucidation or
clarification – the artifact is not infrequently a new RFD that formalizes
our newly extended thinking.  (<a href="https://68.rfd.oxide.computer">RFD
68</a> is an early public and concrete example of this;
<a href="https://508.rfd.oxide.computer">RFD 508</a> is a much more recent one that
<a href="https://x.com/kelseyhightower/status/1824502930550268410">garnered some
attention</a>.)</p></div><div class="paragraph"><p>Most importantly, because we have used our values as a clear lens for hiring,
we are able to assure that everyone at Oxide is able to have the same
disposition with respect to responsibility – and this (coupled with the
transparency that the written word allows) permits us to <strong>trust one
another</strong>.  As I elucidated in
<a href="https://speakerdeck.com/bcantrill/things-i-learned-the-hard-way?slide=13">Things
I Learned The Hard Way</a>, the most important quality in a leader is to bind
a team with mutual trust: with it, all things are possible – and without it,
even easy things can be debilitatingly difficult. Graham mentions trust, but
he doesn&#8217;t give it its due.  Too often, founders focus on the immediacy of a
current challenge without realizing that they are, in fact, undermining trust
with their approach.  Bluntly, founders are at grave risk of misinterpreting
Graham&#8217;s "Founders Mode" to be a license to micromanage their teams,
descending into the kind of manic
<a href="https://en.wikipedia.org/wiki/Seagull_management">seagull management</a>
that inhibits a team rather than empowering it.</p></div><div class="paragraph"><p>Founders seeking to internalize Graham&#8217;s advice should recast it by asking
themselves how they can foster mutual trust – and how they can build the
systems that allow trust to be strengthened even as the team expands.  For us
at Oxide, writing is the foundation upon which we build that trust.  Others may
land on different mechanisms, but the goal of founders should be the same:
build the trust that allows a team to kick a Jobsian dent in the universe!</p></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Engineering a Culture]]></title>
        <id>https://oxide.computer/blog/engineering-culture</id>
        <link href="https://oxide.computer/blog/engineering-culture"/>
        <link rel="enclosure" href="https://oxide.computer/img/blog/engineering-a-culture/engineering-structure-thumbnail.svg" type="image/svg"/>
        <updated>2024-03-31T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[A revelation, a bug, and a fix – how it all reflects the culture at Oxide.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>We ran into an interesting issue recently.  On the one hand, it was routine:
we had a bug&#8201;&#8212;&#8201;a regression&#8201;&#8212;&#8201;and the team quickly jumped on it, getting
it root caused and fixed.  But on the other, this particular issue
was something of an Oxide object lesson, representative not just of the
technologies but also of the
culture we have built here.  I wasn&#8217;t the only person who thought so,
and two of my colleagues wrote terrific blog entries with their perspectives:</p></div><div class="ulist"><ul class=""><li><p>Matt Keeter with <a href="https://www.mattkeeter.com/blog/2024-03-25-packing/">It&#8217;s Free Real Estate</a></p></li><li><p>Cliff Biffle with <a href="https://cliffle.com/blog/who-killed-the-network-switch/">Who killed the network switch?  A Hubris Bug Story</a></p></li></ul></div><div class="paragraph"><p>The initial work as described by Matt represents a creative solution to
a thorny problem; if it&#8217;s clear in hindsight, it certainly wasn&#8217;t at the time!
(In Matt&#8217;s evocative words: "One morning, I had a revelation.") I first learned of
Matt&#8217;s work when he demonstrated it during our weekly
<a href="https://www.youtube.com/watch?v=7RR6hFE_jDU#t=6">Demo Friday</a>,
an hour-long unstructured session to demo our work for one another.  Demo
Friday is such an essential part of Oxide&#8217;s culture that it feels like we have
always done it, but in fact it took us nearly two years into the company&#8217;s
life to get there: over the spring and summer of 2021, our colleague Sean
Klein had instituted regular demos for the area that he works on (the
<a href="https://github.com/oxidecomputer/omicron">Oxide control plane</a>),
and others around the company&#8201;&#8212;&#8201;seeing the energy that came from it&#8201;&#8212;&#8201;asked
if they, too, could start regular demos for their domain.  But instead of
doing it group by group, we instituted it company-wide starting in the fall of
2021: an unstructured hour once a week in which anyone can demo
anything.</p></div><div class="paragraph"><p>In the years since, we have had demos of all scopes and sizes.  Importantly,
no demo is too small&#8201;&#8212;&#8201;and we have often found that a demo that feels small
to someone in the thick of work will feel extraordinary to someone outside of
it.  ("I have a small demo building on the work of a lot of other people" has
been heard so frequently that it has become something of an inside joke.) Demo
Friday is important because it gets to one of our most important drivers as
technologists:  <strong>the esteem of our peers</strong>.  The thrill that you get from showing
work to your colleagues is unparalleled&#8201;&#8212;&#8201;and their wonderment in return is
uniquely inspiring.  (Speaking personally, Matt&#8217;s demo addressed a problem
that I had personally had many times over in working on Hubris&#8201;&#8212;&#8201;and I was one
of the many <a href="https://en.wikipedia.org/wiki/W00t">w00ts in the chat</a>, excited to see his
creative solution!)</p></div><div class="paragraph"><p>Having the demos be company-wide has also been a huge win
for not just our shared empathy and teamwork but also our curiosity and
versatility:  it&#8217;s really inspiring to have (say) one colleague show how they
used
<a href="https://www.protoexpress.com/blog/back-drilling-pcb-design-and-manufacturing/">PCB
backdrilling</a> for signal integrity, and the next show an integration they
built using
<a href="https://github.com/oxidecomputer/dropshot">Dropshot</a>
between our CRM and spinning up a demonstration environment for a customer.
And this is more than just idle intellectual curiosity:  our stack is deep&#8201;&#8212;&#8201;spanning
both hardware and software&#8201;&#8212;&#8201;and the demos make for a fun and engaging way to learn
about aspects of the system that we don&#8217;t normally work on.</p></div><div class="paragraph"><p>Returning to Matt and Cliff, if
<a href="https://www.mattkeeter.com/blog/2024-03-25-packing/">Matt&#8217;s work</a>
implicitly hits on aspects of our culture,
<a href="https://cliffle.com/blog/who-killed-the-network-switch/">Cliff&#8217;s story of debugging</a> addresses that culture
explicitly, noting that the experience demonstrated:</p></div><div class="quoteblock"><div class="paragraph"><p><strong>Tight nonhierarchical integration of the team.</strong> This isn’t a Hubris feature, but it’s hard to separate Hubris from the team that built it. Oxide’s engineering team has essentially no internal silos. Our culture rewards openness, curiosity, and communication, and discourages defensiveness, empire-building, and gatekeeping. We’ve worked hard to create and defend this culture, and I think it shows in the way we organized horizontally, across the borders of what other organizations would call teams, to solve this mystery.</p></div></div><div class="paragraph"><p>In
<a href="https://news.ycombinator.com/item?id=39813365">the discussion on Hacker News of Cliff&#8217;s piece</a>,
this cultural observeration stood out, with
<a href="https://news.ycombinator.com/item?id=39837073">a commenter asking</a>:</p></div><div class="quoteblock"><div class="paragraph"><p>I&#8217;d love to hear more about the motivations for crafting such a culture as
well as some particular implementation details. I&#8217;m curious if there are
drawbacks to fostering "openness, curiosity, and communication" within an
organization?</p></div></div><div class="paragraph"><p>The culture at Oxide is in fact very deliberate:  when starting a company,
one is building many things at once (the team, the product, the organization,
the brand)&#8201;&#8212;&#8201;and the culture will both inform and be reinforced by all of
these.
Setting that first cultural cornerstone was very important to us&#8201;&#8212;&#8201;starting with
<a href="https://oxide.computer/principles">our mission, principles,
and values</a>.
Critically, by using our mission, principles, and values as the foundation for
<a href="https://rfd.shared.oxide.computer/rfd/0003">our hiring process</a>,
we have deliberately created a culture that reinforces itself.</p></div><div class="paragraph"><p>Some of the implementation details:</p></div><div class="ulist"><ul class=""><li><p>We have <a href="https://oxide.computer/blog/compensation-as-a-reflection-of-values">uniform compensation</a> (even if it might not scale indefinitely)</p></li><li><p>We are <a href="https://rfd.shared.oxide.computer/">writing intensive</a> (but we still believe in spoken collaboration)</p></li><li><p>We have no formalized performance review process (but we believe in feedback)</p></li><li><p>We record every meeting (but not every conversation)</p></li><li><p>We have a remote work force (but we also have an office)</p></li><li><p>We are non-hierarchical (but we all ultimately report to our CEO)</p></li><li><p>We don&#8217;t use engineering metrics (but we all measure ourselves by our
customers and their success)</p></li></ul></div><div class="paragraph"><p>If it needs to be said, there is plenty of <strong>ambiguity</strong>: if you are using
absolutes to think of Oxide (outside of our principles of honesty, integrity
and decency!) you are probably missing some nuance of our culture.</p></div><div class="paragraph"><p>Finally, to the (seemingly loaded?) question of the "drawbacks" of fostering
"openness, curiosity, and communication" within an organization, the only
drawback is that it&#8217;s hard work: culture has to be deliberate without being
overly prescriptive, and that can be a tricky balance.  In this regard,
building a culture is very different than building (say) software:  it is not
engineered in a traditional sense, but is rather a gooey, squishy, organism
that will evolve over time.  But the reward of the effort is something that its
participants care intensely about: it will continue to be (in Cliff&#8217;s words) a
culture that we work hard to not just create but defend!</p></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Moore's Scofflaws]]></title>
        <id>https://oxide.computer/blog/moores-scofflaws</id>
        <link href="https://oxide.computer/blog/moores-scofflaws"/>
        <updated>2024-02-20T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[The tyranny of per-core licensing.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>Years ago, Jeff Bezos famously quipped that "your margin is my opportunity."
This was of course aimed not at Amazon&#8217;s customers, but rather its
competitors, and it was deadly serious: customers of AWS in those bygone years
will fondly remember that every re:Invent brought with it another round of
price cuts.  This era did not merely reflect Bezos&#8217;s relentless execution, but
also a disposition towards who should reap the reward of advances in
underlying technology: Amazon believed (if implicitly) that improvements at
the foundations of computing (e.g., in transistor density, core count, DRAM
density, storage density, etc.) should reflect themselves in lower prices for
consumers rather than higher margins for suppliers.</p></div><div class="paragraph"><p>Price cuts are no longer a re:Invent staple, having been replaced by a regular
Amazon tradition of a different flavor:  cutting depreciation (and therefore
increasing earnings) by
<a href="https://www.theregister.com/2024/02/02/amazon_q4_2023/">extending the effective
life of their servers</a>.  (These announcements are understandably much more
subdued, as "my depreciation is my margin opportunity" doesn&#8217;t have quite the
same ring to it.)</p></div><div class="paragraph"><p>As compute needs have grown and price cuts have become an increasingly distant
memory, some have questioned their sky-high cloud bills, wondering if they
should in fact be owning their compute instead of renting it.  When we started
Oxide, we knew from operating our own public cloud what those economics looked
like&#8201;&#8212;&#8201;and we knew that over time others of a particular scale would come to
the same realization that they would be better off not giving their margin
away by renting compute.  (Though it&#8217;s safe to say that we did not predict
that it would be <a href="https://www.youtube.com/watch?v=a30vFpSaoZg">DHH leading the
charge</a>!)</p></div><div class="paragraph"><p>Owning one&#8217;s own cloud sounds great, but there is a bit that&#8217;s unsaid: <strong>what
about the software?</strong>  Software is essential for elastic, automated
infrastructure:  hardware alone does not a cloud make!  Unfortunately, the
traditional server vendors do not help here: because of a PC-era divide in how
systems are delivered, customers are told to look elsewhere for any and all
system software.  This divide is problematic on several levels.  First, it
impedes the hardware/software co-design that we (and, famously,
<a href="https://www.youtube.com/watch?v=XAfTXYa36f4">others</a>!) believe is essential to
deliver the best possible product.  Second, it leads to
<a href="https://twitter.com/_sysengineer/status/1487149172637712386">infamous finger
pointing</a> when the whole thing doesn&#8217;t work.  But there is also a thorny
economic problem:  when your hardware and your software don&#8217;t come from the
same provider, <strong>to whom should go the spoils of better hardware?</strong></p></div><div class="paragraph"><p>To someone who has just decided to buy their hardware out of their frustration
with renting it, the answer feels obvious:  whoever owns the hardware should
naturally benefit from its advances!  Unfortunately, the enterprise software
vendor delivering your infrastructure often has other ideas&#8201;&#8212;&#8201;and because
their software is neither rented nor bought, but rather comes from the
hinterlands of software licensing, they have broad latitude as to how it is
priced and used.  In particular, this allows them to charge based on the
hardware that you run it on&#8201;&#8212;&#8201;to have <strong>per-core software licensing.</strong></p></div><div class="paragraph"><p>This galling practice isn&#8217;t new (and is in fact as old as symmetric
multiprocessing systems), but it has taken on new dimensions in the era of
<a href="https://en.wikipedia.org/wiki/Chiplet">chiplets</a> and packaging innovation: the
advances that your next CPU has over your current one are very likely to be
expressed in core count.  Per-core licensing allows a third party&#8201;&#8212;&#8201;who
neither made the significant investment in developing the next generation of
microprocessor nor paid for the part themselves&#8201;&#8212;&#8201;to exact a tax on improved
infrastructure.  (And this tax can be
<a href="https://news.vmware.com/company/cpu-pricing-model-update-feb-2020">shockingly
brazen</a>!) Couple this with
<a href="https://arstechnica.com/information-technology/2023/12/broadcom-ends-vmware-perpetual-license-sales-testing-customers-and-partners/">the
elimination of perpetual licensing</a>, and software costs can potentially absorb
the entire gain from a next-generation CPU, leaving a disincentive to run
newer, more efficient infrastructure.  As an industry, we have come to accept
this practice, but we shouldn&#8217;t: in the go-go era of
<a href="https://en.wikipedia.org/wiki/Dennard_scaling">Dennard scaling</a> (when clock
rates rose at a blistering rate), software vendors never would have been
allowed to get away with charging by the gigahertz; we should not allow them to
feel so emboldened to charge by core count now!</p></div><div class="paragraph"><p>If it needs to be said, we have taken a different approach at Oxide:  when you
buy the <a href="/blog/the-cloud-computer">Oxide cloud computer</a>, <strong>all of the
software to run it is included</strong>.  This includes all of the software necessary
to run the rack as elastic infrastructure:
<a href="/product/compute">virtual compute</a>,
<a href="/product/storage">virtual storage</a>,
<a href="/product/networking">virtual networking</a>.
(And yes, it&#8217;s all open source&#8201;&#8212;&#8201;which unfortunately demands the immediate
clarification that it&#8217;s <a href="https://opensource.org/osd/"><em>actually</em> open source</a>
rather than <a href="https://bcantrill.dtrace.org/2018/12/16/a-eula-in-foss-clothing/">pretend open
source</a>.) When we add a new feature to our software, there is no licensing
enablement or other such nuisance&#8201;&#8212;&#8201;the feature just comes with the next
update.  And what happens when AMD releases a new CPU with twice the core
count?  The new sled running the new CPU runs along your existing rack&#8201;&#8212;&#8201;you&#8217;re not paying more than the cost of the new sled itself.  This gives the
dividends of Moore&#8217;s Law (or
<a href="https://www.youtube.com/watch?v=cuvp-e4ztC0">Wright&#8217;s Law</a>!) to whom they
rightfully belong:  the users of compute.</p></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[A Gap in the TrustZone Preset Settings for the LPC55S69]]></title>
        <id>https://oxide.computer/blog/lpc55s69-tzpreset</id>
        <link href="https://oxide.computer/blog/lpc55s69-tzpreset"/>
        <updated>2023-11-20T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[A weakness with TrustZone preset settings.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>We&#8217;re very excited to have <a href="https://oxide.computer/blog/the-cloud-computer">announced</a>
the general availability of our cloud computer. As part of this work, we
continue to build on top of the LPC55S69 from NXP as our Root of Trust. We&#8217;ve
discovered some gaps when using TrustZone preset settings on the LPC55S69 that
can allow for unexpected behavior including enabling debug settings and
exposure of the UDS (Unique Device Secret). These issues require a signed
image or access at manufacturing time.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_how_to_safely_securely_configure_a_chip" aria-hidden="true"></span><a class="link group" href="#_how_to_safely_securely_configure_a_chip">How to (safely, securely) configure a chip<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The LPC55S69 uses the <a href="https://developer.arm.com/documentation/ddi0553/latest">Armv8-m</a>
architecture which includes TrustZone-M. We&#8217;ve <a href="https://oxide.computer/blog/exploiting-undocumented-hardware-blocks-in-the-lpc55s69">previously</a>
discussed some aspects of the Armv8-m architecture and <a href="https://media.defcon.org/DEF%20CON%2029/DEF%20CON%2029%20video%20and%20slides/DEF%20CON%2029%20-%20Laura%20Abbott%20Rick%20Altherr%20-%20Breaking%20TrustZone-M%20-%20Privilege%20Escalation%20on%20LPC55S69.mp4">presented</a>
on it in more detail. Fundamentally, setting up TrustZone-M is simply a matter
of putting the right values in the right registers. The word "simply" is, of
course, doing a lot of heavy lifting here. TrustZone-M must also be set up
in conjunction with the Memory Protection Unit (MPU) and any other vendor
specific security settings. Once the ideal settings have been decided upon,
there&#8217;s still the matter of actually performing the register programming
sequence. NXP offers a feature called TrustZone preset data to make this
programming easier. Register data may optionally be appended to the end of
an image for the LPC55S69, and the ROM will set the registers before jumping
into the user image. Some of those registers may also be configured to
prevent futher modification. This means the user image does not need to be
concerned with the settings for those registers.</p></div><div class="paragraph"><p>The structure used to configure the registers looks like the <a href="https://github.com/nxp-mcuxpresso/spsdk/blob/09c711a8fd4c54f126a7dfe1b3ae8bb361c5473e/spsdk/data/tz_presets/lpc55s6x.yaml">following</a>:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code class="language-c" data-lang="c"><span style="color:#C6A5EA">typedef</span><span style="color:#C6A5EA"> struct</span><span style="color:#E7E7E8"> _tzm_secure_config</span><br><span style="color:#A1A4A5">{</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_vtor_addr</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">  /*! CM33 Secure vector table address */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_vtor_ns_addr</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! CM33 Non-secure vector table address */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_nvic_itns0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! CM33 Interrupt target non-secure register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_nvic_itns1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! CM33 Interrupt target non-secure register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> mcm33_vtor_addr</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MCM33 Secure vector table address */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_ctrl</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Control Register.*/</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_mair0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Memory Attribute Indirection Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_mair1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Memory Attribute Indirection Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 0 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 0 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 1 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 1 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar2</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 2 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar2</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 2 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar3</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 3 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar3</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 3 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar4</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 4 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar4</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 4 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar5</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 5 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar5</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 5 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar6</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 6 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar6</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 6 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar7</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 7 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar7</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MPU Region 7 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_ctrl_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Control Register.*/</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_mair0_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Memory Attribute Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_mair1_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Memory Attribute Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar0_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 0 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar0_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 0 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar1_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 1 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar1_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 1 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar2_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 2 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar2_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 2 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar3_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 3 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar3_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 3 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar4_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 4 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar4_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 4 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar5_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 5 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar5_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 5 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar6_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 6 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar6_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 6 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rbar7_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 7 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_mpu_rlar7_ns</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! Non-secure MPU Region 7 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_ctrl</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rbar0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 0 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rlar0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 0 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rbar1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 1 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rlar1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 1 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rbar2</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 2 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rlar2</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 2 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rbar3</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 3 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rlar3</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 3 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rbar4</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 4 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rlar4</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 4 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rbar5</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 5 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rlar5</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 5 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rbar6</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 6 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rlar6</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 6 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rbar7</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 7 Base Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_sau_rlar7</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! SAU Region 7 Limit Address Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> flash_rom_slave_rule</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! FLASH/ROM Slave Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> flash_mem_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! FLASH Memory Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> flash_mem_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! FLASH Memory Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> flash_mem_rule2</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! FLASH Memory Rule Register 2 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> rom_mem_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! ROM Memory Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> rom_mem_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! ROM Memory Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> rom_mem_rule2</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! ROM Memory Rule Register 2 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> rom_mem_rule3</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! ROM Memory Rule Register 3 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ramx_slave_rule</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ramx_mem_rule0</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram0_slave_rule</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram0_mem_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! RAM0 Memory Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram0_mem_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! RAM0 Memory Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram1_slave_rule</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! RAM1 Memory Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram1_mem_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! RAM1 Memory Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram2_mem_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! RAM2 Memory Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram3_mem_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! RAM3 Memory Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram3_mem_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! RAM3 Memory Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram4_slave_rule</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram2_mem_rule0</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram3_slave_rule</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram1_mem_rule0</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram2_slave_rule</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ram4_mem_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! RAM4 Memory Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> apb_grp_slave_rule</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! APB Bridge Group Slave Rule Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> apb_grp0_mem_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! APB Bridge Group 0 Memory Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> apb_grp0_mem_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! APB Bridge Group 0 Memory Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> apb_grp0_mem_rule2</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! APB Bridge Group 0 Memory Rule Register 2 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> apb_grp0_mem_rule3</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! APB Bridge Group 0 Memory Rule Register 3 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> apb_grp1_mem_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! APB Bridge Group 1 Memory Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> apb_grp1_mem_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! APB Bridge Group 1 Memory Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> apb_grp1_mem_rule2</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! APB Bridge Group 1 Memory Rule Register 2 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> apb_grp1_mem_rule3</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! APB Bridge Group 1 Memory Rule Register 3 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ahb_periph0_slave_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! AHB Peripherals 0 Slave Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ahb_periph0_slave_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! AHB Peripherals 0 Slave Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ahb_periph1_slave_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! AHB Peripherals 1 Slave Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ahb_periph1_slave_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! AHB Peripherals 1 Slave Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ahb_periph2_slave_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! AHB Peripherals 2 Slave Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ahb_periph2_slave_rule1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! AHB Peripherals 2 Slave Rule Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> ahb_periph2_mem_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! AHB Peripherals 2 Memory Rule Register 0*/</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> usb_hs_slave_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! HS USB Slave Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> usb_hs__mem_rule0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! HS USB Memory Rule Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> sec_gp_reg0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! Secure GPIO Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> sec_gp_reg1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! Secure GPIO Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> sec_gp_reg2</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! Secure GPIO Register 2 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> sec_gp_reg3</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! Secure GPIO Register 3 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> sec_int_reg0</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! Secure Interrupt Mask for CPU1 Register 0 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> sec_int_reg1</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! Secure Interrupt Mask for CPU1 Register 1 */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> sec_gp_reg_lock</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! Secure GPIO Lock Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> master_sec_reg</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! Master Secure Level Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> master_sec_anti_pol_reg</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> cm33_lock_reg</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! CM33 Lock Control Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> mcm33_lock_reg</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5"> /*! MCM33 Lock Control Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> misc_ctrl_dp_reg</span><span style="color:#A1A4A5">;</span><span style="color:#A1A4A5">/*! Secure Control Duplicate Register */</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> misc_ctrl_reg</span><span style="color:#A1A4A5">;</span><br><span style="color:#C6A5EA">  uint32_t</span><span style="color:#E7E7E8"> misc_tzm_settings</span><span style="color:#A1A4A5">;</span><br><span style="color:#A1A4A5">}</span><span style="color:#EDD5A6"> tzm_secure_config_t</span><span style="color:#A1A4A5">;</span></code></pre></div></div><div class="paragraph"><p>An implementation detail of the ROM is that the settings for these registers
are (mostly) applied in the order shown in the structure. This means that the
very first register that gets changed is <code>VTOR</code> which switches the vector
table from the one in the ROM to the user provided one. <strong>Any faults that
occur after <code>VTOR</code> is changed will be handled by user code, not ROM
code.</strong> This turns out to have some "interesting" side effects.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_unlocking_debug_access" aria-hidden="true"></span><a class="link group" href="#_unlocking_debug_access">(Un)locking debug access<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The LPC55S69 offers debug access via <a href="https://developer.arm.com/documentation/ihi0031/g/?lang=en">standard ARM interfaces (SWD)</a>.
Debug access can be configured to be always available, always disabled, or
only available to authenticated users. These settings are designed to be
applied at manufacturing time via the <a href="https://github.com/nxp-mcuxpresso/spsdk/blob/09c711a8fd4c54f126a7dfe1b3ae8bb361c5473e/spsdk/data/pfr/cmpa/lpc55s6x_1b.xml">CMPA</a> region.
Debugging is disabled by default while executing in the ROM and only enabled
(if allowed) as the very last step before jumping to user code. The debug
settings are also locked out, preventing further modification from user code
except in specific authenticated circumstances. Because debug access is highly
sensitive, it makes sense to minimize the amount of time the ROM spends with
it enabled.</p></div><div class="paragraph"><p>If the debug settings are applied last, this means that the TrustZone preset
settings must be applied before them. Combine this information with the
implementation detail of how the preset setting are applied, <strong>if the code
faults after <code>VTOR</code> is changed but before we apply the debug settings, it
will be possible to run in user controlled code with debug registers open
for modification</strong>.</p></div><div class="paragraph"><p>How easy is it to actually trigger this? Very easy. Other registers in the
preset structure include settings for the MPU. Setting the enable bit in
<code>MPU_CTRL</code> without any other regions set is enough to trigger
the fault. NXP actually says in their manual that you need to make sure
the entire ROM region is configured as secure privileged and executable
otherwise "boot process will fail". "fail" in this case is vectoring off
into the appropriate fault handler of the user code.</p></div><div class="paragraph"><p>This makes the following sequence possible:</p></div><div class="ulist"><ul class=""><li><p>Have debug disabled in the CMPA</p></li><li><p>Sign an image with TrustZone preset settings with a valid <code>VTOR</code> and MPU
settings that exclude the ROM region</p></li><li><p>Have the <code>MemManage</code> fault handler follow the standard sequence to enable
debugging</p></li><li><p>The image will trigger the fault handler and have debugging enabled despite
the settings in the CMPA</p></li></ul></div><div class="paragraph"><p>This does require access to the secure boot signing key, but it&#8217;s a departure
from the presentation of the CMPA settings as being independent of any
possible settings in an image.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_extracting_the_uds" aria-hidden="true"></span><a class="link group" href="#_extracting_the_uds">Extracting the UDS<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>One additional step in the setting of the debug registers is a final lockout
of some PUF registers. The PUF (Physically Unclonable Function) is designed to
tie secrets to a specific chip. When a secret is PUF encoded, it can only
be decoded by that specific chip. The LPC55S69 uses the PUF to encode the
Unique Device Secret (UDS) for use as the basis of a <a href="https://trustedcomputinggroup.org/work-groups/dice-architectures/">DICE</a> identity.
To ensure the identity is tied to the specific chip and cannot be cloned,
access to the PUF index for the UDS is locked out after it is used.</p></div><div class="paragraph"><p>The UDS is always locked out for secure boot images, but the ROM relies on
the code path for debug settings to lock out for non-secure images.
TrustZone preset settings can be used with non-secure CRC images which means
that the previously described issue can be used to extract the UDS since the
final lockout will never occur.</p></div><div class="paragraph"><p>Requiring an unsigned image significantly limits the impact to
cases such as the following:</p></div><div class="ulist"><ul class=""><li><p>Attacker at manufacturing time runs ISP command to generate the UDS on an
unprogrammed LPC55S69</p></li><li><p>Attacker runs an unsigned image with a buggy TrustZone preset to extract the
UDS</p></li><li><p>Attacker continues on with the rest of the manufacturing sequence, making
sure not to re-generate the extracted UDS</p></li></ul></div><div class="paragraph"><p>This may be mitigated with sufficient tooling at manufacturing time but the
issue still remains.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_is_this_a_security_issue" aria-hidden="true"></span><a class="link group" href="#_is_this_a_security_issue">Is this a security issue?<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>There was disagreement between Oxide and NXP about whether this qualified
as a true security vulnerability (Oxide&#8217;s opinion) vs. a gap in design and
documentation (NXP&#8217;s opinion). The areas of disagreement were related to what
exactly it was possible to do with these issues and what was
required to make them happen. Unlocking the debug ports requires access to the
secure boot signing keys and arguably if you can sign something with a bad
TrustZone preset you don&#8217;t need to bother with debug port access; once your
secure boot integrity has been compromised all bets are off. Oxide believes
this undersells the potential for mitigation and why this should be considered
a security issue: there could be circumstances where having debug port access
would make extracting assets significantly easier.</p></div><div class="paragraph"><p>Transparency is an Oxide value and that is what we strive for in bug reporting.
Our goal is to make sure that issues are acknowledged and information about
the bug is made widely available. NXP agreed to acknowledge this issue as
a non-security errata and there will not be a CVE filed at this time. Given
the narrow scope and lack of agreement between Oxide and NXP, filing a CVE
would provide <a href="https://daniel.haxx.se/blog/2023/08/26/cve-2020-19909-is-everything-that-is-wrong-with-cves/">little benefit</a>.
If new information were to come to light from Oxide, NXP, or other
researchers who are interested in our findings, we would re-evaluate this
decision.</p></div><div class="paragraph"><p>We are pleased that NXP is choosing to protect its customers by informing them
of this gap. A bigger takeaway from this issue is to understand the limitations
of secure/verified boot. A proper secure boot implementation will ensure that
the only code that runs on a device is code that has been signed with an
appropriate private key. Secure boot provides no assertions about the
implementation of that code. <strong>The strength of secure boot is bounded by the
code you choose to sign</strong>. In the absence of a fix for this errata, we will
not be using the TrustZone preset data. If other customers choose to continue
using TrustZone preset data they will need to be diligent about validating
their inputs to avoid introducing gaps in the security model. Oxide has a
commitment to open firmware to ensure our customers can have confidence in
what code we will be signing to run on their machines.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_timeline" aria-hidden="true"></span><a class="link group" href="#_timeline">Timeline<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_2023_08_16" aria-hidden="true"></span><a class="link group" href="#_2023_08_16">2023-08-16<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Oxide discovers issue while reviewing image settings</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_2023_08_21" aria-hidden="true"></span><a class="link group" href="#_2023_08_21">2023-08-21<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Oxide discloses issue to NXP PSIRT with a disclosure deadline of 2023-11-20</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_2023_08_21_2" aria-hidden="true"></span><a class="link group" href="#_2023_08_21_2">2023-08-21<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Oxide PSIRT acknowledges receipt</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_2023_10_11" aria-hidden="true"></span><a class="link group" href="#_2023_10_11">2023-10-11<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>NXP requests meeting to discuss the report with Oxide</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_2023_10_19" aria-hidden="true"></span><a class="link group" href="#_2023_10_19">2023-10-19<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Oxide and NXP meet to discuss the reported issues</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_2023_10_23" aria-hidden="true"></span><a class="link group" href="#_2023_10_23">2023-10-23<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Oxide suggests documentation clarifications</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_2023_10_27" aria-hidden="true"></span><a class="link group" href="#_2023_10_27">2023-10-27<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>NXP agress to issue an errata</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_2023_11_20" aria-hidden="true"></span><a class="link group" href="#_2023_11_20">2023-11-20<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Oxide publishes this blog post as a disclosure</p></div></div></div></div></div></div>]]></content>
        <author>
            <name>Laura Abbott</name>
        </author>
        <contributor>
            <name>Laura Abbott</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[The Cloud Computer]]></title>
        <id>https://oxide.computer/blog/the-cloud-computer</id>
        <link href="https://oxide.computer/blog/the-cloud-computer"/>
        <link rel="enclosure" href="https://oxide.computer/img/blog/the-cloud-computer/oxide-pcb-closeup.jpg" type="image/jpg"/>
        <updated>2023-10-26T09:00:00.000Z</updated>
        <summary type="html"><![CDATA[Announcing the world's first commercial cloud computer.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>Today we are announcing the general availability of the world&#8217;s first
commercial cloud computer — along with
<a href="https://oxide.computer/blog/oxide-unveils-the-worlds-first-commercial-cloud-computer">our $44M Series A financing</a>.</p></div><div class="paragraph"><p>From the outset at Oxide, and as I outlined in
<a href="https://www.youtube.com/watch?v=vvZA9n3e5pc">my 2020 Stanford talk</a>,
we have had three core beliefs as a company:</p></div><div class="olist arabic"><ol class="arabic"><li class=""><p>Cloud computing is the future of all computing infrastructure.</p></li><li class=""><p>The computer that runs the cloud should be able to be <strong>purchased</strong> and not
merely rented.</p></li><li class=""><p>Building a cloud computer necessitates a rack-level approach — and the
co-design of both hardware and software.</p></li></ol></div><div class="paragraph"><p>Of these beliefs, the first is not at all controversial: the agility,
flexibility, and scalability of cloud computing have been indisputably
essential for many of the services that we depend on in the modern economy.</p></div><div class="paragraph"><p>The degree that the second belief is controversial, however, depends on who you
are:  for those that are already running on premises due to security,
regulatory, economic, or latency reasons, it is self-evident that computers
should be able to be purchased and not merely rented.  But to others, this has
been more of a revelation — and since we started Oxide, we have found more and
more people realize that the rental-only model for the cloud is not
sustainable.  Friends love to tag us on links to
<a href="https://a16z.com/the-cost-of-cloud-a-trillion-dollar-paradox/">VC thinkpieces</a>,
<a href="https://world.hey.com/dhh/why-we-re-leaving-the-cloud-654b47e0">CTO rants</a>, or
<a href="https://www.idc.com/getdoc.jsp?containerId=IDC_P20184">analyst reports on
industry trends</a> — and we love people thinking of us, of course (even when
being tagged for the dozenth time!) — but the only surprise is how surprising
it continues to be for some folks.</p></div><div class="paragraph"><p>The third belief — that the development of a cloud computer necessitates
rack-scale design of both hardware <em>and</em> software — may seem iconoclastic to
those who think only in terms of software, but it is in fact not controversial
among technologists: as computing pioneer Alan Kay famously observed, "people
who are really serious about software should make their own hardware." This is
especially true in cloud computing, where the large public cloud companies
have long ago come to the conclusion that they needed to be designing their
own holistic systems.  But if this isn&#8217;t controversial, why hasn&#8217;t there been
a cloud computer before Oxide&#8217;s?  First, because <strong>it&#8217;s big</strong>:  to meaningfully
build a cloud computer, one must break out of the shackles of the 1U or 2U
server, and really think about the rack as the unit of design.  Second,
it hasn&#8217;t been done because <strong>it&#8217;s hard</strong>:  co-designing hardware and
software that spans compute, networking, and storage requires building an
extraordinary team across disparate disciplines, coupling deep expertise with
a strong sense of versatility, teamwork, and empathy.  And the team isn&#8217;t
enough by itself: it also needs courage, resilience, and (especially) time.</p></div><div class="paragraph"><p>So the biggest question when we set out was not "is the market there?" or "is
this the right way to do it?", but rather <strong>could we pull this off?</strong></p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_pulling_it_off" aria-hidden="true"></span><a class="link group" href="#_pulling_it_off">Pulling it off<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>We have indeed
<a href="https://oxide.computer/product/specifications">pulled it off</a> — and it&#8217;s been a
wild ride!  While we have talked about the trek quite a bit on our podcast,
<a href="https://oxide-and-friends.transistor.fm">Oxide and Friends</a> (and
specifically, <a href="https://oxide-and-friends.transistor.fm/episodes/shipping-the-first-oxide-rack-your-questions-answered">Steve
and I recently answered questions about the rack</a>), our general availability
is a good opportunity to reflect on some of the first impressions that the
Oxide cloud computer has made upon those who have seen it.</p></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_where_are_all_the_boxes" aria-hidden="true"></span><a class="link group" href="#_where_are_all_the_boxes">&quot;Where are all the boxes?&quot;<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>The traditional rack-and-stack approach starts with a sea of boxes arriving
with servers, racks, cabling, etc.  This amounts to a literal
<a href="https://en.wikipedia.org/wiki/Kit_car">kit car</a> approach — and it starts with
tedious, dusty, de-boxing.  But the Oxide rack ships with everything installed
and comes in just <strong>one</strong> box — a crate that is
<a href="https://oxide-and-friends.transistor.fm/episodes/tales-from-manufacturing-shipping-rack-1">its own feat of
engineering</a>.  All of this serves to dramatically reduce the latency from
equipment arrival to power on and first provision — from weeks and months to
days or even hours.</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_is_it_on" aria-hidden="true"></span><a class="link group" href="#_is_it_on">&quot;Is it on?&quot;<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>We knew at the outset that rack-level design would afford us the ability to
change the geometry of compute sleds — that we would get higher density in the
rack by trading horizontal real estate for vertical.  We knew, too, that we
were choosing to use 80mm fans for their ability to move more air much more
efficiently — so much so that we leveraged
<a href="https://oxide.computer/blog/navigating-todays-supply-chain-challenges">our
approach to the supply chain</a> to partner with Sanyo Denki (our fan provider) to
lower the minimum speed of the fans from 5K RPM to the 2K RPM that we needed.
But adding it up, the Oxide rack has a surprising aesthetic attribute:  <strong>it is
whisper quiet.</strong>  To those accustomed to screaming servers, this is so
unexpected that when we were
<a href="https://oxide-and-friends.transistor.fm/episodes/oxide-and-the-chamber-of-mysteries">getting FCC
compliance</a>, the engineer running the test sheepishly asked us if we were sure
the rack was on — when it was dissipating 15 kW!  That the rack is quiet wasn&#8217;t
really deliberate (and we are frankly much more interested in the often hidden
power draw that blaring fan noise represents), but it does viscerally embody
much of the Oxide differentiation with respect to both rack-level design and
approach to the supply chain.</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_where_are_the_cables" aria-hidden="true"></span><a class="link group" href="#_where_are_the_cables">&quot;Where are the cables?&quot;<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Anyone accustomed to a datacenter will note the missing mass of cold-aisle
cabling that one typically sees at the front of a rack.  But moving to the back
of the rack reveals only a <a href="https://en.wikipedia.org/wiki/Busbar">DC busbar</a> and
a tight, cabled backplane.  This represents one of the bigger bets we made:
<a href="https://oxide-and-friends.transistor.fm/episodes/cabling-the-backplane">we blindmated
networking</a>.  This was mechanically tricky, but the payoff is huge: capacity
can be added to the Oxide cloud computer simply by snapping in a new compute
sled — nothing to be cabled whatsoever!  This is a domain in which we have
leapfrogged the hyperscalers, who (for their own legacy reasons) don&#8217;t do it
this way.  This can be jarring to veteran technologists.  As one exclaimed upon
seeing the rack last week, "I am both surprised and delighted!" (Or rather:
a very profane variant of that sentiment.)</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_you_did_your_own_switch_too" aria-hidden="true"></span><a class="link group" href="#_you_did_your_own_switch_too">&quot;You did your own switch too?!&quot;<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>When we first started the company, one of our biggest technical quandaries was
what to do about the switch.  At some level, both paths seemed untenable:  we
knew from our own experience that integrating with third-party switches would
lead to exactly the kind of integration pain for customers that we sought to
alleviate — but it also seemed outrageously ambitious to do our own switch in
addition to everything else we were doing.  But as we have many times over the
course of Oxide, we opted for the steeper path in the name of saving our
customers grief, choosing to
<a href="https://oxide-and-friends.transistor.fm/episodes/the-sidecar-switch-2021-11-29">build our own
switch</a>.  If it has to be said,
<a href="https://oxide-and-friends.transistor.fm/episodes/bringup-lab-chronicles-a-measurement-two-years-in-the-making">getting it working
isn&#8217;t easy</a>!  And of course, building the switch is insufficient: we also
needed to <a href="https://oxide-and-friends.transistor.fm/episodes/rack-scale-networking">build our
own networking software</a> — to say nothing of the
<a href="https://oxide-and-friends.transistor.fm/episodes/the-network-behind-the-network">management network</a>
required to be able to manage compute sleds when they&#8217;re powered off.</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_wait_thats_part_of_it" aria-hidden="true"></span><a class="link group" href="#_wait_thats_part_of_it">&quot;Wait, <em>that’s</em> part of it?!&quot;<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>It&#8217;s one thing to say that all of the software that one needs to operate the
cloud computer is built in — but it&#8217;s another to actually see what that
software includes.  And for many, it&#8217;s seeing the
<a href="https://github.com/oxidecomputer/console">Oxide web console</a> (or its
<a href="https://oxide-console-preview.vercel.app/">live demo</a>!) that really drives the
message home:  yes, <strong>all</strong> of the software is included.  And because the
<a href="https://oxide-and-friends.transistor.fm/episodes/the-frontend-of-the-computer">console
implementation</a> is built on the <a href="https://docs.oxide.computer/">public API</a>,
everything that one can do in the console for the Oxide rack is also available
via CLI and API — a concrete manifestation of our
<a href="https://www.youtube.com/watch?v=EmSjZbSzA3A">code-as-contract</a> approach.</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_and_theres_no_separate_licensing" aria-hidden="true"></span><a class="link group" href="#_and_theres_no_separate_licensing">&quot;And there’s no separate licensing?&quot;<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>One common source of pain for users of on-prem infrastructure has been license
management: financial pain due to over-paying and under-utilizing, and
operational pain in the navigation of different license terms, different
expiration dates, unpredictable dependencies, and
<a href="https://www.theregister.com/2022/05/31/vmware_broadcom_acquisition_customer_reaction/">uncertain
vendor futures</a>.  From the beginning we knew that we wanted to deliver a
delightful, integrated experience:  we believe that cloud computers should come
complete with all system software built-in, and with no additional licensing to
manage or to pay for.  Bug fixes and new features are always only an update
away and do not require a multi-departmental discussion to determine value and
budget.</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_its_all_open_source" aria-hidden="true"></span><a class="link group" href="#_its_all_open_source">&quot;It’s all open source?&quot;<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>While the software is an essential part of the Oxide cloud computer, what we
sell is in fact the computer.  As <a href="https://www.youtube.com/watch?v=um5bC20NTQ0">a
champion of open source</a>, this allows Oxide a particularly straightforward open
source strategy:  <a href="https://github.com/oxidecomputer/">our software is all open</a>.
So you don&#8217;t need to worry about hinky open core models or relicensing
surprises.  And from a user perspective, you are assured levels of transparency
that you don&#8217;t get in the public cloud — let alone the proprietary on-prem
world.</p></div></div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_getting_your_own_first_impression" aria-hidden="true"></span><a class="link group" href="#_getting_your_own_first_impression">Getting your own first impression<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>We&#8217;re really excited to have the first commercial cloud computer — and for
it to be generally available!  If you yourself are interested, we look
forward to it making its first impression on you —
<a href="https://oxide.computer/sales">reach out to us</a>!</p></div></div></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Building Big Systems with Remote Hardware Teams]]></title>
        <id>https://oxide.computer/blog/building-big-systems-with-remote-hardware-teams</id>
        <link href="https://oxide.computer/blog/building-big-systems-with-remote-hardware-teams"/>
        <link rel="enclosure" href="https://oxide.computer/img/blog/small-boards/psc-closeup.jpg" type="image/jpg"/>
        <updated>2023-03-08T15:30:00.000Z</updated>
        <content type="html"><![CDATA[<link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fdimmlet.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fdimmlet.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fdimmlet.webp&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fk2r2.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fk2r2.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fk2r2.webp&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini.webp&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet.webp&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet-and-periphs.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet-and-periphs.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet-and-periphs.webp&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini-rot-zoom.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini-rot-zoom.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini-rot-zoom.webp&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><div id="content" class="asciidoc-body w-full"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>The product we&#8217;re building, a rack-scale computer, is specifically designed to
be a centralized, integrated product because that&#8217;s what our customers need.
This requirement and the design choices we&#8217;ve made to meet this need
create some daily efficiency challenges for our team. As a remote-first company,
we&#8217;re designing this product with team members (including the hardware team)
across most North American time zones and even multiple continents, so a large
portion of our team is not going into the office/lab every day for hands-on
access to "production" hardware. At first blush, the design of our product and
the design of our team appear to conflict at some level: we value remote work,
but we can&#8217;t ship entire racks to the homes of our teammates for both practical
and economic reasons.</p></div><div class="paragraph"><p>Our racks are rather inconvenient for a home installation: over 2.3 m (7.7')
tall, very heavy, and have 3-phase power inputs that aren&#8217;t usable in a typical
residential setting. Aside from the logistical challenges of a home
installation, there&#8217;s also the actual cost: these are expensive, and
outfitting each remote team member with a full, or even partially populated,
rack is economically infeasible. Further, a racked target is not terribly useful
for development, as accessing them for debugging is challenging: we
have no externally accessible debugging interfaces or other things that can be
repurposed as such because our customers don&#8217;t want that stuff! We can (and do!)
travel some to get hands-on with a full system, but it became clear early on in
the development cycle that we needed more convenient ways of being productive
remotely.</p></div><div class="paragraph"><p>Remote productivity on this design is a multi-faceted problem and the solution
includes robust remote access to fully-built and partially built systems back
at HQ, but that alone does not address all the needs.</p></div><div class="paragraph"><p>This post will deal more with the philosophy we have developed around our
non-product board designs as we&#8217;ve learned what works for us on our journey
through remote development. Some of these tools have become pivotal in
increasing our remote efficiency, especially early in the design cycle when the
"real" systems weren&#8217;t very functional and remote accessibility was limited.
For more board-by-board specifics, check out a great
<a href="https://oxide.computer/podcasts/oxide-and-friends/1173990">Oxide and Friends
episode</a> where we talked through the genesis of many of
these designs. With many of our team members who designed these
boards on-hand, it was a great discussion and a lot of fun talking about the
role prototypes have played in facilitating our actual product design.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_not_a_distraction_from_real_product_design" aria-hidden="true"></span><a class="link group" href="#_not_a_distraction_from_real_product_design">Not a distraction from &quot;real&quot; product design<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>We fully believe that these small designs, most of which end up taking around a
week of engineering time to design, have <strong>radically</strong> accelerated or augmented
our "real" product designs. I detail a couple of specific examples of how this
prototype hardware helped us, from enabling software work before any "real"
hardware existed, to prototyping circuits like our multiplexed QSPI flash
design. Specifically for the QSPI design, the initial circuit just did not work
like we expected and using these boards we were able to quickly (and
inexpensively!) iterate on the design, directly informing the work on our "real"
designs, and in this case, likely saving a spin of our production hardware that
wouldn&#8217;t have worked. We were even able to connect our SPI mux to extant
development hardware from AMD and validate our assumptions before building a
server sled. The Oxide and Friends episode mentioned above covers some of these
and other stories in more detail.</p></div><div class="paragraph"><p>Our team fully embraces toolmaking up and down the stack: it informs many of our
design choices and directions. Bryan recently gave a
<a href="https://www.p99conf.io/session/sharpening-the-axe-the-primacy-of-toolmaking/">talk</a>
on the concept, and this is yet another application of it. Just like software
teams build tools to help build software, we&#8217;re building hardware tools to help
build hardware and software.</p></div><div class="paragraph"><p>To emphasize how pervasive this culture is in our company,
<a href="https://discord.com/channels/1042492311080288306/1064708202962354258/1064736636077867078">Dan</a>
made a great point during the Oxide and Friends chat:</p></div><div class="quoteblock"><blockquote>Anyone in the company is empowered to do this.</blockquote></div><div class="paragraph"><p>We don&#8217;t need approval or sign-off, we just go do what&#8217;s right for Oxide, and I
think this quote from
<a href="https://www.linkedin.com/feed/update/urn:li:activity:7022200431799934976?updateEntityUrn=urn%3Ali%3Afs_feedUpdate%3A%28V2%2Curn%3Ali%3Aactivity%3A7022200431799934976%29">Aaron</a>
really sums up our team&#8217;s viewpoint:</p></div><div class="quoteblock"><blockquote>Investments in tools pay off long-term and often faster than you&#8217;d think!</blockquote></div><div class="paragraph"><p>We&#8217;ve seen time and time again the effort put into these small boards has paid
back big dividends in team productivity, development ease, and bug chasing.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_why_we_needed_custom_hardware_vs_off_the_shelf_development_boards" aria-hidden="true"></span><a class="link group" href="#_why_we_needed_custom_hardware_vs_off_the_shelf_development_boards">Why we needed custom hardware vs off-the-shelf development boards<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>There are multiple aspects to our need for custom hardware. First, the custom
designs supplement our use of off-the-shelf (OTS) hardware. We use <strong>many</strong>
off-the-shelf development boards and even provide
<a href="https://github.com/oxidecomputer/hubris#flash">support</a> for a number of these
boards in <a href="https://github.com/oxidecomputer/hubris">Hubris</a>. These are great for
many use-cases, but less great when we are trying to model specific circuits or
subsystems of our product designs. Second, we have numerous examples of custom
boards that were built simply because we could find no useful OTS alternative:
boards like the Dimmlet (I<sup>2</sup>C access to DDR4 SPD EEPROMs) and the K.2 (U.2 &#8594;
PCIEx4 CEM breakout) fall into this category.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fdimmlet.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fdimmlet.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fdimmlet.webp&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fdimmlet.webp&amp;w=1440&amp;q=90" alt="Narrow PMOD-interface board for interfacing with the SPD EEPROMs on the two installed DDR4 DIMMs"/></div><div class="title">Narrow PMOD-interface board for interfacing with the SPD EEPROMs on the two installed DDR4 DIMMs</div></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fk2r2.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fk2r2.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fk2r2.webp&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fk2r2.webp&amp;w=1440&amp;q=90" alt="PCIe U.2 connector to PCIe x4 CEM connector extender board"/></div><div class="title">PCIe U.2 connector to PCIe x4 CEM connector extender board</div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_thriftiness_in_practice" aria-hidden="true"></span><a class="link group" href="#_thriftiness_in_practice">Thriftiness in practice<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>While this strategy of developing prototypes touches on many Oxide values (as
discussed below), Thriftiness deserves special attention. Making inexpensive
hardware has never been easier! Quick-turn PCB houses, both offshore and
onshore, have achieved incredibly low cost while maintaining high quality. We
had 50 K.2r2 PCBs with impedance control and a framed stencil fabricated for
&lt;$400USD. For something so simple (BOM count &lt;10 parts) we built these in-house
using an open-source pick and place machine (Lumen PNP from
<a href="https://opulo.io/">Opulo</a>), and a modified toaster oven with a
<a href="https://www.whizoo.com/controleo3">Controleo3</a> controller. We&#8217;ve also done
hot-plate reflow and hand assembly. And while we will outsource assembly when it
makes sense due to complexity or volume, for these simple, low volume designs,
we see real benefits in self-building: we can build as few or as many as we
want, do immediate bring-up and feed any rework directly into the next batch,
and there&#8217;s no overhead in working with a supplier to get kitted parts there,
quotes, questions etc. A good example of this was on the Dimmlet: I messed up
the I<sup>2</sup>C level translator circuit by missing the chip&#8217;s requirements about
which side was connected to the higher voltage. Since I was hand-assembling
these, I built one, debugged it, and figured out the rework required to make it
function. Since this rework included flipping the translator and cutting some
traces, catching this issue on the first unit made reworking the remaining ones
<strong>before</strong> going through assembly much easier.</p></div><div class="paragraph"><p>All of that to say, the cost of building small boards is really low. A single
prototype run that saves a "real" board re-spin pays for itself immediately.
Enabling software development before "real" hardware lands pays for itself
immediately. Even when things don&#8217;t work out, the cost of failure is low; we
lost a few hundred dollars and some engineering time, but learned something in
the process.</p></div><div class="paragraph"><p>Because of this low cost, we can use a "looser" design process, with fewer
tollgates and a less formal review/approval process. This lowers the
engineering overhead required to execute these designs. We can have more
informal reviews, a light-weight (if any) specification and allow design
iteration to happen naturally. Looking at the designs, we have multiple examples
of design refinement like the K.2r2 which improved on the electrical and
mechanical aspects of the original K.2, and a refinement to the sled&#8217;s bench
power connector boards resulting in a more compact and ergonomic design that
improves mating with sleds in their production sheet metal.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_experience_and_the_evolution_of_our_strategy" aria-hidden="true"></span><a class="link group" href="#_experience_and_the_evolution_of_our_strategy">Experience and the evolution of our strategy<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Early in our company&#8217;s history, the team built out a development platform,
named the Gemini Bring-up board, representing the core of the embedded
design for our product-- our Gemini complex (Service Processor + Root of Trust<br>
Management Network plane). The resulting platform was a very nice development
tool, with hilarious silkscreen and some awesome ideas that have continued
informing current and future designs, but we rapidly outgrew this first design.
While the major choices held, such as which microcontrollers are present, the
still-nebulous design of the actual product, and subsequent design iteration,
left the periphery of the bring-up board bearing little resemblance to the
final Gemini complex design. The changes came from a variety of unforeseen
sources: the global chip shortage forced BOM changes and a better understanding
of the constraints/needs of our product necessitated architecture changes,
resulting in further drift between this platform and what we intended to
implement in the product.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini.webp&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini.webp&amp;w=1440&amp;q=90" alt="First custom Oxide hardware with SP"/></div><div class="title">First custom Oxide hardware with SP and RoT</div></div><div class="paragraph"><p>A re-imagining of what would be most useful gave way to the Gimletlet, a major
work-horse for in-house development, designed (and initially hot-plate reflowed) by
Cliff. The Gimletlet is essentially a development board using the STM32H7 part
that we&#8217;re using as our Service Processor (SP) in our product. It provides power
and basic board functionality including a couple of LEDs, and a dedicated
connector for a network breakout card, and breaks out most of the remaining I/O
to PMOD-compatible headers. This choice has been key to enabling a very modular
approach to prototyping, recognizing that less is more when it comes to
platforms. The Gimletlet design means that we can build purpose-built interface
cards without needing to worry about network connectivity or processor support,
simplifying the design of the interface cards and able to share a core board
support package.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet.webp&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet.webp&amp;w=1440&amp;q=90" alt="Custom STM32H7 board with I/O breakout to many PMOD interfaces"/></div><div class="title">Custom STM32H7 board with I/O breakout to many PMOD interfaces</div></div><div class="paragraph"><p>Our team has learned that modularity is key to making these small proto-boards
successful. It does mean workspaces can get a little messy with a bunch of
boards connected together, but we&#8217;ve found this to be a good balance, allowing
our team members to cobble together a small, purpose-built system that meets
their specific needs, and allows us to easily share these common, low-cost
setups to our distributed team. The modularity also means that storing them is
relatively easy as they can be broken down and stashed in small boxes.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet-and-periphs.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet-and-periphs.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet-and-periphs.webp&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgimletlet-and-periphs.webp&amp;w=1440&amp;q=90" alt="Gimletlet with Igntionlet"/></div><div class="title">Gimletlet with Igntionlet, SPI MUx, Dimmlet, RoTCarrierCarrier, and RoTCarrier connected</div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_our_values_tie_ins" aria-hidden="true"></span><a class="link group" href="#_our_values_tie_ins">Our values tie-ins<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>There are some obvious <a href="/principles#values">values</a> tie-ins like teamwork and
thriftiness as already mentioned, but as I started writing this section I
realized we hit more of our values than I had even realized. Rather than attempt
to enumerate each one, I wanted to hit on some maybe less-obvious ones:</p></div><div class="ulist"><ul class=""><li><p>Humor: The silkscreens on our boards contain jokes, word-play and other
silliness because we enjoy making our co-workers laugh and want our work to be
fun too. The funny silkscreen is often snuck in post-review, and thus
a surprise to co-workers as they open the finished hardware.
Engineering demands creativity — I&#8217;ve worked at places where silliness baked
into a board would be frowned upon, but at Oxide it is supported and even
encouraged! This enables team members to bake a little bit of their personality
into these designs, while allowing the rest of the team to have fun as it&#8217;s
discovered.</p></li></ul></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini-rot-zoom.webp&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini-rot-zoom.webp&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini-rot-zoom.webp&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fsmall-boards%2Fgemini-rot-zoom.webp&amp;w=1440&amp;q=90" alt="Gemini Bring up board with silkscreen riffing on Root of Trust vs Route of Trust vs Newt of Trust as well as pointing out the untrustworthiness of vendor boot ROMs"/></div><div class="title">Preview of Gemini Bring up board</div></div><div class="ulist"><ul class=""><li><p>Rigor/Urgency: We often find Rigor and Urgency in tension with each other,
but in this case, they are complementary. The time from concept to ordering of
a PCB on some of these designs is measured in hours or days, not weeks. Being
able to move quickly from a paper concept to a physical manifestation of that
concept in real hardware has been instrumental in grounding our assumptions and
informing our designs. We&#8217;re able to quickly iterate in areas where we have
questions, driving resolution without holding up the rest of the design. This
work directly contributes to better architecture and circuit design decisions
in our "real" designs.</p></li><li><p>Transparency/Responsibility/Teamwork: We believe in openness, including our
own designs, so we&#8217;re opening up the various proto-board design repositories
for reference and hope that something there is useful in your own hardware
endeavors. These designs are things that we wished existed and so created them,
some of these may be a bit specific for our use-cases, but there are some
generally useful things there too. These are mostly KiCAD designs and support
for them is "as-is" since we&#8217;re focused on getting our product out the door,
but feel free to reach out in the repo with questions and we&#8217;ll attempt to
answer on a best-effort basis.</p></li></ul></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_our_open_source_hardware_repos" aria-hidden="true"></span><a class="link group" href="#_our_open_source_hardware_repos">Our open source hardware repos<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="ulist"><ul class=""><li><p><a href="https://github.com/oxidecomputer/gemini-bringup">gemini-bringup</a></p></li><li><p><a href="https://github.com/oxidecomputer/hw-lpc55-carrier">RoT-Carrier and Carrier-Carrier</a></p></li></ul></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_gimletlets_peripherals" aria-hidden="true"></span><a class="link group" href="#_gimletlets_peripherals">Gimletlets + peripherals<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="ulist"><ul class=""><li><p><a href="https://github.com/oxidecomputer/hw-gimletlet">Gimletlets (v1 + 2)</a></p></li><li><p><a href="https://github.com/oxidecomputer/hw-ignitionlet">Ignitionlet</a></p></li><li><p><a href="https://github.com/oxidecomputer/hw-spimux">SPI-mux</a></p></li><li><p><a href="https://github.com/oxidecomputer/hw-dimmlet">Dimmlet</a></p></li><li><p><a href="https://github.com/oxidecomputer/hw-gimletlet-nic">GimletletNIC</a></p></li></ul></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_other_designs" aria-hidden="true"></span><a class="link group" href="#_other_designs">Other designs<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="ulist"><ul class=""><li><p><a href="https://github.com/oxidecomputer/hw-k2">k.2</a></p></li><li><p><a href="https://github.com/oxidecomputer/hw-samtec-dbg">debug header breakout</a></p></li><li><p><a href="https://github.com/oxidecomputer/hw-ignition-adapter">iceprog-compatible adafruit breakout</a></p></li></ul></div></div></div></div></div></div>]]></content>
        <author>
            <name>Nathanael Huffman</name>
        </author>
        <contributor>
            <name>Nathanael Huffman</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[A Tool for Discussion]]></title>
        <id>https://oxide.computer/blog/a-tool-for-discussion</id>
        <link href="https://oxide.computer/blog/a-tool-for-discussion"/>
        <link rel="enclosure" href="https://oxide.computer/img/blog/rfd-site/rfd-site-featured-image.png" type="image/png"/>
        <updated>2023-02-02T17:00:00.000Z</updated>
        <summary type="html"><![CDATA[Showcasing a hub for knowledge sharing and collaboration that drives our decision-making process.]]></summary>
        <content type="html"><![CDATA[<link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-directory.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-directory.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-directory.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-search.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-search.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-search.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inline-comments-2.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inline-comments-2.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inline-comments-2.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-discussion.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-discussion.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-discussion.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inter-link.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inter-link.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inter-link.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-jump-to.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-jump-to.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-jump-to.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><div id="content" class="asciidoc-body w-full"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>At Oxide, RFDs (Requests for Discussion) play a crucial role in driving our architectural and design decisions. They document the processes, APIs, and tools that we use. The workflow for the RFD process is based upon those of the Golang proposal process, Joyent RFD process, Rust RFC (Request for Comments) process, and Kubernetes proposal process. To learn more about RFDs and their process, you can read <a href="https://oxide.computer/blog/rfd-1-requests-for-discussion">this post</a>.</p></div><div class="quoteblock"><div class="paragraph"><p>Similar to RFCs, our philosophy of RFDs is to allow both timely
discussion of rough ideas, while still becoming a permanent repository
for more established ones.</p></div></div><div class="paragraph"><p>Oxide RFDs are essentially a collection of AsciiDoc documents, collected in a GitHub repo. They can be quickly iterated on in a branch, discussed actively as part of a pull request to be merged, or commented upon after having been published.</p></div><div class="paragraph"><p>Whilst a repo is a useful storage and collaboration tool, there are a number of drawbacks: it doesn&#8217;t provide the best reading experience, is limited in terms of AsciiDoc support, and is challenging to share externally. To address these issues we developed an internal RFD site. This post serves as showcase for that site and gives a brief look at some of its features.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_rfd_directory" aria-hidden="true"></span><a class="link group" href="#_rfd_directory">RFD directory<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Users land directly on the directory. By default it is sorted by last updated to give the user an idea of the RFDs that are actively being worked on.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-directory.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-directory.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-directory.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-directory.png&amp;w=1440&amp;q=90" alt="RFD site homepage"/></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_full_text_search" aria-hidden="true"></span><a class="link group" href="#_full_text_search">Full-text search<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Full-text search is powered by a self-hosted <a href="https://www.meilisearch.com/">Meilisearch</a> instance. The search index is automatically updated whenever an RFD is edited. Users can access the search function through the navigation menu or by using the hotkey <code>CMD+K</code> and can quickly navigate through the search results using their keyboard whilst previewing the associated RFD.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-search.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-search.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-search.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-search.png&amp;w=1440&amp;q=90" alt="Search dialog showing results and a preview of the matched RFD"/></div></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_inline_pr_discussion" aria-hidden="true"></span><a class="link group" href="#_inline_pr_discussion">Inline PR discussion<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>The discussion surrounding an RFD is crucial to understanding its context, but until recently users would have to open the associated pull request in a separate tab to view its comments. To improve this experience, we&#8217;ve implemented a feature that uses the GitHub API to fetch the pull request discussion and display the comments that are still actively attached to a line alongside the part of the document they relate to.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inline-comments-2.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inline-comments-2.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inline-comments-2.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inline-comments-2.png&amp;w=1440&amp;q=90" alt="Pop-over menu with comments that relate to the part of the document they are next to"/></div><div class="title">Inline comments</div></div><div class="paragraph"><p>We achieve this by using the <code>getLineNumber</code> function in <code>asciidoctor.js</code>, which allows us to map the raw line number of the comment (from the GitHub API) to the nearest block in the rendered document. While this method may not pinpoint the exact line, it is usually accurate enough.</p></div><div class="paragraph"><p>To avoid slowing down page load times, we use the Remix <a href="https://remix.run/docs/en/v1/guides/streaming">deferred response</a> feature to stream in the comments asynchronously, holding only for the critical RFD content to finish loading.</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code class="language-ts" data-lang="ts"><span style="color:#C6A5EA">  const</span><span style="color:#E7E7E8"> rfd </span><span style="color:#A7E0C8">=</span><span style="color:#C6A5EA"> await</span><span style="color:#9DAFFA"> fetchRfd</span><span style="color:#E7E7E8">(num</span><span style="color:#A1A4A5">,</span><span style="color:#E7E7E8"> user)</span><br><span style="color:#C6A5EA">  if</span><span style="color:#E7E7E8"> (</span><span style="color:#A7E0C8">!</span><span style="color:#E7E7E8">rfd) </span><span style="color:#C6A5EA">throw</span><span style="color:#9DAFFA"> resp404</span><span style="color:#E7E7E8">()</span><br><br><span style="color:#A1A4A5">  // this must not be awaited, it is being deferred</span><br><span style="color:#C6A5EA">  const</span><span style="color:#E7E7E8"> discussionPromise </span><span style="color:#A7E0C8">=</span><span style="color:#9DAFFA"> fetchDiscussion</span><span style="color:#E7E7E8">(rfd</span><span style="color:#A7E0C8">.</span><span style="color:#E7E7E8">discussion_link</span><span style="color:#A1A4A5">,</span><span style="color:#E7E7E8"> user)</span><br><br><span style="color:#C6A5EA">  return</span><span style="color:#9DAFFA"> defer</span><span style="color:#E7E7E8">(</span><span style="color:#A1A4A5">{</span><span style="color:#E7E7E8"> rfd</span><span style="color:#A1A4A5">,</span><span style="color:#E7E7E8"> discussionPromise </span><span style="color:#A1A4A5">}</span><span style="color:#E7E7E8">)</span></code></pre></div></div><div class="paragraph"><p>Users can access the full discussion of an RFD at any time by opening a dialog regardless of their current location on the page. This dialog also provides the ability to jump directly to the line that is being commented on.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-discussion.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-discussion.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-discussion.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-site-discussion.png&amp;w=1440&amp;q=90" alt="Dialog with a GitHub PR style timeline showing comments and snippets of the raw document"/></div><div class="title">Full discussion</div></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_inter_rfd_linking" aria-hidden="true"></span><a class="link group" href="#_inter_rfd_linking">Inter-RFD linking<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>When an RFD document references another RFD within its content, the user can hover over the reference to see a preview of the title, authors, status, and the date of the last update. This makes it easy for users to understand the context and relationship between different RFDs, and quickly access the related documents.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inter-link.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inter-link.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inter-link.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-inter-link.png&amp;w=1440&amp;q=90" alt="Pop-over that previews the linked RFD"/></div></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_jump_to_menu" aria-hidden="true"></span><a class="link group" href="#_jump_to_menu">Jump-to menu<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>For users who know the title or number of the RFD they want to view, a menu can be opened by pressing <code>CMD+/</code> from any page on the site. This menu allows users to quickly filter and select the desired RFD using their keyboard.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-jump-to.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-jump-to.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-jump-to.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Frfd-site%2Frfd-jump-to.png&amp;w=1440&amp;q=90" alt="Navigation modal that shows a list of RFDs being filtered by an input"/></div></div></div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_upcoming" aria-hidden="true"></span><a class="link group" href="#_upcoming">Upcoming<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The internal tooling around RFDs is always improving, and as it does, we hope that the way we collaborate will also improve. There is still work to be done in terms of discoverability of documentation, such as adding more tools to filter and tag RFDs, and creating collections of documents. This will make it easier for new employees to get up to speed, and make it easier to manage the challenges that come with a growing team and an increasing amount of documentation. Having a better understanding of the whole stack is valuable, as it allows us to better understand the impact of our work on other parts of the product.</p></div><div class="paragraph"><p>Additionally, we need to consider how we can make this process more accessible to everyone. Writing an RFD currently requires cloning a Git repo, running a script, committing, pushing, and making a PR. We are thinking about how to do this all through the web app with an embedded text editor. Oxide is and will continue to be an engineering-led organization, but RFDs are not just for engineers. Making it easier for everyone to create and collaborate on these documents will result in richer conversations.</p></div></div></div></div>]]></content>
        <author>
            <name>Ben Leonard</name>
        </author>
        <contributor>
            <name>Ben Leonard</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Navigating Today’s Supply Chain Challenges]]></title>
        <id>https://oxide.computer/blog/navigating-todays-supply-chain-challenges</id>
        <link href="https://oxide.computer/blog/navigating-todays-supply-chain-challenges"/>
        <updated>2022-09-08T17:00:00.000Z</updated>
        <summary type="html"><![CDATA[The tale of a small tech startup navigating procurement in the most constrained market in recent history.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>We’ve all experienced it. From toilet paper, exercise equipment, toys, cars, and everything in between, the supply chain during COVID has been blamed for many consumer goods shortages, and rightfully so. During lockdown, how many of us stalked our local warehouse clubs for that elusive delivery of toilet paper, scared of the implications if none was found? Or maybe you tried negotiating the price on eBay for a set of weights that was 3-4x the usual cost? Those shortages seen by the average consumer also heavily plagued electronics manufacturers and their customers as well.</p></div><div class="paragraph"><p>Now imagine being a start-up during COVID. A start-up in the electronics industry. A start-up in competition for those highly demanded, severely constrained electronic components. A start-up with no name recognition, no history, and no relationships with manufacturers and / or distributors. Seemingly simple items like capacitors and resistors saw 20+ week lead times, with other parts advertising lead times of 52, 98, and even 104+ weeks. That’s what the supply chain looked like for Oxide in 2021, and in many component categories, still looks like today.</p></div><div class="paragraph"><p>Our Operations Team has been hard at work since late 2020 trying to secure supply for a product that, throughout 2021 and into 2022, has continued to undergo design changes. The procurement function became a delicate balancing act taking into account lead time, cost, industry outlooks, and working closely with our engineering team regarding upcoming design changes. How much faith could we put in the demand for a given part today, when we knew an updated Bill of Materials (BOM) would be published in a few weeks? For parts with lead times that would extend past our first customer ship date, how much supply should we purchase 12-18 months ahead of schedule, knowing our design was not finalized? Working with borrowed money (literally, from our investors), we needed to quickly put in place a robust procurement system to balance the issues we faced. We needed an actionable plan that solved supply issues on many fronts. So, we did what the average consumer did during COVID; we stalked the stores (in our case, online distributors) day and night, weekdays and weekends waiting for restocks. We negotiated with suppliers, investigating whether there was additional inventory available but being held back. In some cases, being a start-up and only needing small quantities was helpful. We were able to get sample quantities of parts that would last us through our engineering build cycle. However, being a small start-up also meant we were up against the big guys. Getting recognition of our existence, let alone inventory allocated to us, was often a stressful, tedious process. What have we found that helped our team the most? Strategic supplier relationships.</p></div><div class="paragraph"><p>There is not enough that can be said for setting up strong, trusting relationships with your suppliers. All of us on the Operations Team at Oxide have extensive backgrounds at some of the world’s top manufacturing and supply chain companies. We’ve seen and heard it all. We know the lengths many procurement professionals will go to in order to secure supply during allocations. They may inflate demand knowing their allocation quantity is based on their demand, or they may communicate required dates that are several weeks or months ahead of when the supply is actually needed. However, those responsible for the supply allocations usually realize this. When the truth comes to light, that company’s future demand is often taken with a grain of salt. It becomes difficult to trust that company again. That’s where the Oxide Ops Team differentiate ourselves. Oxide’s principles and values truly drive our everyday work. We’re firmly committed to our principles of Integrity, Honesty, and Decency, and integrate them into all of our business practices. We strive to balance our sometimes conflicting values in order to strengthen our vendor relationships. Here are a few of the Oxide values and how we showcase them in our supply chain relationships.</p></div><div class="ulist"><ul class=""><li><p><strong>Candor</strong> — We’re upfront about our needs, including quantities and dates. As these items change, we do our best to proactively communicate those changes to our suppliers. We know there will be times we need our suppliers to jump through hoops for us, to expedite, to get supply not otherwise allocated to us. However, we also understand these should be one-off instances and not the norm. We want our supplier reps to succeed just as much as we strive for success at Oxide. Being candid helps ensure we are all set up for success.</p></li><li><p><strong>Rigor</strong> — We demand a lot from ourselves, but we also demand a lot from our suppliers. If a date slips or the component quality isn’t as expected, we request our supplier proactively communicate, root cause, and implement corrective action as needed. We have a small team and we rely on our suppliers to have the same sense of rigor as we do at Oxide.</p></li><li><p><strong>Teamwork</strong> — We look at the relationships with our suppliers as extended team members. We want to instill in them a sense of pride for the Oxide product, just as much as we support them and their company. Successes and failures are shared amongst everyone involved. We will not be successful at Oxide without our extended team.</p></li><li><p><strong>Thriftiness</strong> – We’re a start-up with maniacally focused founders, a very involved board of directors, and limited capital. We’re building a massive product while being very cognizant of costs. Given our small size and start-up status, we rely on our relationships with our suppliers, coupled with massive amounts of internet searching and price comparing, to try and get the best costs we can. We know we’re paying more for items than the big guys, but we’re trying to close that gap as much as we can. Getting our suppliers on board with our vision, and getting them excited about the Oxide rack, is instrumental in price negotiations. We’re also sure that one day we’ll be one of those big guys. :)</p></li></ul></div><div class="paragraph"><p>Aligning ourselves with suppliers we can trust and partners invested in the success of Oxide has allowed us to successfully navigate the current supply chain conditions. Treating others with respect and kindness cannot be underestimated. Building strong relationships on an unfaltering basis of Integrity, Honesty and Decency is key. Adhering to our principles and balancing our values will continue to drive our successes.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_when_allocation_hits_the_fan" aria-hidden="true"></span><a class="link group" href="#_when_allocation_hits_the_fan">When Allocation Hits the Fan<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Allocation. A term no supply chain professional wants to hear. Even more so when you’re a start-up in a critical test phase of your new product which has yet to launch. Founders, investors, manufacturing partners and others, all anxious for an update. That timing device, tiny in size, but mighty in nature, gating your entire build process. Your product can’t run without it. There are no suitable alternates and there is no supply via your normal channels. There is, however, a large supply showing in the broker market. Over 100K. <em>Wow, score!</em> You may have just solved your high-profile supply constraint. Now the only thing left to decide is which of these companies will get your business.</p></div><div class="paragraph"><p>Before you get too excited though, you need to pause, step back, and analyze the situation. Could there really be over 100K of this highly constrained part on the broker market? That $0.38 part is showing for between $1.10 and $7.08 on the broker market. How could there be that much variation? Is the higher priced part <em>“real”</em> while the lower priced part possibly counterfeit or stolen? What would happen if you were to receive a counterfeit part? The brokers typically all provide some sort of generic <em>“guarantee”</em> on their website. How bad could it be? You could order the part, have it tested, realize it’s not real and get your money back, right? Sounds easy, though it rarely is. From reading reviews of brokers, speaking with people who have had bad experiences, and my own search for broker parts, many of the broker websites are not legitimate. Embrace your inner pessimist and begin your search being wary of everyone. While there are certain countries which automatically throw up red flags, there are also plenty of US based companies I wouldn’t consider doing business with. It’s ok to be pessimistic now and then. You need to protect your company, your product, and your reputation. What sorts of issues could you face with parts purchased from a broker? You could end up with parts that have old date codes, have not been stored correctly in humidity controlled / ESD bags, damaged, or downright counterfeit. Things to look for when evaluating an online broker:</p></div><div class="olist arabic"><ol class="arabic"><li class=""><p><strong>Misspellings &amp; Poor Grammar.</strong> Sure, we all make mistakes from time to time. I had to make sure <em>“misspellings”</em> was spelled correctly! However, a professional website should not have misspellings, blatant grammar issues or obviously poor translation.</p></li><li class=""><p><strong>Authorized Distributor Claims.</strong> Make sure to go to the actual manufacturer’s website and look up their authorized distributors. If a broker claims they are authorized and aren’t listed, do not order anything, ever.</p></li><li class=""><p><strong>100% Guaranteed Claims – Authenticity, Quality, etc.</strong> Read the superfine print. Understand what is being guaranteed. A phrase such as “guaranteed to function like original part” should make you pause given use of the word <em>“like”</em>. Most sites seem to offer some feel-good blurb on how they’ve had the parts tested in-house or by a third-party tester and results are available. What are the qualifications of the tester? What were they testing? Some websites will even tell you they support you having the part tested. If your tests show the part is not original, you can return the part with your test data. However, reading deeper into their return policy, often found in a different section of their website, will reveal that you cannot return any part that has been opened and / or is not the full quantity ordered. Return windows may also be abnormally short, not affording you enough time to test the parts. Unfortunately for you, in order to perform a physical and electrical verification, you must open the packaging and use several for testing purposes. You have now invalidated your ability to return the part.</p></li><li class=""><p><strong>Payment Terms</strong> – Be extremely cognizant of payment terms, types of payment accepted, and the entity you are paying. Research the payee and bank information. There are certain payment methods that are more secure and better for this type of transaction than others.</p></li><li class=""><p><strong>Do Your Research</strong> – Spend some time reading online reviews. Take note of who / where any good reviews are coming from. Pay closer attention to the negative reviews. While it’s true more people are likely to leave a negative review than a positive review, if you see consistency in the negative reviews, it’s probably best to move along. Common negative reviews of brokers include no communication after payment sent, payment sent and part not actually in stock, payment sent and part not received, and parts do not work as expected (old date code, damaged, counterfeit). A quick search can open your eyes to a lot of questionable activities!</p></li></ol></div><div class="paragraph"><p>After checking out many of the websites showing stock on the part you desperately need, you’re back to square one. You’ve realized you can’t possibly trust one of these unheard-of websites to provide an instrumental component in your product. You’ve spoken with the manufacturer and distributors and nothing is available, not even samples. What next? Give up? Tell your founders and investors the timeline is in jeopardy and all forward progress must come to a halt? None of those sound like great alternatives.</p></div><div class="paragraph"><p>I’m blessed in that I have a history in the broker market from a previous job in the computer industry. I’ve been exposed to all sorts of people and stories, some that make you just shake your head in disbelief. I already have the handful of people I feel comfortable and enjoy working with. These are a few areas I look at when deciding to work with any broker.</p></div><div class="olist arabic"><ol class="arabic"><li class=""><p><strong>Certifications (ISO, OSHA, R2, eStewards, etc)</strong> – While these certifications are typically for manufacturers and / or refurbishers, it gives me a sense of comfort in knowing that a company has achieved any of these certifications. Can a certification be <em>“bought”</em>? Sure, though no one involved would admit it. Don’t make this your only deciding factor but do take it into account. Physical site visits can help clarify any outstanding questions.</p></li><li class=""><p><strong>Length of Time in Business</strong> – The good ones survive the times. Some not-so-great ones survive as well. Some new ones have yet to make a name for themselves but may be great options and provide amazing customer service. Or, they may cut corners to try and increase the bottom line. Do your research and talk to respected members of the secondary market community.</p></li><li class=""><p><strong>Reputation</strong> – Not everyone will agree on a binary assignment of <em>“good”</em> or <em>“bad”</em> for a company. Again, speak with people in the industry about the company, its leadership, and its employees. Do your research on how the company started, how they’ve grown and changed over time, employee turnover, focus for the future, etc.</p></li><li class=""><p><strong>Component Testing</strong> – As we’ve seen, many companies say they do component testing to verify legitimacy of a part. Ask questions, ask to see sample reports, inquire where they do their testing (in-house, 3rd party), etc. You may even consider asking if you can be present during the testing. You can learn a lot from how that question is answered, even if you don’t plan on actually being present.</p></li><li class=""><p><strong>Warranty</strong> – Do they offer the same level of warranty as the manufacturer? What is covered by the warranty? How are warranty claims made?</p></li><li class=""><p><strong>Trust</strong> – Trust the people you’re going to be working with and choose people you’re going to enjoy working with. There are a lot of good brokers out there, so you do have options. Find one you sync with, and the relationship will be off to a positive start.</p></li></ol></div><div class="paragraph"><p>In the end, choosing a broker to work with is both a tactical and personal choice. We don’t often get to choose who we work with, but when presented with an opportunity to do so, make sure you choose wisely. The quality and security of your product depend on it, and oftentimes, so does your sanity.</p></div></div></div></div>]]></content>
        <author>
            <name>Kate Hicks</name>
        </author>
        <author>
            <name>Kirstin Neira</name>
        </author>
        <contributor>
            <name>Kate Hicks</name>
        </contributor>
        <contributor>
            <name>Kirstin Neira</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Benefits as a Reflection of Values]]></title>
        <id>https://oxide.computer/blog/benefits-as-a-reflection-of-values</id>
        <link href="https://oxide.computer/blog/benefits-as-a-reflection-of-values"/>
        <updated>2022-04-20T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[Our values drive us to provide the best benefits we can find, and then some.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>“We offer the best health insurance we could find” is what we promise in <a href="https://oxide.computer/careers">our job postings</a>. On paper, this is accurate: the health insurance Oxide offers is the best plan we can find that is offered to small businesses.</p></div><div class="paragraph"><p>What we left unsaid until now is that the best health insurance offered to small businesses is, in fact, not very good at all if you don’t neatly fit into a narrow demographic; the bitter irony is that the US healthcare system isn’t designed for those of us who rely on it the most. And life-saving treatments that aren’t needed by able-bodied cisgender people are, more often than not, deemed “not medically necessary” in off-the-shelf insurance policies simply because there is no law to require their coverage. In our society’s bizarre and accidental system, we rely on employers to provide benefits everyone should have, including healthcare, retirement plans, and dependent care.</p></div><div class="paragraph"><p>When I came out as trans and started seeking medical care, I worked at a large employer that directly paid for the medical costs of its employees and dictated how their insurance networks process claims. I had the benefits I needed because other trans people fought for them and the company could unilaterally choose to provide them. Startups don’t have this luxury and are at the whims of insurance companies to keep the cost of hiring and retaining employees manageable. Meanwhile, insurers put profit over care, and won’t budge on off-the-shelf benefits plans unless Congress forces the issue – yet as I write this, lawmakers across the country are either ignoring us or actively stripping away our right to get the healthcare we need, so we’re not holding our breath.</p></div><div class="paragraph"><p>With this in mind, I was initially uneasy about applying to Oxide because we didn’t make our benefits clear to prospective applicants. But I still applied — not out of blind faith, but because I felt a company built on <a href="https://oxide.computer/principles">these values</a> would put its people first and work to provide what I needed. Shortly after I started, despite insurance companies not budging even an inch, our CEO Steve announced a reimbursement arrangement that would cover $10,000 of out-of-pocket healthcare expenses for gender-related healthcare per year. This isn’t perfect, but it’s a damn good start.</p></div><div class="paragraph"><p>Future applicants shouldn’t need to put this much faith in us upholding our values in order to be comfortable about applying, though. Here’s a much clearer summary of our benefits:</p></div><div class="ulist"><ul class=""><li><p>We offer the best medical, dental, and vision insurance plans we can find as a small employer; premiums are 100% paid by Oxide for both employees and dependents.</p></li><li><p>We offer an optional FSA plan for out-of-pocket healthcare and dependent care expenses.</p></li><li><p>We reimburse (through an HRA) up to $17,000 annually: $10,000 annually for gender affirmation or infertility expenses, $5,000 annually for hearing and laser eye surgery expenses, and $2,000 annually for dental and miscellaneous healthcare expenses. The HRAs cover out-of-pocket expenses regardless of whether insurance covers them partially or not at all.</p></li></ul></div><div class="paragraph"><p>The bottom line: Where our insurers fall short, we will work to meet our employees where they need us to be.</p></div><div class="paragraph"><p>As with <a href="https://oxide.computer/blog/compensation-as-a-reflection-of-values">our compensation model</a>, the benefits we provide embody <a href="https://oxide.computer/principles">our mission, principles, and values</a>: We can’t focus on our mission if we’re distracted by healthcare expenses. Our principles of integrity, honesty, and decency compel us to care for our teammates and their families. And our approach to benefits intersects with several of our values:</p></div><div class="ulist"><ul class=""><li><p>It is driven by our empathy. Even if we don’t have the context for someone else’s needs, we don’t need it: none of us ever want to have to worry about healthcare expenses for ourselves, our partners, or our families, and we wouldn’t wish it on each other. We understand that this approach is necessary and important, even if some of us don’t directly benefit.</p></li><li><p>It is a step toward building a more diverse team. In this regard, we are not meeting the same standard to which we hold ourselves with our other values. We strive to change that by embracing the needs of our current team as well as those of prospective future teammates. Benefits are a critical part of what employers bring to the table for candidates, and we don’t want to inhibit people from applying to Oxide because of the perception that small companies can only provide meager coverage that doesn’t work for them. While <a href="https://oxide.computer/blog/compensation-as-a-reflection-of-values">our compensation model</a> ensures we have no pay gap, our approach ensures that people relying more on these vital benefits are still getting paid the same as their peers. Every member of the team has different needs, and we will do our best to address as many of them as we can.</p></li><li><p>It is a reflection of our resilience. We will do everything within our power to take care of our employees. We will continue to fight our insurers to provide for basic healthcare needs, and when they fall short, we will find other ways to provide for those needs (such as offering HRAs) while we continue to fight. We will never stop advocating for our employees.</p></li><li><p>It is a fundamental responsibility to our teammates. We don’t treat healthcare benefits as a “perk”: it is a basic need for all of us. And while it is tiring to continue to fight against an uncaring and unwavering healthcare system only to make incremental progress, we know that we must do so to keep our mission in sight.</p></li></ul></div><div class="paragraph"><p>Finally, in the spirit of transparency: we’ve made <a href="https://drive.google.com/drive/folders/1WJs_tIFlpTOiJK4dI5KnuX_aamoVMXrY">our benefits information public</a> starting today. These are close to the same documents employees see when signing up for benefits (with some information only relevant for employees removed). We’re working to provide additional information for specific situations that we’re aware of — and we know that our benefits are not complete; there are innumerable needs none of us have experienced or thought of.</p></div><div class="paragraph"><p>We share our benefits information for two important reasons: first, we want applicants to be able to learn everything we know about our benefits so that they feel confident in applying even in the face of a healthcare need that is not commonly covered; second, we want to give employees at other similarly-situated companies tools (such as suggesting HRAs) to help fight for the healthcare coverage they need. We have a responsibility to take care of our employees, but we also have a responsibility to make our industry a better place to work for everyone.</p></div></div>]]></content>
        <author>
            <name>iliana etaoin</name>
        </author>
        <contributor>
            <name>iliana etaoin</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Another vulnerability in the LPC55S69 ROM]]></title>
        <id>https://oxide.computer/blog/another-vulnerability-in-the-lpc55s69-rom</id>
        <link href="https://oxide.computer/blog/another-vulnerability-in-the-lpc55s69-rom"/>
        <link rel="enclosure" href="https://oxide.computer/img/blog/lpc55s69-rom/featured-image.svg" type="image/svg"/>
        <updated>2022-03-23T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[The discovery of an undocumented hardware block in the LPC55S69.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>Here at Oxide, we continue to work on building servers as they should be. Last year, we discovered an undocumented hardware block in the LPC55S69 (our chosen part for our product’s Root of Trust implementation) that could be used to violate security boundaries. This issue highlighted the importance of transparency as an Oxide value which is why we are bringing another recently discovered vulnerability to light today. While continuing to develop our product, we discovered a buffer overflow in the ROM of the LPC55S69. This issue exists in the In-System Programming (ISP) code for the signed update mechanism which lives in ROM. This vulnerability allows an attacker to gain non-persistent code execution with a carefully crafted update regardless of whether the update is signed. This can be used to circumvent restrictions when the chip is fully locked down and also extract the device’s DICE Unique Device Secret (UDS). Because this issue exists in ROM there is no known workaround other than disabling all hardware and software paths to enter ISP mode. CVE-2022-22819 has been assigned for this vulnerability. Finding two separate issues in the same chip only strengthens Oxide’s assertion that keeping code proprietary does not improve product security and hardware manufacturers such as NXP should make their ROM source available for customer review.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_updates_are_hard" aria-hidden="true"></span><a class="link group" href="#_updates_are_hard">Updates are hard<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Before discussing the exploit, it’s worth thinking about the higher level problem: how do you update your software on a microcontroller once it leaves the factory? This turns out to be a tricky problem where a bug can result in a non-functional device. To make this problem easier, chip makers like NXP will provide some method to put the chip in a mode that allows for safe modification of flash independent of installed firmware. NXP offers this via its In System Programming (ISP) mode.</p></div><div class="paragraph"><p>ISP mode allows a host (typically a general purpose computer) to read and write various parts of the chip including flash by sending commands to the target over a variety of protocols. The LPC55S69 supports receiving ISP commands over UART, SPI, I2C, and, on variants that include the necessary peripheral, CAN. The LPC55S69 can be configured to require code be signed with a specific key. In this configuration, most commands are restricted and changes to the flash can only come via the <code>receive-sb-file</code> command.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_the_update_format" aria-hidden="true"></span><a class="link group" href="#_the_update_format">The update format<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The <code>receive-sb-file</code> ISP command uses the SB2 format. This format includes a header followed by a series of commands which can modify the flash or start code execution. Confidentiality and integrity of an update are provided by encrypting the commands with a key programmed at manufacturing time, inserting a secure digest of the commands in the update header, and finally signing the header. The C representation of the first part of the header looks like the following:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code class="language-C" data-lang="C"><span>struct sb2_header_t {</span><br><span>	uint32_t nonce[4];</span><br><span></span><br><span>	uint32_t reserved;</span><br><span>	uint8_t m_signature[4];</span><br><span>	uint8_t m_majorVersion;</span><br><span>	uint8_t m_minorVersion;</span><br><span></span><br><span>	uint16_t m_flags;</span><br><span>	uint32_t m_imageBlocks;</span><br><span>	uint32_t m_firstBootTagBlock;</span><br><span>	section_id_t m_firstBootableSectionID;</span><br><span></span><br><span>	uint32_t m_offsetToCertificateBlockInBytes;</span><br><span></span><br><span>	uint16_t m_headerBlocks;</span><br><span></span><br><span>	uint16_t m_keyBlobBlock;</span><br><span>	uint16_t m_keyBlobBlockCount;</span><br><span>	uint16_t m_maxSectionMacCount;</span><br><span>	uint8_t m_signature2[4];</span><br><span></span><br><span>	uint64_t m_timestamp;</span><br><span>	version_t m_productVersion;</span><br><span>	version_t m_componentVersion;</span><br><span>	uint32_t m_buildNumber;</span><br><span>	uint8_t m_padding1[4];</span><br><span>};</span></code></pre></div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_the_bug" aria-hidden="true"></span><a class="link group" href="#_the_bug">The bug<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The SB2 update is parsed sequentially in 16-byte blocks. The header identifies some parts of the update by block number (e.g. block 0 is at byte offset 0, block 1 at byte offset 16 etc). The bug comes from improper bounds checking on the block numbers. The SB2 parser in ROM copies the header to a global buffer before checking the signature. Instead of stopping when the size of the header has been copied (a total of 8 blocks or 128 bytes), the parsing code copies up to <code>m_keyBlobBlock</code> number of blocks. In a correctly formatted header, <code>m_keyBlobBlock</code> will refer to the block number right after the header, but the code does not check the bounds on this. If <code>m_keyBlobBlock</code> is set to a much larger number the code will continue copying bytes beyond the end of the global buffer, a classic buffer overflow.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_impact" aria-hidden="true"></span><a class="link group" href="#_impact">Impact<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The full extent of this bug depends on system configuration with code execution possible in many circumstances. A simple version of this can allow for enabling SWD access (normally disabled during ISP mode) via jumping to existing code in ROM. A more sophisticated attack has been demonstrated as a proof-of-concept to provide arbitrary code execution. While code execution via this vulnerability does not directly provide persistence, attack code executes with the privileges of ISP mode and can thus modify flash contents. If this system is configured for secure boot and sealed via the Customer Manufacturing Programming Area (CMPA), modifications of code stored in flash will be detected on subsequent boots. Additionally, ISP mode executes while the DICE UDS (Unique Device Secret) is still accessible allowing for off-device derivation of keys based on the secret.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_mitigation" aria-hidden="true"></span><a class="link group" href="#_mitigation">Mitigation<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Because this is an issue in the ROM, the best mitigation without replacing the chip is to prevent access to the vulnerable SB2 parser. Disabling ISP mode and not using flash recovery mode will avoid exposure, although this does mean the chip user must come up with alternate designs for those use cases.</p></div><div class="paragraph"><p>The NXP ROM also provides an API for applying an SB2 update directly from user code. Using this API in any form will still provide a potential path to expose the bug. Checking the signature on an update using another ROM API before calling the update API would provide verification than an update is from a trusted source. This is not the same thing as verifying that the update data is correct or not malicious. Signature verification does provide a potential mechanism for some degree of confidence if using the SB2 update mechanism cannot be avoided.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_conclusion" aria-hidden="true"></span><a class="link group" href="#_conclusion">Conclusion<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>As exciting as it was to find this issue, it was also surprising given NXP’s previous statement that the ROM had been reviewed for vulnerabilities. While no review is guaranteed to find every issue, this issue once again highlights that a single report is no substitute for transparency. Oxide continues to assert that open firmware is necessary for building a more secure system. Transparency in what we are building and how we are building it will allow our customers to make a fully informed choice about what they are buying and how their system will work. We, once again, invite everyone to join us in making open firmware the industry baseline.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_timeline" aria-hidden="true"></span><a class="link group" href="#_timeline">Timeline<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="dlist"><dl><dt class="hdlist1">2021-12-22</dt><dd><p>Oxide discovers vulnerability while attempting to understand SB2 update process</p></dd><dt class="hdlist1">2021-12-23</dt><dd><p>Oxide discloses vulnerability to NXP</p></dd><dt class="hdlist1">2022-01-03</dt><dd><p>NXP PSIRT acknowledges the report</p></dd><dt class="hdlist1">2022-01-04</dt><dd><p>NXP PSIRT acknowledges the vulnerability</p></dd><dt class="hdlist1">2022-02-28</dt><dd><p>NXP Discloses issues in a NXP Security Bulletin (NDA required) and confirms that a new ROM revision, and thus new part revisions, are required to correct the vulnerability in affected product lines.</p></dd><dt class="hdlist1">2022-03-23</dt><dd><p>Oxide discloses as CVE-2022-22819</p></dd></dl></div></div></div></div>]]></content>
        <author>
            <name>Laura Abbott</name>
        </author>
        <contributor>
            <name>Laura Abbott</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Hubris and Humility]]></title>
        <id>https://oxide.computer/blog/hubris-and-humility</id>
        <link href="https://oxide.computer/blog/hubris-and-humility"/>
        <updated>2021-11-30T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[The release of a small open-source operating system for deeply-embedded computer systems.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>When <a href="https://oxide.computer/blog/oxide-computer-company-initial-boot-sequence">we started Oxide</a>, we knew we were going to take a fresh look at the entire system. We knew, for example, that we wanted to have a true hardware root of trust and that we wanted to revisit the traditional BMC. We knew, too, that we would have our own system software on each of these embedded systems, and assumed that we would use an existing open source operating system as a foundation. However, as we waded deeper into these embedded systems and especially their constraints of security and robustness we found that what we wanted out of the existing operating systems wasn’t necessarily what they offered (or even wanted to offer).</p></div><div class="paragraph"><p>As time went on in early 2020 and we found ourselves increasingly forcing existing systems out of the comfort of their design centers, we wondered: was our assumption of using an existing system wrong? Should we in fact be exploring our own de novo operating system? In particular, our colleague <a href="http://cliffle.com/">Cliff Biffle</a>, who had a ton of experience with both Rust and embedded systems, had a vision for what such a system might look like (namely, the system that he had always wanted for himself!). Cliff dove into a sketch of his ideas, giving the nascent system a name that felt perfectly apt: Hubris.</p></div><div class="paragraph"><p>After just a few weeks, Cliff’s ideas were taking concrete shape, and it was clear that there was a lot to like: the emerging Hubris was an all-Rust system that was not distracting itself by accommodating other runtimes; it was microkernel-based, allowing for safety and isolation; it employed a strictly synchronous task model, allowing for it be easily developed and comprehended; and it was small and light, allowing it to fit into some of the tight spots we envisioned for it. But for me, it was the way Cliff thought about the building of the system that really set Hubris apart: instead of having an operating system that knows how to dynamically create tasks at run-time (itself a hallmark of multiprogrammed, general purpose systems), Cliff had designed Hubris to fully specify the tasks for a particular application at build time, with the build system then combining the kernel with the selected tasks to yield a single (attestable!) image.</p></div><div class="paragraph"><p>This is the best of both worlds: it is at once dynamic and general purpose with respect to what the system can run, but also entirely static in terms of the binary payload of a particular application — and broadly static in terms of its execution. Dynamic resource exhaustion is the root of many problems in embedded systems; having the system know a priori all of the tasks that it will ever see liberates it from not just a major source of dynamic allocation, but also from the concomitant failure modes. For example, in Hubris, tasks can always be safely restarted, because we know that the resources associated with a task are available if that task itself has faulted! And this eliminates failure modes in which dynamic task creation in response to load induces resource exhaustion; as Cliff has quipped, it is hard to have a fork bomb when the system lacks fork itself!</p></div><div class="paragraph"><p>Precedence for the Hubris approach can be found in other systems like library operating systems, but there is an essential difference: Hubris is a memory-protected system, with tasks, the kernel, and drivers all in disjoint protection domains. (And yes, even in memory safe languages like Rust, memory protection is essential!) In this regard, Hubris represents what we like about Rust, too: a creative solution that cuts through a false dichotomy to yield a system that is at once nimble and rigorous.</p></div><div class="paragraph"><p>It was clear that Cliff was on the right track with Hubris, and the rest of us jumped in with gusto. For my own part, with debugging and debuggability deep in my marrow, I set to work writing the debugger that I felt that we would need — and that Hubris deserved. Following Cliff’s lead, I dubbed it Humility, and it’s been exciting for me to see the debugger and the operating system work together to yield a higher-quality system.</p></div><div class="paragraph"><p>We have known for quite some time that we would open source Hubris: not only is open source core to our own commercial thesis at Oxide, we also believe that the open source revolution — and its many advantages for customers — are long overdue in the lowest layers of the software stack. So we were waiting for the right occasion, and the <a href="https://osfc.io/">Open Source Firmware Conference</a> afforded us an excellent one: if you are a listener of our <a href="https://oxide.computer/podcasts">On the Metal</a> podcast, you heard us talk about OSFC a bunch, and it felt entirely fitting that we would kickoff our own open source firmware contribution there. And while the conference starts today, the good news is that you haven’t missed anything! Or at least, not yet: the conference is virtual, so if you want to hear Cliff talk about Hubris in his own words — and it’s before 12:10 Pacific today — it’s not too late to <a href="https://tickets.osfc.io/">buy a ticket</a>! (The recording will naturally be released after the conference.)</p></div><div class="paragraph"><p>And of course, if you just want to play with the system itself, Hubris and Humility are both now open source! Start by checking out the <a href="https://github.com/oxidecomputer/hubris">Hubris repo</a>, the <a href="https://hubris.oxide.computer/reference/">Hubris docs</a>, and the <a href="https://github.com/oxidecomputer/humility">Humility repo</a>. (And if you are looking for a hardware vehicle for your exploration, take a look at the ST Nucleo-H753ZI evaluation board — a pretty capable computer for less than thirty bucks!) We believe Rust to be a part of the <a href="https://www.youtube.com/watch?v=XbBzSSvT_P0">coming firmware revolution</a>, and it’s exciting for us to have a system out there that embodies that belief!</p></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Exploiting Undocumented Hardware Blocks in the LPC55S69]]></title>
        <id>https://oxide.computer/blog/exploiting-undocumented-hardware-blocks-in-the-lpc55s69</id>
        <link href="https://oxide.computer/blog/exploiting-undocumented-hardware-blocks-in-the-lpc55s69"/>
        <updated>2021-04-30T23:00:00.000Z</updated>
        <summary type="html"><![CDATA[A write up of the LPC55S69 ROM Patch.]]></summary>
        <content type="html"><![CDATA[<link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-patch-layout.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-patch-layout.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-patch-layout.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Flpc55-flash-layout.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Flpc55-flash-layout.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Flpc55-flash-layout.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><link rel="preload" as="image" imageSrcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-rom-patcher.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-rom-patcher.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-rom-patcher.png&amp;w=2100&amp;q=90 2100w" imageSizes="(min-width: 600px) 700px, 1400px, 2100px"/><div id="content" class="asciidoc-body w-full"><div id="preamble"><div class="sectionbody"><div class="paragraph"><p>At Oxide Computer, we are designing a new computer system from the ground up. Along the way we carefully review all hardware selected to ensure it meets not only functional needs but our security needs as well. This work includes reverse engineering where necessary to get a full understanding of the hardware. During the process of reverse engineering the NXP LPC55S69 ROM we discovered an undocumented hardware block intended to allow NXP to fix bugs discovered in the ROM by applying patches from on-device flash as part of the boot process. That’s important because this ROM contains the first instructions that are run on boot and stores a set of APIs that are called from user applications. Unfortunately, this undocumented block is left open and accessible by non-secure, unprivileged user code thus allowing attackers to make runtime modifications to purportedly trusted APIs, allowing them to potentially hijack future execution and subvert multiple security boundaries. This issue has been assigned CVE-2021-31532.</p></div><div class="paragraph"><p>This vulnerability was found by pure chance. We believe that this issue would have been discovered much earlier if the source code for the ROM itself were publicly available. For us, finding and disclosing this issue has highlighted the importance of being able to audit the components in our system. Transparency is one of our <a href="https://oxide.computer/about/">values</a> at Oxide because we believe that open systems are more likely to be secure ones.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_details" aria-hidden="true"></span><a class="link group" href="#_details">Details<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The purpose of a secure boot process rooted in a hardware root of trust is to provide some level of assurance that the firmware and software booted on a server is unmodified and was produced by a trusted supplier. Using a root of trust in this way allows users to detect certain types of persistent attacks such as those that target <a href="https://arstechnica.com/information-technology/2020/12/dangerous-uefi-malware-is-rare-a-botnet-called-trickbot-may-change-that/">firmware</a>. Hardware platforms developed by cloud vendors contain a hardware root of trust, such as <a href="https://cloud.google.com/blog/products/gcp/titan-in-depth-security-in-plaintext">Google’s Titan</a>, Microsoft’s Cerberus, and <a href="https://aws.amazon.com/ec2/nitro/">AWS’s Nitro</a>. For Oxide’s rack, we evaluated the <a href="https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpc5500-cortex-m33/high-efficiency-arm-cortex-m33-based-microcontroller-family:LPC55S6x">NXP LPC55S69</a> as a candidate for our hardware root of trust.</p></div><div class="paragraph"><p>Part of evaluating a hardware device for use as a root of trust is reviewing how trust and integrity of code and data is maintained during the boot process. A common technique for establishing trust is to put the first instruction in an on-die ROM. If this is an actual <a href="https://www.arrow.com/en/research-and-events/articles/what-is-rom-types-of-rom-explained">mask ROM</a> the code is permanently encoded in the hardware and cannot be changed. This is great for our chain of trust as we can have confidence that the first code executed will be what we expect and we can use that as the basis for validating other parts of the system. A downside to this approach is that any bugs discovered in the ROM cannot be fixed in existing devices. Allowing modification of read-only code has been associated with <a href="https://media.defcon.org/DEF%20CON%2026/DEF%20CON%2026%20presentations/DEFCON-26-Yuwei-Zheng-Shaokun-Cao-Bypass-the-SecureBoot-and-etc-on-NXP-SOCs-Updated.pdf">exploits</a> in other generations of chips.</p></div><div class="paragraph"><p>An appealing feature of the LPC55 is the addition of <a href="https://developer.arm.com/ip-products/security-ip/trustzone">TrustZone-M</a>. TrustZone-M provides hardware-enforced isolation allowing sensitive firmware and data to be protected from attacks against the rest of the system. Unlike TrustZone-A which uses thread context and memory mappings to distinguish between secure and non-secure worlds, TrustZone-M relies on designating parts of the physical address space as either secure or non-secure. Because of this, any hardware block that supports remapping of memory regions or that is shared between secure and non-secure worlds can potentially break that isolation. ARM recognized this risk and explicitly prohibited including their own <a href="https://developer.arm.com/documentation/ddi0439/b/Debug/About-the-Flash-Patch-and-Breakpoint-Unit&#8212;&#8203;FPB-/FPB-programmers-model">Flash Patch and Breakpoint (FPB) unit</a>, a hardware block commonly included in Cortex-M devices to improve debugging, in devices with TrustZone-M.</p></div><div class="paragraph"><p>While doing our due diligence in reviewing the part, we discovered a custom undocumented hardware block by NXP that is similar to the ARM FPB but for patching ROM. While this ROM patcher is useful for fixing bugs discovered in the ROM after chip fabrication, it potentially weakens trusted boot assertions, as there is no longer a 100% guarantee that the same code is running each time the system boots. Thankfully, experimentation revealed that ROM patches are cleared upon device reset thus preventing any viable attacks against secure boot.</p></div><div class="paragraph"><p>NXP also has a set of runtime APIs in ROM for accessing the on-board flash, authenticating firmware images, and entering in-system programming mode. These ROM APIs are expected to be called from secure mode and some, such as skboot_authenticate, require privileged mode as well. Since the ROM patcher is accessible from non-secure/unprivileged mode, an attacker can leverage these ROM APIs to gain privilege escalation by modifying the ROM API as follows:</p></div><div class="olist arabic"><ol class="arabic"><li class=""><p>Pick a target ROM API (say flash_program) likely to be used by a secure mode application</p></li><li class=""><p>Use the ROM patcher to change the first instruction to branch to an attacker controlled address</p></li><li class=""><p>The next call into the ROM will execute the selected address</p></li></ol></div><div class="paragraph"><p>This issue can be mitigated through use of the <a href="https://developer.arm.com/documentation/100699/0100/">memory protection unit (MPU)</a> or <a href="https://developer.arm.com/documentation/100235/0004/the-cortex-m33-peripherals/security-attribution-and-memory-protection/security-attribution-unit">security attribution unit (SAU)</a> which restricts access to specified address ranges. Not all code bases will choose to enable the MPU, however. Developers may consider this unnecessary overhead given the expected small footprint of a microcontroller. This issue shows why that’s a dangerous assumption. Even close examination of the official documentation would not have given any indication of a reason to use the MPU. Multiple layers of security can mitigate or lessen the effects of a security issue.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_how_did_we_find_this" aria-hidden="true"></span><a class="link group" href="#_how_did_we_find_this">How did we find this<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Part of building a secure product means knowing exactly what code is running and what that code is doing. While having first instruction code in ROM is good for measured boot (we can know what code is running), the ROM itself is completely undocumented by NXP except for API entry points. This means we had no idea exactly what code was running or if that code was correct. Running undocumented code isn’t a value-add no matter how optimized or clever that code might be. We took some time to reverse engineer the ROM to get a better idea of how exactly the secure boot functionality worked and verify exactly what it was doing.</p></div><div class="paragraph"><p>Reverse engineering is a very specialized field but it turns out you can get a decent idea of what code is doing with <a href="https://ghidra-sre.org/">Ghidra</a> and a knowledge of ARM assembly. It also helps that the ROM code was not intentionally obfuscated so Ghidra did a decent job of turning it back into C. Using the breadcrumbs available to us in NXP’s documentation we discovered an undocumented piece of hardware related to a “ROM patch” stored in on-chip persistent storage and we dug in to understand how it works.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_details_about_the_hardware_block" aria-hidden="true"></span><a class="link group" href="#_details_about_the_hardware_block">Details about the hardware block<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>NXP’s homegrown ROM patcher is a hardware block implemented as an APB peripheral at non-secure base address 0x4003e000 and secure base address 0x5003e000. It provides a mechanism for replacing up to 16 32-bit words in the ROM with either an explicit 32-bit value or a svc instruction. The svc instruction is typically used by unprivileged code to request privileged code to perform an operation on its behalf. As this provides a convenient mechanism for performing an indirect call, it is used to trampoline to a patch stored in SRAM when the patch is longer than a few words.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-patch-layout.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-patch-layout.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-patch-layout.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-patch-layout.png&amp;w=1440&amp;q=90" alt="NXP patch layout"/></div><div class="title">NXP patch layout</div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_persistent_rom_patches_stored_in_flash" aria-hidden="true"></span><a class="link group" href="#_persistent_rom_patches_stored_in_flash">Persistent ROM patches stored in flash<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>NXP divides the flash up into two main parts: regular flash and protected flash. Regular flash is available to the device developer for all uses. The protected flash region holds data for device settings. NXP documents the user configurable parts of the protected flash region in <a href="https://www.nxp.com/docs/en/application-note/AN12283.pdf">detail</a>. The documentation notes the existence of an NXP area which cannot be reprogrammed but gives limited information about what data exists in that area.</p></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Flpc55-flash-layout.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Flpc55-flash-layout.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Flpc55-flash-layout.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Flpc55-flash-layout.png&amp;w=1440&amp;q=90" alt="LPC55 flash layout"/></div><div class="title">LPC55 flash layout</div></div><div class="paragraph"><p>The limited documentation for the NXP area in protected flash refers to a ROM patch area. This contains a data structure for setting the ROM patcher at boot up. We’ve decoded the structure but some of the information may be incomplete. Each entry in the NXP ROM patch area is described by a structure. This is the rough structure we’ve reverse engineered:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code class="language-C" data-lang="C"><span>struct rom_patch_entry {</span><br><span>	u8 word_count;</span><br><span>	u8 relative_address;</span><br><span>	u8 command;</span><br><span>	u8 magic_marker; // Always ‘U’</span><br><span>	u32 offset_to_be_patched</span><br><span>	u8 instructions[];</span><br><span>}</span></code></pre></div></div><div class="paragraph"><p>There’s three different commands defined by NXP to program the ROM patcher: a group of single word changes, an svc change, and a patch to SRAM. For the single word, the addresses to be changed are written to the entry in the array at offset 0x100 along with their corresponding entries in the reverse array at 0xf0. The relative_address field seems to determine if the addresses are relative or absolute. All the patches on our system have only been a single address so the full use of relative_address may be slightly different. For an svc change, the address is written to the 0x100 array, and the instructions are copied to an offset in the SRAM region. The patch to SRAM doesn’t actually use the flash patcher but it adjusts values in the global state stored in the SRAM.</p></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_using_the_rom_patcher" aria-hidden="true"></span><a class="link group" href="#_using_the_rom_patcher">Using the ROM patcher<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Let’s show a detailed example of using the ROM patcher to change a single 32-bit word. In general, assuming the ROM patcher block starts at address 0x5003e000 and using patch slot “n” to modify a target ROM address “A” to have value “V”, we would do the following:</p></div><div class="olist arabic"><ol class="arabic"><li class=""><p>Set bit 29 at 0x5003e0f4 to turn off all patches</p></li><li class=""><p>Write our target address A to the address register at 0x5003e100 + 4*n</p></li><li class=""><p>Write our replacement value V to the value register at 0x5003e0f0 - 4*n</p></li><li class=""><p>Set bit n to the enable register at 0x5003e0fc</p></li><li class=""><p>Clear bit 29 and set bit n in 0x5003d0f4 to use the replacement value</p></li></ol></div><div class="paragraph"><p>To make this concrete, let’s modify ROM address 0x13001000 from its initial value of 0 to a new value 0xffffffff. We’ll use the first patch slot (bit 0 in 0xf4).</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>// Initial value at the address in ROM that we’re going to patch
pyocd> read32 0x13001000
13001000: 00000000 |….|

// Step 1: Turn off all patches
pyocd> write32 0x5003e0f4 0x20000000

// Step 2: Write the target address (0x13001000)
pyocd> write32 0x5003e100 0x13001000

// Step 3: Write the value we’re going to patch it with (0xffffffff)
pyocd> write32 0x5003e0f0 0xffffffff

// Step 4: Enable patch 0
pyocd> write32 0x5003e0fc 0x1

// Step 5: Turn on the ROM patch and set bit 0 to use replacement
pyocd> write32 0x5003e0f4 0x1

// Our replaced value
pyocd> read32 0x13001000

13001000: ffffffff |….|</code></pre></div></div><div class="imageblock   "><div class="content"><img srcSet="/_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-rom-patcher.png&amp;w=750&amp;q=90 700w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-rom-patcher.png&amp;w=1440&amp;q=90 1400w, /_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-rom-patcher.png&amp;w=2100&amp;q=90 2100w" sizes="(min-width: 600px) 700px, 1400px, 2100px" src="/_vercel/image?url=%2Fimg%2Fblog%2Fexploiting-undocumented-hardware-blocks-in-the-lpc55s69%2Fnxp-rom-patcher.png&amp;w=1440&amp;q=90" alt="NXP ROM patcher"/></div><div class="title">NXP ROM patcher</div></div><div class="paragraph"><p>We can use these same steps to modify the flash APIs. NXP provides a function to verify that bytes have been written correctly to flash:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code class="language-C" data-lang="C"><span>status_t FLASH_VerifyProgram(flash_config_t *config, uint32_t start,</span><br><span>	uint32_t lengthInBytes,</span><br><span>	const uint32_t *expectedData,</span><br><span>	uint32_t *failedAddress,</span><br><span>	uint32_t *failedData);</span></code></pre></div></div><div class="paragraph"><p>The function itself lives at 0x130073f8 (This is after indirection via the official function call table)</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>pyocd> disas 0x130073f8 32
0x130073f8: 2de9f847 push.w {r3, r4, r5, r6, r7, r8, sb, sl, lr}
0x130073fc: 45f61817 movw r7, #0x5918
0x13007400: 8046 mov r8, r0
0x13007402: c1f20047 movt r7, #0x1400
0x13007406: 3868 ldr r0, [r7]
0x13007408: 5fea030a movs.w sl, r3
0x1300740c: 85b0 sub sp, #0x14
0x1300740e: 0490 str r0, [sp, #0x10]
0x13007410: 0c46 mov r4, r1
0x13007412: 08bf it eq
0x13007414: 0420 moveq r0, #4
0x13007416: 1546 mov r5, r2</code></pre></div></div><div class="paragraph"><p>We can modify this function to always return success. ARM THUMB2 uses r0 as the return register. 0 is the value for success so we need to generate a mov r0, #0instruction followed by a bx lr instruction to return. This ends up being 0x2000 for the mov r0, #0 and 0x4770 for bx lr. The first instruction at 0x130073f8 is conveniently 4 bytes so it’s easy to replace with a single ROM patch slot.</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>// Turn off the patcher
pyocd> write32 0x5003e0f4 0x20000000

// Write the target address
pyocd> write32 0x5003e100 0x130073f8

// Write the target value
pyocd> write32 0x5003e0f0 0x47702000

// Enable patch 0
pyocd> write32 0x5003e0fc 0x1

// Turn on the patcher and use replacement for patch 0
pyocd> write32 0x5003e0f4 0x1

// The first two instructions have been replaced
pyocd> disas 0x130073f8 32
0x130073f8: 0020 movs r0, #0
0x130073fa: 7047 bx lr
0x130073fc: 45f61817 movw r7, #0x5918
0x13007400: 8046 mov r8, r0
0x13007402: c1f20047 movt r7, #0x1400
0x13007406: 3868 ldr r0, [r7]
0x13007408: 5fea030a movs.w sl, r3
0x1300740c: 85b0 sub sp, #0x14
0x1300740e: 0490 str r0, [sp, #0x10]
0x13007410: 0c46 mov r4, r1
0x13007412: 08bf it eq
0x13007414: 0420 moveq r0, #4
0x13007416: 1546 mov r5, r2</code></pre></div></div><div class="paragraph"><p>So long as this patch is active, any call to FLASH_VerifyProgram will return success regardless of its contents.</p></div><div class="paragraph"><p>NXP also provides a function to verify the authenticity of an image:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>skboot_status_t skboot_authenticate(const uint8_t *imageStartAddr,
	secure_bool_t *isSignVerified)</code></pre></div></div><div class="paragraph"><p>In addition to returning a status code, the value stored in the second argument also contains a separate return value that must be checked. It does make the ROM patching code longer but not significantly so. The assembly we need is:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>// Two instructions to load kSECURE_TRACKER_VERIFIED = 0x55aacc33U
movw r0, 0xcc33
movt r0, 0x55aa

// store kSECURE_TRACKER_VERIFIED to r1 aka isSignVerified
str r0, [r1]

// Two instructions to load kStatus_SKBOOT_Success = 0x5ac3c35a
movw r0, 0xc35a
movt r0, 0x5ac3

// return
bx lr</code></pre></div></div><div class="paragraph"><p>If you look at a sample disassembly, there’s a mixture of 16 and 32 bit instructions:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>45c: f64c 4033 movw r0, #52275 ; 0xcc33
460: f2c5 50aa movt r0, #21930 ; 0x55aa
464: 6008 str r0, [r1, #0]
466: f24c 305a movw r0, #50010 ; 0xc35a
46a: f6c5 20c3 movt r0, #23235 ; 0x5ac3
46e: 4770 bx lr</code></pre></div></div><div class="paragraph"><p>Everything must be written in 32-bit words so the 16 bit instructions either get combined with bytes from another instruction or padded with nop. The start of the function is halfway on a word boundary (0x1300a34e) which needs to be padded:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>pyocd> disas 0x1300a34c 32
0x1300a34c: 70bd pop {r4, r5, r6, pc}
0x1300a34e: 38b5 push {r3, r4, r5, lr}
0x1300a350: 0446 mov r4, r0
0x1300a352: 0d46 mov r5, r1
0x1300a354: fbf7e0f9 bl #0x13005718
0x1300a358: 0020 movs r0, #0
0x1300a35a: 00f048f9 bl #0x1300a5ee
0x1300a35e: 00b1 cbz r0, #0x1300a362
0x1300a360: 09e0 b #0x1300a376
0x1300a362: 0de0 b #0x1300a380
0x1300a364: 38b5 push {r3, r4, r5, lr}
0x1300a366: 0446 mov r4, r0
0x1300a368: 0d46 mov r5, r1
0x1300a36a: 0020 movs r0, #0

// Turn off the ROM patch
pyocd> write32 0x5003e0f4 0x20000000
pyocd>

// Write address and value 0
pyocd> write32 0x5003e100 0x1300a34c
pyocd> write32 0x5003e0f0 0xf64cbf00
pyocd>

// Write address and value 1
pyocd> write32 0x5003e104 0x1300a350
pyocd> write32 0x5003e0ec 0xf2c54033
pyocd>

// Write address and value 2
pyocd> write32 0x5003e108 0x1300a354
pyocd> write32 0x5003e0e8 0x600850aa
pyocd>

// Write address and value 3
pyocd> write32 0x5003e10c 0x1300a358
pyocd> write32 0x5003e0e4 0x305af24c
pyocd>

// Write address and value 4
pyocd> write32 0x5003e110 0x1300a35c
pyocd> write32 0x5003e0e0 0x20c3f6c5
pyocd>

// Write address and value 5
pyocd> write32 0x5003e114 0x1300a360
pyocd> write32 0x5003e0dc 0xbf004770

// Enable patches 0-5
pyocd> write32 0x5003e0f4 0x3f
pyocd>

// Turn on the ROM patcher and set patches 0-5 to single-word replacement mode.
pyocd> write32 0x5003e0f4 0x3f

// The next 7 instructions are the modifications
pyocd> disas 0x1300a34c 32
0x1300a34c: 00bf nop
0x1300a34e: 4cf63340 movw r0, #0xcc33
0x1300a352: c5f2aa50 movt r0, #0x55aa
0x1300a356: 0860 str r0, [r1]
0x1300a358: 4cf25a30 movw r0, #0xc35a
0x1300a35c: c5f6c320 movt r0, #0x5ac3
0x1300a360: 7047 bx lr
0x1300a362: 00bf nop
0x1300a364: 38b5 push {r3, r4, r5, lr}
0x1300a366: 0446 mov r4, r0
0x1300a368: 0d46 mov r5, r1
0x1300a36a: 0020 movs r0, #0</code></pre></div></div><div class="paragraph"><p>The authentication method now returns success for any address passed in.</p></div><div class="paragraph"><p>The careful observer will note that the FLASH_VerifyProgram and skboot_authenticate patches use the same address slots and thus cannot be applied at the same time. We’re limited to eight 32-bit word changes or a total of 32 bytes which limits the number of locations that can be changed. The assembly demonstrated here is not optimized and could certainly be improved. Another approach is to apply one patch, wait for the function to be called and then switch to a different patch.</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_applying_mitigations" aria-hidden="true"></span><a class="link group" href="#_applying_mitigations">Applying Mitigations<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>A full mitigation would provide a lock-out option so that once the ROM patcher is enabled no further changes are available until the next reset. Based on discussions with NXP, this is not a feature that is available on the current hardware.</p></div><div class="paragraph"><p>The LPC55 offers a standard <a href="https://developer.arm.com/documentation/100699/0100/">memory protection unit (MPU)</a>. The MPU works on an allowed list of memory regions. If the MPU is configured without the ROM patcher in the allowed set, any access will trigger a fault. This makes it possible to prevent applications from using the ROM patcher at all.</p></div><div class="paragraph"><p>The LPC55 also has a secure AHB bus matrix to provide another layer of protection. This is custom hardware to block access on both secure and privilege axes. Like the ROM patcher itself, the ability to block access to the ROM patcher is not documented even though it exists. The base address of the ROM patcher (0x5003e000) comes right after the last entry in the APB table (The PLU at 0x5003d000). The order of the bits in the secure AHB registers correspond to the order of blocks in the memory map, which means the bits corresponding to the ROM patcher come right after the PLU. SEC_CTRL_APB_BRIDGE1_MEM_CTRL3 is the register of interest and the bits to set for the ROM patch are 24 and 25.</p></div><div class="paragraph"><p>NXP offers a <a href="https://www.nxp.com/docs/en/application-note/AN12278.pdf">family of products</a> based on the LPC55 line. The LPC55S2x is notable for not including TrustZone-M. While at first glance, this may seem to imply it is immune to privilege escalation via ROM patches, LPC55S2x is still an ARMv8-M device with privileged/non-privileged modes which are just as vulnerable. The non-secure MPU is the only method of blocking non-privileged access to the ROM patcher on all LPC55 variants.</p></div></div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_conclusion" aria-hidden="true"></span><a class="link group" href="#_conclusion">Conclusion<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Nobody expects code to be perfect. Code for the mask ROM in particular may have to be completed well before other code given manufacturing requirements. Several of the ROM patches on the LPC55 were related to power settings which may not be finalized until very late in the product cycle. Features to fix bugs must not introduce vulnerabilities however! The LPC55S69 is marketed as a security product which makes the availability of the ROM patcher even riskier. The biggest takeaway from all of this is that transparency is important for security. A risk cannot be mitigated unless it is known. Had we not begun to ask deep questions about the ROM’s behavior, we would have been exposed to this vulnerability until it was eventually discovered and reported. Attempts to provide security through obscurity, such as preventing read access to ROMs or leaving hardware undocumented, have been repeatedly shown to be ineffective (<a href="https://blog.zapb.de/stm32f1-exceptional-failure/" class="bare">https://blog.zapb.de/stm32f1-exceptional-failure/</a>, <a href="http://dmitry.gr/index.php?r=05.Projects&amp;proj=23" class="bare">http://dmitry.gr/index.php?r=05.Projects&amp;proj=23</a>. PSoC4) and merely prolong the exposure. Had NXP documented the ROM patch hardware block and provided ROM source code for auditing, the user community could have found this issue much earlier and without extensive reverse engineering effort.</p></div><div class="paragraph"><p>NXP, however, does not agree; this is their position on the matter (which they have authorized us to share publicly):</p></div><div class="quoteblock"><div class="paragraph"><p>Even though we are not believers of security-by-obscurity, keeping the interest of our wide customer base the product specific ROM code is not opened to external parties, except to NXP approved Common Criteria certified security test labs for vulnerability reviews.</p></div></div><div class="paragraph"><p>At Oxide, we believe fervently in open firmware, at all layers of the stack. In this regard, we intend to be the model for what we wish to see in the world: by the time our Oxide racks are commercially available next year, you can expect that all of the software and firmware that we have written will be open source, available for view – and scrutiny! – by all. Moreover, we know that the arc of system software bends towards open source: we look forward to the day that NXP – and others in the industry who cling to their proprietary software as a means of security – join us with truly open firmware.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_timeline" aria-hidden="true"></span><a class="link group" href="#_timeline">Timeline<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="dlist"><dl><dt class="hdlist1">2020-12-16</dt><dd><p>Oxide sends disclosure to NXP including an embargo of 90 days</p></dd><dt class="hdlist1">2020-12-16</dt><dd><p>NXP PSIRT Acknowledges disclosure</p></dd><dt class="hdlist1">2021-01-11</dt><dd><p>Oxide requests confirmation that vulnerability was able to be reproduced</p></dd><dt class="hdlist1">2021-01-12</dt><dd><p>NXP confirms vulnerability and is working on mitigation</p></dd><dt class="hdlist1">2021-02-03</dt><dd><p>Oxide requests an update on disclosure timeline</p></dd><dt class="hdlist1">2021-02-08</dt><dd><p>NXP requests clarification of vulnerability scope</p></dd><dt class="hdlist1">2021-02-24</dt><dd><p>Oxide provides responses and a more complete PoC</p></dd><dt class="hdlist1">2021-03-05</dt><dd><p>NXP requests 45 day embargo extension to April 30th, 2021</p></dd><dt class="hdlist1">2021-04-30</dt><dd><p>Oxide publicly discloses this vulnerability as CVE-2021-31532</p></dd></dl></div></div></div></div>]]></content>
        <author>
            <name>Laura Abbott</name>
        </author>
        <contributor>
            <name>Laura Abbott</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Compensation as a Reflection of Values]]></title>
        <id>https://oxide.computer/blog/compensation-as-a-reflection-of-values</id>
        <link href="https://oxide.computer/blog/compensation-as-a-reflection-of-values"/>
        <updated>2021-03-03T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[Our thoughts on compensation, and how they reflect Oxide's values.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>Compensation: the word alone is enough to trigger a fight-or-flight reaction in
many. But we in technology have the good fortune of being in a well-compensated
domain, so why does this issue induce such anxiety when our basic needs are
clearly covered? If it needs to be said, it&#8217;s because compensation isn&#8217;t merely
about the currency we redeem in exchange for our labors, but rather it is a
proxy for how we are valued in a larger organization. This, in turn, brings us
to our largest possible questions for ourselves, around things like meaning and
self-worth.</p></div><div class="paragraph"><p>So when we started Oxide – as in any new endeavor – compensation was an issue we
had to deal with directly. First, there was the thorny issue of how we founders
would compensate ourselves. Then, of course, came the team we wished to hire:
hybrid local and remote, largely experienced to start (on account of
<a href="https://www.youtube.com/watch?v=vvZA9n3e5pc">Oxide&#8217;s outrageously ambitious
mission</a>), and coming from a diverse set of backgrounds and experiences. How
would we pay people in different geographies? How could we responsibly recruit
experienced folks, many of whom have families and other financial obligations
that can&#8217;t be addressed with stock options? How could we avoid bringing people&#8217;s
compensation history – often a reflection of race, gender, class, and other
factors rather than capability – with them?</p></div><div class="paragraph"><p>We decided to do something outlandishly simple: take the salary that Steve,
Jess, and I were going to pay ourselves, and pay that to everyone. The three of
us live in the San Francisco Bay Area, and Steve and I each have three kids; we
knew that the dollar figure that would allow us to live without financial
distress – which we put at $175,000 a year – would be at least universally
adequate for the team we wanted to build. And we mean everyone literally: as of
this writing we have 23 employees, and that&#8217;s what we all make.</p></div><div class="paragraph"><p>Now, because compensation is the hottest of all hot buttons, it can be fairly
expected that many people will have a reaction to this. Assuming you&#8217;ve made it
to this sentence it means you are not already lighting us up in your local
comments section (thank you!), and I want to promise in return that we know some
likely objections, and we&#8217;ll address those. But before we do, we want to talk
about the benefits of transparent uniform compensation, because they are, in a
word, profound.</p></div><div class="paragraph"><p>Broadly, our compensation model embodies our
<a href="https://oxide.computer/principles/">mission, principles, and values</a>. First and
foremost, we believe that our compensation model reflects our principles of
<strong>honesty</strong>, <strong>integrity</strong>, and <strong>decency</strong>. To flip it around: sadly, we have seen extant
comp structures in the industry become breeding grounds for dishonesty, deceit,
and indecency. Beyond our principles, our comp model is a tangible expression of
several of our values in particular:</p></div><div class="ulist"><ul class=""><li><p>It has set the tone with respect to <strong>teamwork</strong>. In my experience, the need to
"quantify" one&#8217;s performance in exchange for justifying changes to individual
compensation are at the root of much of what&#8217;s wrong in the tech industry.
Instead of incentivizing people to achieve together as a team, they are
incentivized to advance themselves – usually with sophisticated-sounding jargon
like OKRs or MBOs, or perhaps reasonable-sounding (but ultimately misguided)
mantras like "measure everything." Even at their very best, these individual
incentives represent a drag on a team, as their infrequent calibration can
prevent a team from a necessary change in its direction. And at worst, they
leave individuals perversely incentivized and operating in direct opposition to
the team&#8217;s best interest. When comp is taken out of the picture, everyone can
just focus on what we need to focus on: getting this outlandish thing built, and
loving and serving the customers who are taking a chance on it.</p></li><li><p>It is an
expression of our <strong>empathy</strong>. Our approach to compensation reflects our belief in
treating other people the way that we ourselves want to be treated. There are
several different dimensions for this, but one is particularly visceral: because
we have not talked about this publicly, candidates who have applied to Oxide
have done so assuming that we have a traditional comp model, and have braced
themselves for the combat of a salary negotiation. But we have spoken about it
relatively upfront with candidates (before they talk to the team, for example),
and (as the one who has often had this discussion) the relief is often palpable.
As one recent candidate phrased it to me: "if I had known about this earlier, I
wouldn&#8217;t have wasted time stressing out about it!"</p></li><li><p>It is (obviously?)
proof-positive of our <strong>transparency</strong>. Transparency is essential for building
trust, itself one of the most important elements of doing something bold
together. One of the interesting pieces of advice we got early on from someone
who has had outsized, repeated success: modulo private personnel meetings, make
sure that every meeting is open to everyone. For those accustomed to more opaque
environments, our level of transparency can be refreshing: for example, new
Oxide employees have been pleasantly surprised that we always go through our
board decks with everyone – but we can&#8217;t imagine doing it any other way.
Transparent compensation takes this to an unusual (but not unprecedented)
extreme, and we have found it to underscore how seriously we take transparency
in general.</p></li><li><p>It has allowed whole new levels of <strong>candor</strong>. When everyone can talk
about their salary, other things become easier to discuss directly. This candor
is in all directions; without comp to worry about, we can all be candid with
respect to our own struggles – which in turn allows us to address them directly.
And we can be candid too when giving public positive feedback; we don&#8217;t need to
be afraid that by calling attention to someone&#8217;s progress, someone else will
feel shorted.</p></li></ul></div><div class="paragraph"><p>These are (some of!) the overwhelming positives; what about those objections?</p></div><div class="ulist"><ul class=""><li><p>Some will say that this salary is too low. While cash compensation gets
exaggerated all of the time, it&#8217;s unquestionable that salaries in our privileged
domain have gotten much higher than our $175,000 (and indeed, many at Oxide have
taken a cut in pay to work here). But it&#8217;s also true that $175,000 per year puts
us each in the top 5% of US individual earners – and it certainly puts a roof
over our families' heads and food in their bellies. Put more viscerally: this is
enough to not fret when your kids toss the organic raspberries into the shopping
cart – or when they devour them before you&#8217;ve managed to get the grocery bags
out of the car! And speaking of those families: nothing is more
anxiety-producing than having a healthcare issue compounded by financial
distress due to inadequate insurance; Oxide not only offers the best healthcare
plans we could find, but we also pay 100% of monthly premiums – a significant
benefit for those with dependents.</p></li><li><p>Some will say that we should be paying
people differently based on different geographical locations. I know there are
thoughtful people who pay folks differently based on their zip code, but
(respectfully), we disagree with this approach. Companies spin this by
explaining they are merely paying people based on their cost of living, but this
is absurd: do we increase someone&#8217;s salary when their spouse loses their job or
when their kid goes to college? Do we slash it when they inherit money from
their deceased parent or move in with someone? The answer to all of these is no,
of course not: we pay people based on their work, not their costs. The truth is
that companies pay people less in other geographies for a simple reason: because
they can. We at Oxide just don&#8217;t agree with this; we pay people the same
regardless of where they pick up their mail.</p></li><li><p>Some will say that this doesn&#8217;t
scale. This is, at some level, surely correct: it&#8217;s hard to envision a
multi-thousand employee Oxide where everyone makes the same salary – but it has
also been (rightly) said that startups should do things that don&#8217;t scale. And
while it seems true that the uniformity won&#8217;t necessarily scale, we believe that
the values behind it very much will!</p></li><li><p>Some will say that this makes us unlikely
to hire folks just starting out in their career. There is truth to this too, but
the nature of our problem at Oxide (namely, technically very broad and very
deep), the size of our team (very small), and the stage of our company (still
pretty early!) already means that engineers at the earliest stages of their
career are unlikely to be a fit for us right now. That said, we don&#8217;t think this
is impossible; and if we felt that we had someone much earlier in their career
who was a fit – that is, if we saw them contributing to the company as much as
anyone else – why wouldn&#8217;t we reflect that by paying them the same as everyone
else?</p></li><li><p>Some will say that this narrows the kind of roles that we can hire for.
In particular, different roles can have very different comp models (sales often
has a significant commission component in exchange for a lower base, for
example). There is truth to this too – but for the moment we&#8217;re going to put
this in the "but-this-can&#8217;t-scale" bucket.</p></li><li><p>Some will say that this doesn&#8217;t
offer a career ladder. Uniform compensation causes us to ask some deeper
questions: namely, what is a career ladder, anyway? To me, the true objective
for all of us should be to always be taking on new challenges – to be unafraid
to learn and develop. I have found traditional ladders to not serve these ends
particularly well, because they focus us on competition rather than
collaboration. By eliminating the rung of compensation, we can put the focus on
career development where it belongs: on supporting one another in our
self-improvement, and working together to do things that are beyond any one of
us.</p></li><li><p>Some will say that we should be talking about equity, not cash
compensation. While it&#8217;s true that startup equity is important, it&#8217;s also true
that startup equity doesn&#8217;t pay the orthodontist&#8217;s bill or get the basement
repainted. We believe that every employee should have equity to give them a
stake in the company&#8217;s future (and that an outsized return for investors should
also be an outsized return for employees), but we also believe that the presence
of equity can&#8217;t be used as an excuse for unsustainably low cash compensation. As
for how equity is determined, it really deserves its own in-depth treatment, but
in short, equity compensates for risk – and in a startup, risk reduces over
time: the first employee takes much more risk than the hundredth.</p></li></ul></div><div class="paragraph"><p>Of these objections, several are of the ilk that this cannot endure at arbitrary
scale. This may be true – our compensation may well not be uniform in perpetuity
– but we believe wholeheartedly that <strong>our values will endure</strong>. So if and when the
uniformity of our compensation needs to change, we fully expect that it will
remain transparent – and that we as a team will discuss it candidly and
empathetically. In this regard, we take inspiration from companies that have
pioneered transparent compensation. It is very interesting to, for example, look
at how <a href="https://buffer.com/resources/salary-formula-changes-2019/">Buffer&#8217;s
compensation has changed over the years</a>. Their approach is different from ours
in the specifics, but they are a kindred spirit with respect to underlying
values – and their success with transparent compensation gives us confidence
that, whatever changes must come with time, we will be able to accommodate them
without sacrificing what is important to us!</p></div><div class="paragraph"><p>Finally, a modest correction. The $175,000 isn&#8217;t quite true – or at least not
anymore. I had forgotten that when we did our initial planning, we had budgeted
modest comp increases after the first year, so it turns out, we all got a raise
to $180,250 in December! I didn&#8217;t know it was coming (and nor did anyone else);
Steve just announced it in the All Hands: no three-hundred-and-sixty degree
reviews, no stack ranking, no OKRs, no skip-levels, no numerical grades – just a
few more organic raspberries in everyone&#8217;s shopping basket. Never has a change
in compensation felt so universally positive!</p></div><div class="paragraph"><p><strong>UPDATES</strong>: Since originally writing this blog entry in 2021, we have
increased our salary a few times, and it now stands at $250,000. We have
also added some sales positions that have variable compensation, consisting
of a lower base salary and a commission component.</p></div></div>]]></content>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[RFD 1 Requests for Discussion]]></title>
        <id>https://oxide.computer/blog/rfd-1-requests-for-discussion</id>
        <link href="https://oxide.computer/blog/rfd-1-requests-for-discussion"/>
        <updated>2020-07-24T18:00:00.000Z</updated>
        <summary type="html"><![CDATA[A look inside our internal Requests for Discussion process.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div id="preamble"><div class="sectionbody"><div class="admonitionblock note"><div class="admonition-icon"><svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg" class="rotate-180"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 12A6 6 0 1 0 6 0a6 6 0 0 0 0 12Zm.083-9c.368 0 .667.299.667.667v2.666A.667.667 0 0 1 6.083 7h-.166a.667.667 0 0 1-.667-.667V3.667c0-.368.299-.667.667-.667h.166Zm0 5c.368 0 .667.299.667.667v.166a.667.667 0 0 1-.667.667h-.166a.667.667 0 0 1-.667-.667v-.166c0-.368.299-.667.667-.667h.166Z" fill="currentColor"></path></svg></div><div class="admonition-content content"><div>Note</div><div>This blog entry is from 2020. For an in-depth discussion of RFDs
and how they have evolved at Oxide since this blog entry was written,
check out our
<a href="https://oxide-and-friends.transistor.fm"><em>Oxide and Friends</em></a> episode
<a href="https://oxide-and-friends.transistor.fm/episodes/rfds-the-backbone-of-oxide">RFDs: The backbone of Oxide</a></div></div></div><div class="paragraph"><p>One of the first things we did in setting up the company was create a repo named “rfd.” This repo houses our requests for discussion. Bryan teased this to the internet…</p></div><div class="paragraph"><p>…and folks asked for our process, so we are going to share it!</p></div><div class="paragraph"><p>The best way to describe RFDs is with “RFD 1 Requests for Discussion.” Below is that RFD.</p></div><div class="paragraph"><p>Writing down ideas is important: it allows them to be rigorously formulated (even while nascent), candidly discussed and transparently shared. We capture the written expression of an idea in a Request for Discussion (RFD), a document in the original spirit of the IETF <a href="https://en.wikipedia.org/wiki/Request_for_Comments">Request for Comments</a>, as expressed by <a href="https://tools.ietf.org/html/rfc3">RFC 3</a>:</p></div><div class="quoteblock"><div class="paragraph"><p>The content of a note may be any thought, suggestion, etc. related to the software or other aspect of the network. Notes are encouraged to be timely rather than polished. Philosophical positions without examples or other specifics, specific suggestions or implementation techniques without introductory or background explication, and explicit questions without any attempted answers are all acceptable. The minimum length for a note is one sentence.</p></div><div class="paragraph"><p>These standards (or lack of them) are stated explicitly for two reasons. First, there is a tendency to view a written statement as ipso facto authoritative, and we hope to promote the exchange and discussion of considerably less than authoritative ideas. Second, there is a natural hesitancy to publish something unpolished, and we hope to ease this inhibition.</p></div></div><div class="paragraph"><p>Similar to RFCs, our philosophy of RFDs is to allow both timely discussion of rough ideas, while still becoming a permanent repository for more established ones. Depending on their state, RFDs may be quickly iterated on in a branch, discussed actively as part of a pull request to be merged, or commented upon after having been published. The workflow for the RFD process for is based upon those of the Golang proposal process, Joyent RFD process, Rust RFC process, and Kubernetes proposal process.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_when_to_use_an_rfd" aria-hidden="true"></span><a class="link group" href="#_when_to_use_an_rfd">When to use an RFD<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The following are examples of when an RFD is appropriate, these are intended to be broad:</p></div><div class="ulist"><ul class=""><li><p>Add or change a company process</p></li><li><p>An architectural or design decision for hardware or software</p></li><li><p>Change to an API or command-line tool used by customers</p></li><li><p>Change to an internal API or tool</p></li><li><p>Change to an internal process</p></li><li><p>A design for testing</p></li></ul></div><div class="paragraph"><p>RFDs not only apply to technical ideas but overall company ideas and processes as well. If you have an idea to improve the way something is being done as a company, you have the power to make your voice heard by adding to discussion.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_rfd_metadata_and_state" aria-hidden="true"></span><a class="link group" href="#_rfd_metadata_and_state">RFD Metadata and State<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>At the start of every RFD document, we’d like to include a brief amount of metadata. The metadata format is based on the <a href="https://github.com/trentm/python-markdown2/wiki/metadata">python-markdown2</a> metadata format. It’d look like:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>—
authors: Andy Smith <andy@example.computer>, Neal Jones <neal@example.computer>
state: prediscussion
—</code></pre></div></div><div class="paragraph"><p>We keep track of three pieces of metadata:</p></div><div class="olist arabic"><ol class="arabic"><li class=""><p><code>authors</code>: the authors (and therefore owners) of an RFD. They should be listed with their name and e-mail address.</p></li><li class=""><p><code>state</code>: must be one of the states discussed below.</p></li><li class=""><p><code>discussion</code>: for RFDs that are in or beyond the discussion state, this should be a link to the PR to integrate the RFD; see below for details.</p></li></ol></div><div class="paragraph"><p>An RFD can be in one of the following six states:</p></div><div class="olist arabic"><ol class="arabic"><li class=""><p><code>prediscussion</code></p></li><li class=""><p><code>ideation</code></p></li><li class=""><p><code>discussion</code></p></li><li class=""><p><code>published</code></p></li><li class=""><p><code>committed</code></p></li><li class=""><p><code>abandoned</code></p></li></ol></div><div class="paragraph"><p>A document in the prediscussion state indicates that the work is not yet ready for discussion, but that the RFD is effectively a placeholder. The prediscussion state signifies that work iterations are being done quickly on the RFD in its branch in order to advance the RFD to the discussion state.</p></div><div class="paragraph"><p>A document in the ideation state contains only a description of the topic that the RFD will cover, providing an indication of the scope of the eventual RFD. Unlike the prediscussion state, there is no expectation that it is undergoing active revision. Such a document can be viewed as a scratchpad for related ideas. Any member of the team is encouraged to start active development of such an RFD (moving it to the prediscussion state) with or without the participation of the original author. It is critical that RFDs in the ideation state are clear and narrowly defined.</p></div><div class="paragraph"><p>Documents under active discussion should be in the discussion state. At this point a discussion is being had for the RFD in a Pull Request.</p></div><div class="paragraph"><p>Once (or if) discussion has converged and the Pull Request is ready to be merged, it should be updated to the published state before merge. Note that just because something is in the published state does not mean that it cannot be updated and corrected. See the <a href="#_making_changes_to_an_rfd">Making changes to an RFD</a> section for more information.</p></div><div class="paragraph"><p>The prediscussion state should be viewed as essentially a collaborative extension of an engineer’s notebook, and the discussion state should be used when an idea is being actively discussed. These states shouldn’t be used for ideas that have been committed to, organizationally or otherwise; by the time an idea represents the consensus or direction, it should be in the published state.</p></div><div class="paragraph"><p>Once an idea has been entirely implemented, it should be in the committed state. Comments on ideas in the committed state should generally be raised as issues — but if the comment represents a call for a significant divergence from or extension to committed functionality, a new RFD may be called for; as in all things, use your best judgment.</p></div><div class="paragraph"><p>Finally, if an idea is found to be non-viable (that is, deliberately never implemented) or if an RFD should be otherwise indicated that it should be ignored, it can be moved into the abandoned state.</p></div><div class="paragraph"><p>We will go over this in more detail. Let’s walk through the life of a RFD.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_rfd_life_cycle" aria-hidden="true"></span><a class="link group" href="#_rfd_life_cycle">RFD life-cycle<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>There is a prototype script in this repository, scripts/new.sh, that will automate the process.</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>$ scripts/new.sh 0042 “My title here”</code></pre></div></div><div class="paragraph"><p>If you wish to create a new RFD by hand, or understand the process in greater detail, read on.</p></div><div class="admonitionblock note"><div class="admonition-icon"><svg width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg" class="rotate-180"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 12A6 6 0 1 0 6 0a6 6 0 0 0 0 12Zm.083-9c.368 0 .667.299.667.667v2.666A.667.667 0 0 1 6.083 7h-.166a.667.667 0 0 1-.667-.667V3.667c0-.368.299-.667.667-.667h.166Zm0 5c.368 0 .667.299.667.667v.166a.667.667 0 0 1-.667.667h-.166a.667.667 0 0 1-.667-.667v-.166c0-.368.299-.667.667-.667h.166Z" fill="currentColor"></path></svg></div><div class="admonition-content content"><div>Note</div><div>Never at anytime through the process do you push directly to the master branch. Once your pull request (PR) with your RFD in your branch is merged into master, then the RFD will appear in the master branch.</div></div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_reserve_a_rfd_number" aria-hidden="true"></span><a class="link group" href="#_reserve_a_rfd_number">Reserve a RFD number<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>You will first need to reserve the number you wish to use for your RFC. This number should be the next available RFD number from looking at the current git branch -r output.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_create_a_branch_for_your_rfd" aria-hidden="true"></span><a class="link group" href="#_create_a_branch_for_your_rfd">Create a branch for your RFD<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Now you will need to create a new git branch, named after the RFD number you wish to reserve. This number should have leading zeros if less than 4 digits. Before creating the branch, verify that it does not already exist:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>$ git branch -rl *0042</code></pre></div></div><div class="paragraph"><p>If you see a branch there (but not a corresponding sub-directory in rfd in master), it is possible that the RFD is currently being created; stop and check with co-workers before proceeding! Once you have verified that the branch doesn’t exist, create it locally and switch to it:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>$ git checkout -b 0042</code></pre></div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_create_a_placeholder_rfd" aria-hidden="true"></span><a class="link group" href="#_create_a_placeholder_rfd">Create a placeholder RFD<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Now create a placeholder RFD. You can do so with the following commands:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>$ mkdir -p rfd/0042
$ cp prototypes/prototype.md rfd/0042/README.md</code></pre></div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_or_if_you_prefer_asciidoc" aria-hidden="true"></span><a class="link group" href="#_or_if_you_prefer_asciidoc">Or if you prefer asciidoc<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="listingblock"><div class="content"><pre class="highlight"><code>$ cp prototypes/prototype.adoc rfd/0042/README.adoc</code></pre></div></div><div class="paragraph"><p>Fill in the RFD number and title placeholders in the new doc and add your name as an author. The status of the RFD at this point should be prediscussion.</p></div><div class="paragraph"><p>If your preference is to use asciidoc, that is acceptable as well, however the examples in this flow will assume markdown.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_push_your_rfd_branch_remotely" aria-hidden="true"></span><a class="link group" href="#_push_your_rfd_branch_remotely">Push your RFD branch remotely<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Push your changes to your RFD branch in the RFD repo.</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>$ git add rfd/0042/README.md
$ git commit -m ‘0042: Adding placeholder for RFD <Title>’
$ git push origin 0042</code></pre></div></div><div class="paragraph"><p>After your branch is pushed, the table in the README on the master branch will update automatically with the new RFD. If you ever change the name of the RFD in the future, the table will update as well. Whenever information about the state of the RFD changes, this updates the table as well. The single source of truth for information about the RFD comes from the RFD in the branch until it is merged.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_iterate_on_your_rfd_in_your_branch" aria-hidden="true"></span><a class="link group" href="#_iterate_on_your_rfd_in_your_branch">Iterate on your RFD in your branch<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Now, you can work on writing your RFD in your branch.</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>$ git checkout 0042</code></pre></div></div><div class="paragraph"><p>Now you can gather your thoughts and get your RFD to a state where you would like to get feedback and discuss with others. It’s recommended to push your branch remotely to make sure the changes you make stay in sync with the remote in case your local gets damaged.</p></div><div class="paragraph"><p>It is up to you as to whether you would like to squash all your commits down to one before opening up for feedback, or if you would like to keep the commit history for the sake of history.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_discuss_your_rfd" aria-hidden="true"></span><a class="link group" href="#_discuss_your_rfd">Discuss your RFD<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>When you are ready to get feedback on your RFD, make sure all your local changes are pushed to the remote branch. At this point you are likely at the stage where you will want to change the status of the RFD from prediscussion to discussionfor a fully formed RFD or to ideation for one where only the topic is specified. Do this in your branch.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_push_your_rfd_branch_remotely_2" aria-hidden="true"></span><a class="link group" href="#_push_your_rfd_branch_remotely_2">Push your RFD branch remotely<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Along with your RFD content, update the RFD’s state to discussion in your branch, then:</p></div><div class="listingblock"><div class="content"><pre class="highlight"><code>$ git commit -am ‘0042: Add RFD for <Title>’
$ git push origin 0042</code></pre></div></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_open_a_pull_request" aria-hidden="true"></span><a class="link group" href="#_open_a_pull_request">Open a Pull Request<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Open a pull request on GitHub to merge your branch, in this case 0042 into the master branch.</p></div><div class="paragraph"><p>If you move your RFD into discussion but fail to open a pull request, a friendly bot will do it for you. If you open a pull request but fail to update the state of the RFD to discussion, the bot will automatically correct the state by moving it into discussion. The bot will also cleanup the title of the pull request to be RFD {num} {title}. The bot will automatically add the link to the pull request to the discussion: metadata.</p></div><div class="paragraph"><p>After the pull request is opened, anyone subscribed to the repo will get a notification that you have opened a pull request and can read your RFD and give any feedback.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_discuss_the_rfd_on_the_pull_request" aria-hidden="true"></span><a class="link group" href="#_discuss_the_rfd_on_the_pull_request">Discuss the RFD on the pull request<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The comments you choose to accept from the discussion are up to you as the owner of the RFD, but you should remain empathetic in the way you engage in the discussion.</p></div><div class="paragraph"><p>For those giving feedback on the pull request, be sure that all feedback is constructive. Put yourself in the other person’s shoes and if the comment you are about to make is not something you would want someone commenting on an RFD of yours, then do not make the comment.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_merge_the_pull_request" aria-hidden="true"></span><a class="link group" href="#_merge_the_pull_request">Merge the Pull Request<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>After there has been time for folks to leave comments, the RFD can be merged into master and changed from the discussion state to the published state. The timing is left to your discretion: you decide when to open the pull request, and you decide when to merge it. As a guideline, 3-5 business days to comment on your RFD before merging seems reasonable — but circumstances (e.g., time zones, availability of particular expertise, length of RFD) may dictate a different timeline, and you should use your best judgment. In general, RFDs shouldn’t be merged if no one else has read or commented on it; if no one is reading your RFD, it’s time to explicitly ask someone to give it a read!</p></div><div class="paragraph"><p>Discussion can continue on published RFDs! The discussion: link in the metadata should be retained, allowing discussion to continue on the original pull request. If an issue merits more attention or a larger discussion of its own, an issue may be opened, with the synopsis directing the discussion.</p></div><div class="paragraph"><p>Any discussion on an RFD in the can still be made on the original pull request to keep the sprawl to a minimum. Or if you feel your comment post-merge requires a larger discussion, an issue may be opened on it — but be sure to reflect the focus of the discussion in the issue synopsis (e.g., “RFD 42: add consideration of RISC-V”), and be sure to link back to the original PR in the issue description so that one may find one from the other.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_making_changes_to_an_rfd" aria-hidden="true"></span><a class="link group" href="#_making_changes_to_an_rfd">Making changes to an RFD<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>After your RFD has been merged, there is always opportunity to make changes. The easiest way to make a change to an RFD is to make a pull request with the change you would like to make. If you are not the original author of the RFD name your branch after the RFD # (e.g. 0001) and be sure to @ the original authors on your pull request to make sure they see and approve of the changes.</p></div><div class="paragraph"><p>Changes to an RFD will go through the same discussion and merge process as described above.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_committing_to_an_rfd" aria-hidden="true"></span><a class="link group" href="#_committing_to_an_rfd">Committing to an RFD<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>Once an RFD has become implemented — that is, once it is not an idea of some future state but rather an explanation of how a system works — its state should be moved to be committed. This state is essentially no different from published, but represents ideas that have been more fully developed. While discussion on committed RFDs is permitted (and changes allowed), they would be expected to be infrequent.</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_changing_the_rfd_process" aria-hidden="true"></span><a class="link group" href="#_changing_the_rfd_process">Changing the RFD process<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="paragraph"><p>The best part about the RFD process is that it itself is expressed in this RFD; if you want to change the process itself, you can apply the RFD process to its own RFD: chime in on the discussion link or open an issue as dictated by its current state!</p></div></div></div><div class="sect1"><h2 data-sectnum=""><span class="anchor" id="_tooling" aria-hidden="true"></span><a class="link group" href="#_tooling">Tooling<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h2><div class="sectionbody"><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_api" aria-hidden="true"></span><a class="link group" href="#_api">API<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>Because RFDs are so core to everything we do, we automatically update a CSV file of all the RFDs along with their state, links, and other information in the repo for easy parsing. We then have functions in rust that allow us to easily get this information and automate or program tooling with RFD data.</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_short_urls" aria-hidden="true"></span><a class="link group" href="#_short_urls">Short URLs<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>As you can imagine, keeping track of RFDs and their links is unweidly at scale. To help, we have short URLs. You can link to any RFD on GitHub with {num}.rfd.oxide.computer. So for example, 12.rfd.oxide.computer. The path also works: rfd.oxide.computer/12 if that is preferred.</p></div><div class="paragraph"><p>Any discussion for an RFD can be linked with {num}.rfd.oxide.computer/discussion.</p></div><div class="paragraph"><p>These short URLs get automatically updated when a new RFD is opened.</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_chat_bot" aria-hidden="true"></span><a class="link group" href="#_chat_bot">Chat bot<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>In chat you can use !rfd {any text} | {rfd number} to return information about that RFD. For example, !rfd 1 returns the links to RFD 1, its discussion (if it is in discussion), and information about its state. Remembering the number for an RFD is often hard so any strings you pass to the bot will be fuzzy matched across RFD titles. !rfd user api will return the RFD that title matches the text. In this example, it is RFD 4.</p></div></div></div><div class="sect2"><h3 data-sectnum=""><span class="anchor" id="_shared_rfd_rendered_site" aria-hidden="true"></span><a class="link group" href="#_shared_rfd_rendered_site">Shared RFD Rendered Site<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" class="text-accent-secondary ml-2 hidden group-hover:inline-block"><g fill="currentColor"><path d="m6.586 12.243 1.59-1.591a.75.75 0 0 1 1.061 0l.354.353a.75.75 0 0 1 0 1.06L8 13.658A4 4 0 0 1 2.343 8l1.591-1.591a.75.75 0 0 1 1.06 0l.354.354a.75.75 0 0 1 0 1.06l-1.59 1.591a2 2 0 1 0 2.828 2.829M12.066 9.591a.75.75 0 0 1-1.06 0l-.354-.354a.75.75 0 0 1 0-1.06l1.59-1.591a2 2 0 1 0-2.828-2.829l-1.59 1.591a.75.75 0 0 1-1.061 0l-.354-.353a.75.75 0 0 1 0-1.06L8 2.342A4 4 0 0 1 13.657 8z"></path><path d="M9.945 5.702a.75.75 0 0 0-1.061 0L5.702 8.884a.75.75 0 0 0 0 1.06l.353.354a.75.75 0 0 0 1.061 0l3.182-3.182a.75.75 0 0 0 0-1.06z"></path></g></svg></a></h3><div class="sectionbody"><div class="paragraph"><p>As a way to share certain RFDs with other parties like potential customers, partners, and friends of the company, we have created a website that renders the RFD markdown or asciidoc into HTML in a nice format. This is a nice way to get feedback without adding everyone to the repo (as well as nicely formatting the content).</p></div><div class="paragraph"><p>And that’s a wrap! Hopefully, this is helpful if you ever think about doing the same type of process internally!</p></div></div></div></div></div></div>]]></content>
        <author>
            <name>Jessie Frazelle</name>
        </author>
        <contributor>
            <name>Jessie Frazelle</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[RIP Khaled Bichara, 1971-2020]]></title>
        <id>https://oxide.computer/blog/rip-khaled-bichara</id>
        <link href="https://oxide.computer/blog/rip-khaled-bichara"/>
        <updated>2020-02-03T17:00:00.000Z</updated>
        <summary type="html"><![CDATA[We were deeply saddened to learn that Khaled Bichara, one of Oxide's angel investors, died in a car accident in Cairo on Friday night. Our heart goes out to his family, and to all those who he touched over his career.]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>We were deeply saddened to learn that
<a href="https://en.wikipedia.org/wiki/Khaled_Bichara">Khaled Bichara</a>, one of Oxide&#8217;s
angel investors,
<a href="https://www.menabytes.com/khaled-bichara-dies-car-accident/">died in a car
accident in Cairo on Friday night</a>.</p></div><div class="paragraph"><p>Those of us who have known Khaled for years have known him to be a bold investor
who appreciated hard technical problems – and also a profoundly decent person,
who cared deeply for his family, his companies, and his country. Khaled&#8217;s
stories of kindling entrepreneurship in Egypt were inspiring to any who heard
them – and served as a reminder of the reponsibility that we all have to our
broader communities. Our most recent conversation with Khaled – just a few
short months ago – remains vivid: he was excited by our technical vision and
thrilled to be a part of Oxide. For our part, we were looking forward to a long
journey together, and to making good on his belief in us; we are gutted to have
lost him so abruptly. Our heart goes out to his family, and to all those who he
touched over his career; Silicon Valley may be a long way from Cairo, but his
impact and <a href="https://waya.media/the-legacy-of-khaled-bichara/">legacy</a> will be felt
here for years to come.</p></div></div>]]></content>
        <author>
            <name>Steve Tuck</name>
        </author>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <author>
            <name>Jessie Frazelle</name>
        </author>
        <contributor>
            <name>Steve Tuck</name>
        </contributor>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
        <contributor>
            <name>Jessie Frazelle</name>
        </contributor>
    </entry>
    <entry>
        <title type="html"><![CDATA[Oxide Computer Company: Initial boot sequence]]></title>
        <id>https://oxide.computer/blog/introducing-the-oxide-computer-company</id>
        <link href="https://oxide.computer/blog/introducing-the-oxide-computer-company"/>
        <updated>2019-12-01T21:09:00.000Z</updated>
        <summary type="html"><![CDATA[Introducing the Oxide Computer Company!]]></summary>
        <content type="html"><![CDATA[<div id="content" class="asciidoc-body w-full"><div class="paragraph"><p>We have started a computer company! If you haven&#8217;t yet, read Jess&#8217;s account of
us being <a href="https://blog.jessfraz.com/post/born-in-a-garage/">born in a garage</a> and
Bryan&#8217;s on <a href="http://dtrace.org/blogs/bmc/?p=1086">the soul of our new computer
company</a>. Also, see the perspectives of some of our founding engineers:
<a href="https://twitter.com/rmustacc">Robert Mustacchi</a> on
<a href="https://fingolfin.org/blog/20191202/oxide.html">joining Oxide</a>,
<a href="https://twitter.com/jmclulow">Joshua Clulow</a> on the need for
<a href="https://sysmgr.org/blog/2019/12/02/a-new-machine/">a new machine</a>, and
<a href="https://twitter.com/pfmooney">Patrick Mooney</a> on
<a href="https://www.pfmooney.com/post/2019-12-02-the-new-thing/">everything he sees
aligning at Oxide</a> (and in particular, on the importance of
<a href="https://oxide.computer/principles">Oxide&#8217;s principles</a>!).</p></div><div class="paragraph"><p>If it needs to be said, starting a computer company is an ambitious endeavor; we
are thrilled to have investment led by Eclipse Ventures and joined by an
incredible group of institutional and angel investors. Our investors see what we
see: the potential to integrate hardware and software together to bring
hyperscaler-class infrastructure to everyone.</p></div><div class="paragraph"><p>To use the machine as metaphor, Oxide is at the earliest stages of boot: the
power is on, and the first instructions have been executed – but we have a long
way to go before we&#8217;re fully operational! If you are interested in following our
progress
<a href="https://oxidecomputer.us20.list-manage.com/subscribe?u=e46acf89cdf1f5bddf3136473&amp;id=8a6d823488">sign
up for our mailing list</a>. If you are interested in potentially joining us, check
out <a href="https://oxide.computer/careers">our careers page</a>. And if nothing else, give
a listen to our podcast, <a href="https://onthemetal.fm">On the Metal</a>!</p></div></div>]]></content>
        <author>
            <name>Steve Tuck</name>
        </author>
        <author>
            <name>Bryan Cantrill</name>
        </author>
        <author>
            <name>Jessie Frazelle</name>
        </author>
        <contributor>
            <name>Steve Tuck</name>
        </contributor>
        <contributor>
            <name>Bryan Cantrill</name>
        </contributor>
        <contributor>
            <name>Jessie Frazelle</name>
        </contributor>
    </entry>
</feed>