Products Search Support Downloads FAQ Developers Write Us Parody Site - Not Microsoft®
Michaelsoft Binbows

Where do you want to go today?™

Developer Network
Documentation, of a sort
★★★ One main.c, no SDK, no GNU-EFI ★★★ Pull requests welcome, especially the funny ones ★★★ The easiest contribution in the repo is one more declined Linux command ★★★

Binbows for Developers

Binbows is open source. You can read it, build it, break it, and open a pull request that makes it worse in an interesting way. That last one is the intended workflow.

The whole thing is one main.c of about 1,600 lines, a minimal uefi.h with only the protocol definitions it actually needs, a generated font header, and a Makefile. There is no SDK, no GNU-EFI, no EDK2, and no build system beyond make.

The entry point

A UEFI application starts at efi_main with two arguments: a handle representing itself, and the system table, which is the door to everything else. The real thing does more than this, but this is the shape of it.

/* main.c — how Binbows starts */
EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle,
                           EFI_SYSTEM_TABLE *SystemTable)
{
    BS    = SystemTable->BootServices;
    ConIn = SystemTable->ConIn;

    fs_init(ImageHandle);       /* Loaded Image → device → drive C: */
    read_cpu_brand();           /* cpuid 0x80000002-4, for FETCH   */

    /* Locate the framebuffer. No GOP, no picture, nothing to say. */
    BS->LocateProtocol(&gopGuid, NULL, (void **)&Gop);
    if (!Gop) for (;;) __asm__ volatile("hlt");

    show_splash(4000);          /* C:\LOGO.SYS, four seconds       */
    draw_bsod();
    wait_key();
    shell();                    /* never returns                   */
}

Note the hlt loop. There is no operating system to return an error to and no console to print one on, so a missing GOP is the end of the story.

The protocols it uses

Everything Binbows can do, it does through four UEFI protocols. That is the complete list — there is no fifth one, and there is nothing underneath them.

UEFI protocols used by Binbows 98
ProtocolWhat it buys
GRAPHICS_OUTPUT_PROTOCOLA framebuffer address, a resolution, a scanline pitch and a pixel format. Every pixel on screen is written by hand into that buffer.
SIMPLE_TEXT_INPUT_PROTOCOLKeystrokes, polled with Stall() so the cursor can blink in between. This is the entire input system.
LOADED_IMAGE_PROTOCOLWhich device the application was loaded from — the first half of finding drive C:.
SIMPLE_FILE_SYSTEM_PROTOCOLThe second half: the volume's root directory, which becomes C:\. Open, read, close, and the file info structs behind DIR and VOL.
BootServices->Stall()Not a protocol, but it is the only clock in the building. The FORMAT C: hang at 68 percent is one Stall(900000).
Two things that bite. Directory reads end in a variable-length UTF-16 filename, so the firmware answers EFI_BUFFER_TOO_SMALL and expects you to grow the buffer and ask again. And clang lowers copy loops to memset/memcpy/memmove even under -ffreestanding, while -nostdlib supplies none of them — so the project provides its own.

The shell loop

No message queue, no event dispatch, no window manager. The application reads a line and runs it, forever, and it is the only thing running on the machine.

static void shell(void) {
    con_init(make_color(192, 192, 192), make_color(0, 0, 0));

    con_line("Michaelsoft Binbows 98");
    con_line("   (C) Copyright Michaelsoft Corp 1981-1998.");
    con_line("Recovery console. Type HELP for a list of commands.");

    char line[LINE_MAX];
    for (;;) {
        con_put_cwd();
        con_putc('>');
        read_line(line);
        run_command(line);
    }
}

/* If you exit this loop, there is nothing to exit to.
   Which is why EXIT does not. */
PieceWhat it is
con_buf[][]The character grid, mirrored in RAM, so scrolling repaints from memory instead of reading back from the framebuffer — which is very slow.
con_attr[][]A parallel colour plane, one palette index per cell. One byte instead of four, and the palette resolves once against the framebuffer's channel order.
read_line()Line editing, backspace, history on the arrow keys, ESC to clear, and the blinking cursor, all hand-rolled.
run_command()Splits on the first space and walks an if chain of case-insensitive comparisons. No parser, no tokeniser, no shame.
refusals[]A table of about forty Linux command names and the line each one gets declined with. Adding to it is the easiest useful pull request in the project.
bsod_layout[]The blue screen as data: each line, how it sits, and the vertical advance to the next. That makes the block measurable, which is what lets it be centred rather than started at a fixed offset and hoped to fit.

Building from source

The repository builds a bootable ISO. On a modern machine this takes about a second, which would have been science fiction to the people this project is imitating.

# dependencies (macOS)
brew install llvm lld xorriso mtools

# clone and build
git clone https://github.com/lucya-astralis/binbows.git
cd binbows
make

# boot it under QEMU with OVMF firmware
make run
Prerequisites: clang and lld — the target is x86_64-unknown-windows, because a PE/COFF EFI application is, in linker terms, a Windows binary. Plus xorriso and mtools for the image, and qemu with an OVMF firmware image if you want make run. No Python packages, no npm, no container.

Neither mtools nor xorriso has a Windows build, so the repository carries tools/mkfat.py and tools/gptify.py — byte-for-byte substitutes for those two steps, both producing images that have been booted under OVMF.

What is in the repository
FileDescription
main.cEFI entry point, BSOD renderer, text console, filesystem and shell. All of it.
uefi.hMinimal UEFI type definitions — system table, GOP, boot services, text input, simple file system. Only what is used.
font.hIBM VGA 8x16 CP437 font data, generated. See the licence note below.
gen_font.pyFont converter. Reformats the kernel's font_8x16.c; needs no third-party packages, because the source data is already one bit per pixel.
esp/Everything here is copied to the root of the boot volume, which is why DIR has something to show.
assets/logo.bmpThe boot splash, 8-bit with an animation ramp, installed as C:\LOGO.SYS at build time.
tools/mklogo.pyQuantiser and ramp builder for the splash.
tools/mkfat.pyBuilds the FAT12 ESP image without mtools.
tools/gptify.pyAppends the ESP to the ISO as a GPT partition, without xorriso.
ROADMAP.mdWhat is done, what is next, and why. Longer and more honest than this page.
Licence, in one paragraph. The project's own code — main.c, uefi.h, gen_font.py, the Makefile — do whatever you want with it. font.h is the exception: it is a verbatim copy of the IBM VGA 8x16 font from the Linux kernel's lib/fonts/font_8x16.c, which carries SPDX-License-Identifier: GPL-2.0, and those terms cover it and anything built from it. If you need the whole thing under looser terms, swap in a font whose licence suits you and regenerate — gen_font.py is the only thing that would need changing.

Contributing

Contributions are welcome. The bar is not "is this good," it is "does this make the project more itself."

  • Refusals. The lowest-friction contribution in the repository: one line in refusals[], one joke, done. Keep it dry.
  • Bugs: open an issue with the machine, the firmware and what you saw. A photo of the screen is a completely valid bug report here, because there is nowhere to copy text to.
  • Features: discuss first. Some things are deliberately broken and fixing them is a regression. The roadmap says which.
  • Docs: the most valuable and least submitted kind of pull request, as is tradition.
  • Tests: there are none. There is a person who boots it under OVMF and looks at it. You can be that person.

API questions go to [email protected], patches to [email protected], and anything involving a lawyer to [email protected]. The first two are the same inbox. So is the third, spiritually.

Coding style

Match what is there. In case that is ambiguous, what is there is:

RuleRationale
C17, four spacesNot a discussion. The discussion happened and this is what came out of it.
Braces on the same lineK&R. The file is consistent about it and consistency beats your preference here.
Sections marked with rulesLong comment dividers separate the BSOD, the console, the filesystem and the shell. It is one file; it needs the signposts.
80 column limitYour terminal is 80 columns wide. So is the thing you are writing. It has always been 80 columns wide.
Comments explain whyThe code already says what. The interesting comments in main.c are all about firmware behaviour you would not guess from the call.
No emoji in sourceThe website is allowed to have fun. The kernel is not. Especially this one, which is not a kernel.

Open the repository   Downloads

🚧 API DOCS EXPANDING 🚧
The protocol notes are incomplete, which puts them in good company.