< All Blogs
7/19/20264 minutes
Hello!
what do i put here (ignore the slop image i need a placeholder, :( )
Hello!

There are webshell files bundled with this blog post. Check ~/page_files in the webshell. You can open the webshell by scrolling down to the site footer and clicking the little shell button.


Hi, welcome to my first blog entry! Here’s a list of stuff that changed when I fully revamped and rewrote my entire site, which used to consist of only one page.

Blogs

I have blogs now. It’s more like a scratchpad, if anything. Markdown is supported. It’s pretty cool.

Codeblocks

I can embed blocks of code into the page, like this:

Code (c)
int main() {
    return 1;
}

I originally wanted to use Monaco, but fitting in a fully fledged editor blew up the size of the webpage, so I settled with Shiki instead. Some codeblocks can be ran. This one’s backed by Pyodide, so I can run Python here:

Code (python)
print(332)
"return this value back"

Exception handling and JavaScript exists, too:

Code (js)
console.log("hi")
await new Promise(res => setTimeout(res, 100))
throw 100;

Terminal Output

Terminal outputs are embeddable. They are backed by xterm.js.

Output

Hex Editor

There’s also an embedded hex editor that can be loaded inline into blog pages.

Hex Viewer

Diagrams

Mermaid works fine as well! Here’s one about the webshell:

Diagram
postMessagettyS2ttyS19pBrowser tabSharedWorkerv86ash shellvmutilIndexedDB

It’s also SSRed!

Webshell

In case you haven’t realized already, at the very bottom of the page there is a shell button for you to click. Click it to bring it out! The webshell is fully windowed (within the confines of the website page): it can be dragged around, resized, minified, and closed. Clicking on the foreground hides the tab to the right of the screen.


From a technical perspective, though, it’s a bit more interesting. The webshell runs a minimal install of Alpine Linux off v86 on a shared worker thread. The entire installation is <30MB in size, and has a persistent filesystem as well as an Internet connection.

Operating System

Naturally, I decided to go with Alpine Linux, given that the distro itself is minimal, lightweight, and supports 32-bit x86. Choosing the right distro, however, is only one piece of the puzzle.


The kernel used by the Linux install is custom compiled and stripped down to be light and minimal. On my M2 MacBook, the kernel itself takes only ~1.2s to fully initialize and run the init entrypoint script. I hand rolled a shell script (cat /sbin/init | less) to act as the init process. At idle, there are no more than 3-4 processes running on the system at any given time. I also hand-rolled and optimized the shell profile being used by ash for visual appeal.

Guest-Host Interop

For the webshell to be practically usable (though v86 itself is extremely slow), we need to be able to interact with the VM itself beyond having access to an interactive terminal. I, too, hand-rolled a small C program called vmutil running in the background of the VM started by the init script to handle communication between the VM and browser worlds though an unused teletype exposed to the VM. As a matter of fact, if you run ps aux, you will see vmutil running in the background right now!


Using a tty exposed to the Linux system is enough to pass along control signals between the VM and the browser, but for file transport the teletype will be far too slow. To work around this, file transfers take place through the virtio 9p file transport that v86 supports.


The root filesystem that is mounted to the VM is mounted to the VM as a block device containing a read-only squashfs blob. Persistent storage uses a 9p-backed filesystem overlay to 1) store the files in IndexedDB, and 2) avoid the overhead and hassle of allocating a large persistent block device on the browser.


Having 9p-backed filesystems also allowed me to add “attachments” to certain select pages, like this one. If you cd into ~/page_files, you’ll be able to find two scripts that I deliberately left there as VM file attachments, all of which can be ran inside the webshell.

Conclusion?

There’s not much for me to add here. I actually began writing out this personal website a little over a year and a half ago, but did not get to actually publishing it until now. I hope you have just as much fun reading and playing around on my website as I did writing it.