Blog of Hector Martin (marcan), a hacker known for Asahi Linux, writing on reverse engineering, debugging, and hardware hacking.
Commenters praise him as a talented hacker and cite his Go runtime bug write-up as a gripping debugging story. His Asahi resignation post is also referenced.
[ Woops, I went into GPT-3 mode. I'm really bad at rambling concisely, and fitting the result into a couple of comfortably short paragraphs. :/ ]
Thing was, Alley Cat was the only (interesting) game on the machine in question... and when I (sadly) explained what I'd done to the person who gave me the system, they responded by promptly deleting the EXE file. While a bit of a tangent, my honest thanks for helping me realize (as I type this) that this memory was what kicked off the deep-seated negative associations I've had around gaming my whole life, and why I often lock up whenever I think about the subject. (!)
I completely agree that filesystem recovery is somewhat of a more advanced topic, and entirely unfair to expect mastery of at ~10 :D. I kind of understand about 42% of https://marcan.st/2015/10/rescuing-a-broken-ntfs-filesystem/ myself, for example.
I'm very curious how you managed to end up staring at a system with the DriveSpace driver un-loaded though; that just sounds broken. I wonder if you tripped over an uncaught bug/edge case in the setup process.
(And yeah, the system I was using had DOS 6.20 on it, thus had DoubleSpace instead.)
[TIL about the Dysan brand of floppy disks]
How'd you figure out that BAS = QBASIC?
In my case, the person who gave me the PC randomly decided one day that it needed a menu, "so we didn't need to type commands in". The PC sat in my bedroom, and Mum rarely used it... but okay, whatever works. Well, said menu ended up being a…
On many operating systems, including macOS and Windows, the only ABI-stable interface is a userland-to-userland interface. Application code loads a shared library vended by the system and calls functions from that library like open() or CreateFileW(), in userland. These functions are in turn are usually thin wrappers around system calls with equivalent argument lists – but not always, and even when they are, it's only an implementation detail. Trying to call system calls directly without going through the wrappers risks incompatibility with future OS versions, e.g. [1].
On Linux, traditionally, the userland-kernel interface itself is ABI-stable. The userland code can be fully custom and doesn't even need to support dynamic linking. Syscall numbers and arguments are fixed, and application code can perform its own syscall instructions. You can then layer something like glibc on top of that, which provides its own syscall wrapper functions with a corresponding stable (userland-to-userland) ABI, but that's separate.
The vDSO has always been a step away from that. It's userland code, automatically mapped by the kernel, that provides its own system call wrappers. Applications are still allowed to make system calls manually, but they're encouraged to use the vDSO instead. Its original purpose was to allow certain functions such as gettimeofday() to be completed in userland rather than actually performing a syscall [2], but it's been used for a few other things. It's…
> are interoperable in Rust (block_on)
Blocking an OS thread as a mean to be compatible is not exactly what we're trying to do here.
> Except the performance difference between a kernel-mode context switch and a user-mode one is only going to narrow in the future
OS overhead can be minimized, but program stacks are a function of the language's. And if you're not right sizing preemption points in your stack, you'll be switching large parts of it. This means you _must_ have stackful coroutines if you want to keep switching threads.
> The real solution to expensive context switches is to just do fewer of them... No context switch is always faster than a "fast" context switch.
Sure, but writing the perfect assembly and using gotos has always been the fastest. Abstraction has a cost, and some runtimes/languages are currently proving that they can reduce this cost to zero in the current conditions of IO being much costlier than a few 100s of nanos. We're just happening to be at a time where the compiler is starting to be smarter than the user. But I guess the benchmarks will settle all this.
> Just look at this issue: https://marcan.st/2017/12/debugging-an-evil-go-runtime-bug/
So that's a bug in the go compiler. They can either fix it or pay a "a small speed penalty (nanoseconds)" as a workaround, which the author qualifies as "acceptable".
Yes, that's not the absolute performance possible. But why care about that? At some point it all comes down to TCO (except for…
The "Colored function problem" is a complete fallacy: aside from the fact that async and non-async fns are interoperable in Rust (block_on) and other languages, the same argument could be made against functions with any preconditions.
> The solution to expensive context switches is cheap context switches, plain and simple.
Except the performance difference between a kernel-mode context switch and a user-mode one is only going to narrow in the future. The overhead that cannot be eliminated from context switches is their effect on the cache, since you start to run into the laws of physics at that point...
The real solution to expensive context switches is to just do fewer of them... No context switch is always faster than a "fast" context switch.
> I sincerely believe this is Rust's ballpark
I think it's plausible that Rust could get a library-level solution for fibers that does not rely on unstable details of the compiler. Rust will never again have that baked in to the language, as it would make the language completely unsuitable for many low-level tasks.
Fibers, especially the way they are implemented in Go, come with a lot of their own complexity.
Just look at this issue: https://marcan.st/2017/12/debugging-an-evil-go-runtime-bug/
This is just one of the segfaults caused by Go's complex stack control. I don't want to rely on a runtime that contains these sorts of bugs, and the best way to avoid that is to avoid having a runtime in the first place.
http://www.eevblog.com/forum/reviews/ftdi-driver-kills-fake-ftdi-ft232/msg535378/#msg535378
marcan:
"In case anyone was still wondering if this is intentional and malicious...
Straight out of their driver. Function/variable naming and comments mine.
https://marcan.st/transf/ftdi_evil.png
I figured out what's going on with the real chips: turns out their EEPROM is written in 32bit units. Writing to even addresses is ignored; the value is buffered and the address discarded. Writing to odd addresses writes the entire 32bits, using whatever value was last buffered for the other half. So both the PID write and the checksum write are ignored on real FTDI chips, as they are both written to even addresses. I still don't know why it works on clone chips though, since the checksum is written to the wrong place (it should normally be on an odd address); presumably they don't check it."
Basically driver is fuzzing 'chips claiming to be FTDI' with illegal instructions. Want to play clone games? better emulate me completely, otherwise tough titties. I like it. Might not work to well for FTDI in the end due to PR nightmare, but from engineering standpoint its quite brilliant.
There are wifi drivers; you just have to install them separately because they use broadcom chips. It's a proprietary blob. The other things do work, but it requires special packages and you'll need an external keyboard while installing. It's a pain to install, for sure, but it's not insurmountably difficult to get it installed.
Apple Silicon chips are arguably more compatible with Asahi Linux [1], but that's largely in thanks to the hard work of Marcan, who's stepped down as project lead from the project [2].
Overall I still think the right choice is to find a laptop better suited for the purpose of running linux on it, just something that requires more careful consideration than people think. Framework laptops, which seem well suited since ideologically it meshes well with linux users, can be a pain to set up as well.
[1] https://asahilinux.org/
[2] https://marcan.st/2025/02/resigning-as-asahi-linux-project-lead/