metropolis/node: move misplaced packages out of core
abloader, bios_bootcode and minit don't run as part of the core process,
so it doesn't make sense to have them in //metropolis/node/core.
This changes moves these three to //metropolis/node.
Change-Id: I908efb311a138f07a9f1de8e3c23437ff00131ee
Reviewed-on: https://review.monogon.dev/c/monogon/+/4196
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
Tested-by: Jenkins CI
diff --git a/metropolis/node/bios_bootcode/BUILD.bazel b/metropolis/node/bios_bootcode/BUILD.bazel
new file mode 100644
index 0000000..55577a4
--- /dev/null
+++ b/metropolis/node/bios_bootcode/BUILD.bazel
@@ -0,0 +1,17 @@
+load("//metropolis/node/bios_bootcode/genlogo:def.bzl", "gen_logo")
+
+gen_logo(
+ name = "logo.asm",
+ logo = ":logo.png",
+)
+
+genrule(
+ name = "bios_bootcode",
+ srcs = [
+ ":boot.asm",
+ ":logo.asm",
+ ],
+ outs = ["boot.bin"],
+ cmd = "nasm -d LOGO=$(location :logo.asm) $(location :boot.asm) -f bin -o $@",
+ visibility = ["//visibility:public"],
+)
diff --git a/metropolis/node/bios_bootcode/README.md b/metropolis/node/bios_bootcode/README.md
new file mode 100644
index 0000000..4480344
--- /dev/null
+++ b/metropolis/node/bios_bootcode/README.md
@@ -0,0 +1,11 @@
+# BIOS Bootcode
+
+This package contains legacy bootcode which is displayed to non-UEFI users.
+It's sole purpose is to explain users their wrongdoing and tell them to use UEFI.
+It also shows a cute ascii-art logo.
+
+## Build
+
+Bazel generates the logo content with `genlogo`.
+It takes a black/white png-file and converts it to RLE encoded data,
+which is rendered as ascii-art at runtime.
diff --git a/metropolis/node/bios_bootcode/boot.asm b/metropolis/node/bios_bootcode/boot.asm
new file mode 100644
index 0000000..222e913
--- /dev/null
+++ b/metropolis/node/bios_bootcode/boot.asm
@@ -0,0 +1,89 @@
+org 7c00h
+
+start:
+ jmp main
+
+; si: string data, null terminated
+; di: start offset
+writestring:
+ mov al, [si]
+ or al, al
+ jz writestring_done
+ inc si
+ mov byte [fs:di], al
+ add di, 2
+ jmp writestring
+writestring_done:
+ ret
+
+; si: rle encoded data (high bit == color, lower 7: length)
+; di: start offset
+writegfx:
+ mov al, [si]
+ or al, al
+ jz writegfx_done
+ inc si
+
+ mov cl, al
+ and cx, 0b01111111
+ shr al, 7
+
+writegfx_nextinner:
+ or al, al
+ jz writegfx_space
+ mov byte [fs:di], 'M'
+writegfx_space:
+ add di, 2
+ sub cx, 1
+ jz writegfx
+ jmp writegfx_nextinner
+writegfx_done:
+ ret
+
+main:
+ xor ax, ax
+ mov ds, ax
+
+ ; set mode 3 (text 80x25, 16 color)
+ mov ax, 0x3
+ int 0x10
+
+ ; set up fs segment to point at framebuffer
+ mov ax, 0xb800
+ mov fs, ax
+
+ mov di, 4
+ mov si, logo
+ call writegfx
+
+ mov di, 3400
+ mov si, line1
+ call writestring
+
+ mov di, 3544
+ mov si, line2
+ call writestring
+
+end:
+ jmp end
+
+; Workaround to pass file as argument
+%macro incdef 1
+ %push _incdef_
+ %defstr %$file %{1}
+ %include %{$file}
+ %pop
+%endmacro
+
+incdef LOGO
+
+line1:
+ db "Hi there! Didn't see you coming in.", 0
+
+line2:
+ db "Unfortunately, Metropolis can only boot in UEFI mode.", 0
+
+db 0x55
+db 0xAA
+
+; We don't fill the rest with zeros, as this is done by mkimage and friends.
\ No newline at end of file
diff --git a/metropolis/node/bios_bootcode/genlogo/BUILD.bazel b/metropolis/node/bios_bootcode/genlogo/BUILD.bazel
new file mode 100644
index 0000000..c8769a4
--- /dev/null
+++ b/metropolis/node/bios_bootcode/genlogo/BUILD.bazel
@@ -0,0 +1,14 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+
+go_library(
+ name = "genlogo_lib",
+ srcs = ["main.go"],
+ importpath = "source.monogon.dev/metropolis/node/bios_bootcode/genlogo",
+ visibility = ["//visibility:private"],
+)
+
+go_binary(
+ name = "genlogo",
+ embed = [":genlogo_lib"],
+ visibility = ["//visibility:public"],
+)
diff --git a/metropolis/node/bios_bootcode/genlogo/def.bzl b/metropolis/node/bios_bootcode/genlogo/def.bzl
new file mode 100644
index 0000000..5db80ee
--- /dev/null
+++ b/metropolis/node/bios_bootcode/genlogo/def.bzl
@@ -0,0 +1,32 @@
+def _build_logo_impl(ctx):
+ arguments = ctx.actions.args()
+
+ arguments.add_all(["--input"] + ctx.files.logo)
+ output = ctx.actions.declare_file("logo.asm")
+ arguments.add_all(["--output", output])
+
+ ctx.actions.run(
+ outputs = [output],
+ inputs = ctx.files.logo,
+ arguments = [arguments],
+ executable = ctx.executable._genlogo,
+ )
+
+ return DefaultInfo(
+ files = depset([output]),
+ )
+
+gen_logo = rule(
+ implementation = _build_logo_impl,
+ attrs = {
+ "logo": attr.label(
+ allow_single_file = True,
+ ),
+ "_genlogo": attr.label(
+ default = Label(":genlogo"),
+ allow_single_file = True,
+ executable = True,
+ cfg = "exec",
+ ),
+ },
+)
diff --git a/metropolis/node/bios_bootcode/genlogo/main.go b/metropolis/node/bios_bootcode/genlogo/main.go
new file mode 100644
index 0000000..f810357
--- /dev/null
+++ b/metropolis/node/bios_bootcode/genlogo/main.go
@@ -0,0 +1,88 @@
+// Copyright The Monogon Project Authors.
+// SPDX-License-Identifier: Apache-2.0
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "image/color"
+ "image/png"
+ "log"
+ "os"
+)
+
+func main() {
+ input := flag.String("input", "", "")
+ output := flag.String("output", "", "")
+ flag.Parse()
+
+ if *input == "" || *output == "" {
+ log.Fatal("missing input or output flag")
+ }
+
+ inputFile, err := os.Open(*input)
+ if err != nil {
+ log.Fatal("Error opening image file:", err)
+ return
+ }
+ defer inputFile.Close()
+
+ img, err := png.Decode(inputFile)
+ if err != nil {
+ log.Fatal("Error decoding image:", err)
+ }
+
+ if img.Bounds().Dx() != 80 || img.Bounds().Dy() != 20 {
+ log.Fatal("Image dimensions must be 80x20")
+ }
+
+ var linear []uint8
+ for y := 0; y < img.Bounds().Dy(); y++ {
+ for x := 0; x < img.Bounds().Dx(); x++ {
+ gray := color.GrayModel.Convert(img.At(x, y)).(color.Gray).Y
+ linear = append(linear, gray)
+ }
+ }
+
+ // Perform RLE compression
+ var rle []uint8
+ for len(linear) > 0 {
+ val := linear[0]
+ l := uint8(1)
+ for i := 1; i < len(linear); i++ {
+ if linear[i] != val {
+ break
+ }
+ l++
+ }
+
+ L := l
+ for l > 0 {
+ block := l
+ if block > 127 {
+ block = 127
+ }
+ rle = append(rle, (val<<7)|block)
+ l -= block
+ }
+ linear = linear[L:]
+ }
+
+ rle = append(rle, 0)
+
+ outputFile, err := os.Create(*output)
+ if err != nil {
+ log.Fatalf("failed creating output file: %v", err)
+ }
+ defer outputFile.Close()
+
+ outputFile.WriteString("logo: db ")
+ for i, r := range rle {
+ if i > 0 {
+ outputFile.WriteString(", ")
+ }
+ fmt.Fprintf(outputFile, "0x%02x", r)
+ }
+ outputFile.WriteString("\n")
+}
diff --git a/metropolis/node/bios_bootcode/logo.png b/metropolis/node/bios_bootcode/logo.png
new file mode 100644
index 0000000..5f395df
--- /dev/null
+++ b/metropolis/node/bios_bootcode/logo.png
Binary files differ