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.
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.
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.
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.
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.
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.
Nice work. How small did you get it in the end, and did you use any interesting tricks to get the size down?
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:
ret {reg}helps a lot here, because the routine prelude can be justmov x7, lr. Effectively, arm64’s generous register file became my stack.extrto rotate a word and add an incoming byte in a single instruction, inuart_read_u32. This is pretty much whatextris 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.cselandtbzreally do cover most of the use cases. In particular,tbzcan be used to make a tight loop if you’re counting up to a power of 2.Thanks for the update, sounds interesting and well worth a blog post to me.
Have you done this? Specifically writing your own bare metal kernel?
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.
Very cool! What’s the goal? By that I mean, what features are you looking for in your as yet to be completed kernel?
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.
Are you familiar with the Ultibo unikernel for the Pi, which provides a neat Wirthian environment implemented completely in Object Pascal?
I am now! Very cool! :)
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!
There were even TIC-80 demos at Revision this year. This placed #10.
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.
Nice