Refreshed episodes/hosts/comments/series from hpr.sql, and added official HPR transcripts for the 180 episodes aired since the last sync (hpr4516-hpr4695).
453 lines
29 KiB
Plaintext
453 lines
29 KiB
Plaintext
Episode: 4614
|
||
Title: Dauug|18: Faster Than a '286, but Inspectable Like a Soroban
|
||
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr4614/hpr4614.mp3
|
||
Transcribed: 2026-07-31 16:15:11 (official HPR transcript)
|
||
|
||
---
|
||
|
||
This is Hacker Public Radio Episode 4614, for 2026-04-09
|
||
Today's show is entitled, "Dauug|18: Faster Than a ’286, but Inspectable Like a Soroban"
|
||
The host is Marc W. Abel and the duration is 00:37:06
|
||
The flag is Clean, and the license is CC-BY
|
||
The summary is "What would MacGyver build when he can't trust complex VLSI? I don't know, so here's what I'd build."
|
||
Welcome back, Hacker Public Radio listeners!
|
||
My name is Marc Abel, and I'm online at dauug.org, spelled D A U U G dot O R G.
|
||
Today we'll take a first look at an 18-bit controller being designed by The Dauug House
|
||
that doesn't use any complex VLSI.
|
||
It doesn't have a microprocessor or anything like one—no FPGA, PLD, ASIC, or even DRAM.
|
||
Now why would someone want a controller that doesn't use complex VLSI today?
|
||
Because complex VLSI has a long history of containing defects that hacking and malware
|
||
can exploit.
|
||
Even dynamic RAM has been shown to not work as designed when adversaries are present.
|
||
And even if we open-source our microprocessors and whatnot, we have no tools as makers that
|
||
can audit delivered chips against their open-source specs.
|
||
So from the standpoint of maybe someone who needs to automate some aspect of critical
|
||
infrastructure, or maybe someone who lives under an authoritarian regime, it can be valuable
|
||
to have modern electronics that operate transparently,
|
||
don't use any black-box components, and can be inspected by their owners clear down to
|
||
the logic-gate level.
|
||
I've thought about this need for about 20 years in hope of finding a way forward.
|
||
I was encouraged by modern surface mount techniques.
|
||
Individual transistors can be packaged so small that 25,000 can fit in a teaspoon.
|
||
Robots that can place and solder them require skill to set up and use, but they
|
||
aren't expensive.
|
||
And because a 32-bit microprocessor already existed that only had 25,000 transistors
|
||
(it was the original ARM CPU), I was sure right off that maker-constructable computers that
|
||
remain inspectable at the logic-gate level even after delivery could be made practical.
|
||
So I kept thinking.
|
||
My discrete transistor idea had several weaknesses, but I think it was looking at recently-built
|
||
relay computers—
|
||
there are hobbyists that like to build these—that exposed the most serious drawback, and
|
||
that's primary storage.
|
||
If a computer has even a million bits of random-access memory, it would take on the order
|
||
of a million components to build that memory.
|
||
Now a million transistors is way more than 25 thousand, and we'd need about six transistors
|
||
per bit to build a reliable memory.
|
||
So I could probably build a processor from discrete components, but the memory supporting
|
||
it would have to be VLSI, probably in the form of static random access memory, or SRAM.
|
||
But what about the security consequences of using VLSI SRAM?
|
||
Could SRAM introduce concealed security defects that hacking and malware could exploit?
|
||
Whether or not to trust SRAM is a judgment call.
|
||
We need to consider whether SRAM supply chain attacks are viable enough for someone to mount
|
||
one, what transparently functioning alternatives to SRAM could be, and how far we're willing
|
||
to go to have transparently functioning computers in the first place.
|
||
Exploring these questions is outside the scope of this episode, but I'll say a few
|
||
words in SRAM's favor.
|
||
As circuits, static random-access memory components are not proprietary.
|
||
In fact they're the exact opposite of proprietary in that their behavior and pinouts are standardized.
|
||
And although the chips are very large scale integration, this largeness is in cell count
|
||
rather than complexity.
|
||
An SRAM is the same 6 transistor flip-flop over and over again, millions of them, and
|
||
they're all isolated from each other.
|
||
In fact, if you read the datasheet for an SRAM IC alongside a datasheet for an AND gate,
|
||
you'll find they're not much different in length.
|
||
Even if a sophisticated adversary is warned that I plan to build a computer out of static
|
||
RAM, it will be hard to attack the machine by manipulating the SRAM supply chain.
|
||
The attacker would need to know what I was building, where in the circuit each RAM they
|
||
supply would go, when and where I would obtain the components, and how to know whether their
|
||
chip went into my computer or someone else's.
|
||
An attacker would also typically need access to the tainted components at their point of
|
||
use.
|
||
I can't tell you that an attacker this sophisticated won't come around, but I suggest that until
|
||
transparently functioning SRAM computers are in such widespread use that the number of
|
||
targets is large, attacks through the SRAM supply chain will be too expensive compared
|
||
to simpler offensives that cost less.
|
||
In light of SRAM's characteristics, I decided I would still be interested in building a
|
||
transparently functioning computer even if it uses VLSI for primary storage—as long
|
||
as it isn't complex VLSI that could easily conceal exploitable defects.
|
||
But with SRAM chips now permitted in the bill of materials, a question arises as to whether
|
||
SRAM is permissible for storage only, or if it could be used for computing as well.
|
||
I estimate that more likely than not, SRAM is actually safer for use in computing logic
|
||
than it is for storage.
|
||
If SRAM could be used as a logic gate, data passing through that part isn't at rest, it's
|
||
just a few bits at a time, not enough bits to identify structure and meaning in.
|
||
When I use SRAM to implement CPU logic thus far, no SRAM ever sees more than 6 bits
|
||
of data at a time.
|
||
That's not even a byte.
|
||
Also, consider where an attacker might buffer data for exfiltration.
|
||
When an SRAM is used for primary storage, there's lots of room to store and aggregate
|
||
information.
|
||
But SRAM used as a logic gate doesn't store data—
|
||
it only holds firmware.
|
||
So let's consider how SRAM can be used to design transparently functioning computers.
|
||
In Hacker Public Radio episode 4333, I described a minicomputer with preemptive multitasking,
|
||
paged virtual memory, no complex VLSI, and a refreshingly capable instruction set,
|
||
and I named this architecture Dauug|36 after its 36-bit word size.
|
||
Here again, the spelling is D A U U G.
|
||
The CPU, memory subsystem, firmware, and real-time operating system kernel work in
|
||
simulation today, but the architecture still needs I/O and initialization that call for
|
||
significant logic outside the CPU.
|
||
So after a couple false starts designing the missing logic from basic gates and flip-flops,
|
||
I decided the way forward is to build in a very small controller that has no complex
|
||
VLSI.
|
||
I named this smaller architecture Dauug|18 because it can't do as much as Dauug|36, and happens
|
||
to use 18-bit words.
|
||
Like Dauug|36, Dauug|18 is built principally from two kinds of components.
|
||
The simpler kind is basic glue logic from the Advanced Ultra-Low Voltage CMOS family
|
||
from Texas Instruments.
|
||
These are a modern take on the 7400 series of basic gates—AND, NAND, OR, NOR, XOR,
|
||
buffer, inverter, and D flip-flop, and they're insanely fast.
|
||
These ICs come in a variety of packages, but to simplify soldering I only use the packages
|
||
that have leads.
|
||
Most of these chips only operate on a single bit at a time, but the buffers and flip-flops
|
||
are available in widths up to 16 bits, which let us direct the flow of data within the
|
||
CPU.
|
||
There are places in Dauug|18 where buffers need to be installed facing both directions because
|
||
data sometimes flows either way.
|
||
Conveniently TI sells buffers with an extra pin to specify their direction.
|
||
You'd think these are called something natural like "bidirectional buffers," but they're actually
|
||
called "bus transceivers."
|
||
The name sounds like they do something complex, but instead they're just buffers that pass
|
||
bits in either direction.
|
||
The other kind of component in Dauug|18 is synchronous static RAM.
|
||
The word "synchronous" here means that the SRAMs' input is clocked through D flip-flops.
|
||
For read operations, the outputs will be ready five and a half nanoseconds after the clock rises.
|
||
I'm going to share specifics about the CPU's bill of materials and topology here because
|
||
they directly impact Dauug|18's capabilities and how it's programmed.
|
||
This being a radio program, I'll do my best to not lose you in these details.
|
||
But if you'd like a visual aid, I've uploaded a PDF with this show, and if you can't find it there,
|
||
you can visit 18.dauug.org (that's 1 8 dot D A U U G dot O R G), and you'll find a
|
||
PDF link near the bottom of the page.
|
||
The Dauug|18 processor contains just six SRAMs.
|
||
Each SRAM is 18 bits wide and has 262,144 words of storage,
|
||
so their address space is also 18 bits.
|
||
It's noteworthy that this capacity is more or less the smallest synchronous RAM on the
|
||
market, and we want to use the smallest chips we can because of their lower cost
|
||
and smaller firmware size.
|
||
Of these six SRAMs, one is data memory.
|
||
You more or less know what that does, and one of the architecture's limitations is that
|
||
it doesn't support any more data memory than the 256 kibiwords that it comes with.
|
||
Fortunately, code goes in a separate SRAM, which means code and data live in separate
|
||
18-bit address spaces.
|
||
Code is inefficiently stored because Dauug|18 doesn't have a control decoder and doesn't
|
||
have any concept of opcodes.
|
||
Dauug|36 has both, but Dauug|18 has neither because it's a simpler processor.
|
||
Instead, Dauug|18's control signals for each instruction are written directly into words
|
||
of the code memory.
|
||
Of the code SRAM's 18-bit width, six bits are used to tell the arithmetic logic unit
|
||
what it's doing, and the remaining 12 bits are all that are left to control the rest
|
||
of the CPU.
|
||
So that's two SRAMs out of six: the data memory and the code memory.
|
||
The third RAM is called "literal memory" and is wired in parallel lockstep with the
|
||
code memory.
|
||
This third RAM stores 18 bits of information for every instruction that needs literal data
|
||
attached.
|
||
So if you need to read from data memory location 1000, the code memory has the control signals
|
||
to produce the read, and the literal memory has the address to read from, which in this
|
||
case is 1000.
|
||
So in effect, Dauug|18 instructions are 36 bits wide, with 18 of those bits being optional
|
||
literal data, 12 bits being control signals, and 6 bits telling the arithmetic logic unit
|
||
what its function is.
|
||
The code and literal data are stored on different chips because the literal output sometimes
|
||
has to be turned off to accommodate other signals, while the control output must never
|
||
be turned off.
|
||
We've knocked out three SRAMs: data memory, code memory control signals, and literal data
|
||
attached to these control signals.
|
||
There are only three SRAMs left, and they implement the arithmetic logic unit's lowest
|
||
six bits, middle six bits, and highest six bits.
|
||
So how exactly do we use SRAM to compute?
|
||
The answer is we don't actually use SRAM to compute.
|
||
Instead, we use SRAM to look up answers we computed previously.
|
||
Here's how this works.
|
||
Recall that the smallest synchronous SRAMs on the market have 18 address bits, and consider
|
||
a sample problem like C = A + B. Since A is on the left side of the expression A
|
||
+ B, we call A the left operand, and B the right operand.
|
||
If we limit the left operand to 6 bits, it can be an integer between 0 and 63 inclusive,
|
||
and we can do the same with the right operand so that it's also an integer between 0 and
|
||
63.
|
||
And for the moment, let's say that our result of adding A + B wraps around so that C
|
||
will fall between 0 and 63.
|
||
So to make SRAM into a gate that can compute any 6-bit sum, we'll need a truth table with
|
||
a 12-bit address space (that's 4096 rows) where each row is 6 bits wide.
|
||
So it's easy for an SRAM to behave like it's adding 6-bit numbers for us; we just have
|
||
to store all the sums in advance.
|
||
So how do we get the other operations we need, like subtraction, bitwise AND, exclusive OR,
|
||
short multiplication, and so on?
|
||
Well, our SRAM has 18 address bits, and two 6-bit operands only come to 12 bits, so we
|
||
have 6 bits left.
|
||
These 6 are our room to say what we want done,
|
||
so we can put 64 operations on our menu so to speak.
|
||
Maybe operation 0 is addition, operation 1 is subtraction, operation 2 is bitwise AND,
|
||
and so on.
|
||
We're constrained to limit the number of operations we support to 64 at most, but that's
|
||
plenty for our purpose.
|
||
You've probably figured out that what I'm describing is something called a bit-sliced
|
||
ALU.
|
||
Rather than try to compute on 18-bit operands directly, which would take almost 70 billion
|
||
words of memory per operation, we split the processor's 18-bit words into 6-bit chunks,
|
||
where we only need about 4 thousand words of memory per operation.
|
||
If you're having trouble confirming the numbers here, remember that both the left and right
|
||
operands need address space, so the difference is between needing 2**36 rows
|
||
and 2**12 rows for each operation.
|
||
A constraint with bit-sliced arithmetic logic units is that each slice is isolated during
|
||
processing.
|
||
During addition, carries from bit 5 into bit 6 and bit 11 into bit 12 are lost.
|
||
We don't have this problem for bitwise logic such as NOT, NAND, and exclusive NOR, but
|
||
tasks such as addition, subtraction, shifts, and rotates need to look across entire words
|
||
to obtain their final answer.
|
||
How can this constraint be overcome with Dauug|18?
|
||
The answer involves three architectural features.
|
||
All three are simple, but this is a radio show, so let's try together to build a picture
|
||
in our minds.
|
||
The first architectural feature for overcoming isolation between bit slices is that each
|
||
Dauug|18 ALU operation produces two results instead of one result.
|
||
I'll explain in more detail in a moment, but for right now take it on faith that when
|
||
an SRAM looks up the 6-bit sum of A and B, it produces two different answers.
|
||
The second architectural feature is that wiring exists to scramble the order of the bits in
|
||
an 18-bit word.
|
||
I use this term wiring very literally.
|
||
It's not logic,
|
||
it's really just copper.
|
||
The third architectural feature is that, unsurprisingly, you can pass any given problem through the
|
||
arithmetic logic unit more than once, meaning you can compute the answer for a hard problem
|
||
using more than one step.
|
||
So let's consider how these three features work together to solve multi-step problems.
|
||
Dauug|18 takes a question like C = A + B, looks up small hints about the answer for
|
||
each slice separately, shuffles those hints between the slices in some magic way to produce
|
||
a new problem that is closer to the final answer, and then feeds the new problem through
|
||
the same arithmetic logic unit.
|
||
That's the big picture.
|
||
Let's go through these features a second time and explain what they mean more fully.
|
||
The first feature was that ALU computations produce two results instead of one.
|
||
We actually get that for free.
|
||
Each SRAM, remember it's the smallest size we can buy, has 18 address bits we use for
|
||
input, and 18 data bits we use for results.
|
||
But the result computed by each SRAM is only 6 bits, meaning we have 12 bits left over
|
||
in every row to use however we need for supplementary results.
|
||
So when we compute the 6-bit sum of 10 + 10, the answer is 20 and won't carry into
|
||
a 7th bit.
|
||
So that SRAM's main output, I actually call it the left output, is 20.
|
||
But that SRAM also has a 6-bit right output, and one of those bits is whether or not a
|
||
carry occurred, and that bit is zero.
|
||
Now suppose we compute the 6-bit sum of 60 + 3.
|
||
The answer is 63, which is six ones that go to that SRAM's left output.
|
||
Does a carry occur?
|
||
Not immediately,
|
||
so the carry in the right output is zero.
|
||
But there might need to be a carry if the SRAM with the next-lower place value outputs
|
||
a carry.
|
||
If there's no carry from the right, 63 just stays 63,
|
||
but if there's a carry coming in, that 63 wraps around to 0.
|
||
That's called carry propagation.
|
||
To handle propagation, the SRAM's right output has a bit named propagate alongside its companion
|
||
bit named carry.
|
||
The propagate bit will be 1 if and only if the local sum is exactly 63, while the carry
|
||
bit will be 1 if and only if the local sum is more than 63.
|
||
So each 6-bit addition on an SRAM produces two results.
|
||
The left result is the 6-bit sum, and the right result has a carry bit and a propagate bit.
|
||
We just need to get the carry and propagate bits over to any SRAMs that have greater place
|
||
value, and then account for them during a future instruction.
|
||
This is where our second architectural feature comes in, specifically, wires that move bits
|
||
of an 18-bit word outside of their immediate 6-bit slices.
|
||
Recall that each of the three SRAMs in the arithmetic logic unit have a left and right operand.
|
||
When given the appropriate control signal within a CPU instruction, a bus transceiver
|
||
will feed the ALU's left output (that's the sum) to become the left operand of the next
|
||
instruction.
|
||
Simultaneously, the ALU's right output (that's the carry and propagate information) are fed
|
||
through buffers to become the right operand of the next instruction.
|
||
The right operand is actually fed by two buffers, with only one of the buffers active at a time.
|
||
One buffer copies the right result straight back to become the next right operand with
|
||
no changes.
|
||
The other buffer transposes the order of the bits so the 6-bit result from each slice is
|
||
distributed two bits at a time into the three SRAMs for the next operation.
|
||
The upshot is that after the clock cycle where each 6-bit subword is added separately, on
|
||
the next clock every SRAM in the ALU sees the 6-bit sum it just generated as its left
|
||
operand, and carry and propagation information for all three subwords as the right operand.
|
||
The ALU SRAMs use this information to add any carries that are needed within each subword.
|
||
This second pass through the ALU is the third and final architecture feature Dauug|18 uses
|
||
to overcome subword isolation.
|
||
You may pick up that when an SRAM generates a carry bit in its right output, it has to
|
||
supply three copies of the carry bit,
|
||
so it can be distributed to all three SRAMs on the
|
||
next clock cycle.
|
||
For the same reason, it outputs three copies of its propagate bit, so all six bits in the
|
||
right result of addition operations have a purposeful use.
|
||
As I mentioned, addition is not the only operation to benefit from allowing the ALU to shuffle
|
||
a few bits between subwords.
|
||
You've probably guessed that subtraction uses the same mechanism, and it also turns out
|
||
that shifts and rotates of any number of bits can likewise be done in constant time.
|
||
Another operation this bit shuffling enables is population count, sometimes called just
|
||
popcount, or sometimes more formally Hamming weight.
|
||
Popcount computes the number of 1 bits in a given 18-bit word, and the result can be
|
||
as small as 0, when the input word is all zeros, and as large as 18, when the input word is
|
||
all ones.
|
||
It only takes three clock cycles for Dauug|18's ALU to compute a popcount, although the surrounding
|
||
CPU will use a few more clocks to fetch the operand from memory and store the result back.
|
||
Another operation that uses few clock cycles in this ALU design is computing hash values
|
||
for associative arrays.
|
||
This operation is closely related to another task this ALU does in a few clocks, which
|
||
is generate pseudorandom numbers that have good statistical properties.
|
||
Yet another is arbitrary permutations of the bits in an 18-bit word.
|
||
These three operations are efficient because the ALU effectively forms a substitution-permutation
|
||
network.
|
||
In the substitution step, the three SRAMs replace 6-bit subwords of the left operand
|
||
controlled by 6-bit keys in the right operand.
|
||
This substitution takes one clock cycle.
|
||
In the permutation step, which takes no clock cycle, each subword's output is split three
|
||
ways among the subwords of a future right operand.
|
||
If you're interested in the general theory of SRAM arithmetic logic units, including
|
||
how multiplication and division work without additional hardware, the Dauug|36 documentation
|
||
at 36.dauug.org goes into much detail.
|
||
Be sure to check out the download section.
|
||
That's 3 6 dot D A U U G dot O R G.
|
||
And if there's something you can't find or need explained better, I hope you'll drop
|
||
me a line.
|
||
Since the Dauug|18 virtual machine is pre-alpha and hasn't released any files as of March
|
||
2026, I'm probably the only person who's tried to write code for the architecture.
|
||
I'm happy to share it's not an easy CPU to write assembly code for.
|
||
You might think well, assembly code isn't easy in general, or maybe I'm not good at
|
||
writing assembly code.
|
||
You're probably right both times, but this is different.
|
||
I've written thousands of lines of Dauug|36 assembly code, and I've found Dauug|36 a joy to write
|
||
code for.
|
||
But Dauug|18 is more contorted to code due to its economy of components and bottlenecks
|
||
in data handling.
|
||
Here are some of the issues one faces coding for Dauug|18.
|
||
First off, the instruction pointer doesn't count linearly.
|
||
There's no end-user benefit to ordering the code addresses 0, 1, 2, and so on, and implementing
|
||
a linear order would require a counter that doesn't exist as an off-the-shelf component
|
||
with the speed and transparency of operation we need.
|
||
Dauug|36 manages to count linearly, but it uses a 27-bit incrementer comprising 70 gates that
|
||
only work because Dauug|36 can absorb two clock cycles of latency while counting.
|
||
In contrast, Dauug|18 has no extra clock cycles for incrementing a counter between instructions.
|
||
Both CPUs have a 40 MHz clock, but Dauug|18 pulls 40 MIPS while Dauug|36 only gets 10 MIPS.
|
||
Fortunately, there's no technical problem if an instruction pointer counts in a nonlinear
|
||
order, as long as it's deterministic and has a long enough period.
|
||
The only hardware needed, other than 18 flip-flops that hold the current address, is one XOR gate.
|
||
The circuit is called a Galois linear feedback shift register, abbreviated LFSR, and LFSRs
|
||
have been used for more than 50 years as a lightweight alternative to linear instruction
|
||
counters.
|
||
Another issue coding for Dauug|18 is it has no return address stack.
|
||
What you ideally want to do is write your program so no subroutines are reentrant.
|
||
Then each subroutine can allocate one word of data memory for its return address, and
|
||
a caller can save the return address before branching to the subroutine.
|
||
When it's time to return, the subroutine can fetch the return address and branch directly
|
||
to it.
|
||
For subroutines that must be reentrant, you'll need to brute force some kind of return address
|
||
stack in software.
|
||
Likewise there is no hardware-based stack pointer, so reentrant code (if there is any)
|
||
has to do extra work spilling local variables.
|
||
This brings up the further limitation that Dauug|18 really has only one address mode for
|
||
data memory;
|
||
specifically, the memory location being read or written is whatever address happens to
|
||
be at node 1 of the circuit board.
|
||
Node 1 can be driven by literal data in an instruction, or the most recent data memory
|
||
read, or the most recent ALU output, but no further adjustments are made to the address.
|
||
If you need an offset from a base pointer, for example, you're going to need to use the
|
||
ALU to compute that offset, and I'll point out that this can spill whatever ALU result
|
||
you were looking to store in the first place.
|
||
If you're familiar with the riddle where a farmer needs to move a wolf, goat, and cabbage
|
||
across a river one at a time, that's what Dauug|18 memory handling is like in practice.
|
||
It would be different if Dauug|18 had any registers other than the clocked outputs that are inherently
|
||
part of the SRAMs that comprise the CPU.
|
||
Unfortunately, no. Dauug|18 doesn't have any registers,
|
||
that's another limitation that the programmer is called on to overcome.
|
||
Another issue is that although most ALU operations are binary in the sense that they combine
|
||
two operands, as opposed to unary where only one operand is used, there is no direct access
|
||
to supply the ALU with its right operand.
|
||
The only place where the right operand electrically reaches the ALU comes from the ALU's own right
|
||
output.
|
||
This isn't the end of the world, but it adds clock cycles and consumes code memory.
|
||
For instance, if you want to add two numbers, you have to first pass the right operand through
|
||
the ALU from the left side to the right side, which adds a clock cycle to an already-tricky
|
||
addition sequence.
|
||
Another issue with Dauug|18 is that it has no freestanding controller for input or output,
|
||
nor is it designed to have I/O ports that are wider than perhaps a couple of bits.
|
||
On top of all that, all I/O would have to be polled because Dauug|18 has no interrupts
|
||
to facilitate transfers.
|
||
Another limitation in programming and using Dauug|18 is lack of any mechanism that can programmatically
|
||
change code memory.
|
||
You can't just launch a program from a command prompt, not unless the program you want already
|
||
resides in memory.
|
||
The reason this can't work is Dauug|18 doesn't have any microcoding or control decoder, so
|
||
the code memory is needed during every clock to control the CPU.
|
||
No cycles are left when the code memory is free and can be updated.
|
||
One challenge Dauug|18 assembly language programmers will face, and right now there are no other
|
||
languages implemented, is the architecture doesn't have any opcodes.
|
||
Instead, the language describes a collection of control signals that operate the processor.
|
||
The present assembler has rudimental macro support that can somewhat approximate opcodes,
|
||
but the strange flows that result from not having any registers make for complex instructions
|
||
and an appreciable learning curve.
|
||
Dauug|18 is certainly Turing complete and can overcome the aforementioned limitations
|
||
if given enough attention and clock cycles, but only within the umbrella of the architecture's
|
||
18-bit address space.
|
||
Once you're out of code or data memory, neither will expand, and although you could dive into
|
||
the tarpit of swapped external pages, the architecture's near-total lack of I/O support
|
||
make swapping even less realistic than it was on historic architectures.
|
||
The problem is even more acute for code memory, which stores programs inefficiently and can't
|
||
be changed at all by the CPU.
|
||
So with all these constraints imposed on programming and use, is Dauug|18 a lost cause?
|
||
I certainly don't think so.
|
||
In fact, Dauug|18 is on track to be the world's most advanced transparently functioning computer
|
||
when its first prototype is built.
|
||
Here is a machine that's entire operation is determined by open-source firmware and
|
||
a builder's soldering.
|
||
No "black box" parts at all, yet a footprint the size of a postcard.
|
||
Its 18-bit address space might sound small if you're very young, but I was once an MS-DOS
|
||
power user, and 256K is more than most people realize, especially when an architecture has
|
||
18-bit bytes instead of 8-bit bytes.
|
||
And remember that code for your programs doesn't count against the 256K limit for data.
|
||
And in terms of my need—a coprocessor to load firmware and handle I/O for Dauug|36, Dauug|18
|
||
checks my boxes about perfectly.
|
||
It's also hard for me to ignore Dauug|18's potential as an educational tool that implements an
|
||
entire architecture succinctly, transparently, and uniquely.
|
||
I've stressed on this show that Dauug|18 is missing a lot in terms of functionality, but it's
|
||
also missing a lot of headaches.
|
||
There's no dynamic RAM at all, so there are no RowHammer-like vulnerabilities.
|
||
There's no VLSI complex logic except in peripherals you choose to attach
|
||
that could hide exploitable defects.
|
||
There's no writable CPU persistent state;
|
||
the only state that survives a power cycle is its open-source firmware.
|
||
There's no electrical path for the CPU to modify its code memory, strongly reducing
|
||
an attacker's options for injecting code.
|
||
There's no CPU microcode to poison, and the CPU's only firmware is a completely disconnected
|
||
set of one-clock-cycle ALU operations that occur only in the order specified by a running
|
||
program.
|
||
Even this firmware can't be modified without physical access to the machine.
|
||
Dauug|18's clock is generated by a crystal oscillator directly, not a micro-electromechanical system
|
||
with a programmable frequency synthesizer.
|
||
MEMS oscillators are very popular now, but they create opportunities for age-selected
|
||
and frequency-selected attacks that simple crystal oscillators aren't vulnerable to.
|
||
Because the Dauug|18 firmware uses a substitution-permutation network to produce pseudorandom
|
||
numbers and associative array hashes, there are S-boxes in the firmware, but unlike some
|
||
of history's notorious ciphers where S-boxes were manipulated, Dauug|18's S-boxes have no
|
||
unexplained constants.
|
||
Instead, they're extracted from the square root of two using 29 lines of Python, and no
|
||
imported modules whatsoever. Even from the Python standard library.
|
||
No one has any unfair or unlevel knowledge of how Dauug|18's S-boxes work.
|
||
All Dauug|18 components are hand-solderable and can be probed after assembly to confirm that
|
||
all connections match the open-source netlist.
|
||
There is no secret functionality, no vendor lock-in, no encrypted or closed-source firmware,
|
||
no license fees to build, use or modify the machine, no purpose-of-use limitations,
|
||
no proprietary components to be discontinued without substitutes, no planned obsolescence,
|
||
and no right-to-repair infringements.
|
||
You can learn more about Dauug|18 and Dauug|36, including how to support both projects, at
|
||
dauug.org, spelled D A U U G dot O R G.
|
||
My name is Marc Abel, spelled MARC : ABEL.
|
||
Thank you for listening.
|
||
You have been listening to the Hacker Public Radio podcast, at hackerpublicradio.org.
|
||
Today's show was contributed by a HPR listener like yourself.
|
||
If you ever thought of recording a podcast, then visit the HPR site to find out how easy it really is.
|
||
Hosting for HPR has been kindly provided by anhonesthost.com, the Internet Archive, rsync.net, and the HPR Community Content Delivery Network.
|
||
Unless otherwise stated, today's show is released under a Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.
|