1. 17
  1.  

  2. 5

    I had way too much fun paring the binary down to under 1KB, so thought it would be fun to show off. This is a tool for the very limited use-case of writing your own bare metal kernel (to replace Linux) on a raspi 3.

    1. 3

      Nice work. How small did you get it in the end, and did you use any interesting tricks to get the size down?

      1. 4

        I wish there were some clever tricks; it might have made an interesting blog post. Since I wrote the code in 32-bit arm first, the biggest help was things that improved in arm64: CRC-32 and integer division are now built-in instructions, which saved me two routines.

        Other tricks:

        • “Re-roll” any loops and use subroutines heavily. Don’t paste code or unroll anything. A modern CPU can do thousands of instructions per byte to the UART at 115200bps, so the extra branches won’t matter.
        • Don’t obey calling conventions near the leaf nodes (which for me, was the entire program). I noted that a leaf routine trashed registers x0 to x3, then made the calling routine (one step higher in the call-stack) use registers x4 - x6 instead. ret {reg} helps a lot here, because the routine prelude can be just mov x7, lr. Effectively, arm64’s generous register file became my stack.
        • My favorite trick was using extr to rotate a word and add an incoming byte in a single instruction, in uart_read_u32. This is pretty much what extr is for, so it’s not especially clever. I just had to spend an hour reading through the instruction descriptions, looking for interesting ones that might help.
        • The loss of conditional execution was rough, but it felt like csel and tbz really do cover most of the use cases. In particular, tbz can be used to make a tight loop if you’re counting up to a power of 2.
        1. 1

          Thanks for the update, sounds interesting and well worth a blog post to me.

      2. 1

        Have you done this? Specifically writing your own bare metal kernel?

        1. 1

          I’ve… started. :) I got pretty far in rust in 32-bit mode before deciding I should jump into the deep end and go full 64-bit. I’ll definitely post my progress to github as I get things working.

          1. 1

            Very cool! What’s the goal? By that I mean, what features are you looking for in your as yet to be completed kernel?

            1. 2

              My loose goal, besides “fun”, is to build a non-posix unikernel that boots into a text environment reminiscent of the old Apple II. No real goal behind that, though it would be nice to get USB & wifi working.

              1. 2

                Are you familiar with the Ultibo unikernel for the Pi, which provides a neat Wirthian environment implemented completely in Object Pascal?

                1. 2

                  I am now! Very cool! :)

                2. 1

                  SO interesting to me how many people are hearkening back to that time!

                  Makes me think of tic-80 - https://tic.computer/

                  Sounds like a fun project. Good luck!

                  1. 1

                    There were even TIC-80 demos at Revision this year. This placed #10.

                    1. 1

                      Very cool! tic-80 is so much fun. it really evokes the feeling of working in that 8 bit, self contained, everything IMMEDIATELY accessible space while using a modern language, syntax and tools.

        2. 0

          Nice