The funny thing is what literally started all of this is I wanted to update the firmware
on my VisionFive, followed their instructions to a T, and it bricked the firmware.
I found that the embedded recovery ROM still worked, so then tried to follow their
processes to reflash the bootloader/SBI stuff. That likewise failed, so I gave up on
trusting any of their documentation/advice and just started hacking on the thing with
binaries sent over XMODEM on the serial line. Their XMODEM-CRC implementation is broken
so I even had to write my own version of sx (they had a XMODEM send, likewise doesn't
work stock...got it to work modified but then just wrote a simple stdio tool without all
the cruft of their implementation.)
Fast forward to today and the most I've put together for that is this:
https://gitlab.com/segaloco/riscv-bits (src is "kernel" stuff, util is that
XMODEM-CRC transfer thing I mentioned)
I've got some process handling and VM stuff that hasn't gone up to the repo yet,
but it's hanging around because it's incomplete anyway. I then realized with
what I'd learned in the process I was poised to start hacking on other SBCs at that
level, so ordered the Pico, Ox64, and an Onion Omega2 (ARM32, RV64, and MIPS32
respectively) and have slowly been building up development workflows for each (I'm
eschewing vendor libraries and SDKs given my experiences with the VisionFive...)
The boot matter itself is proving the most annoying part, since literally each one of
those has a different mechanism to get an operational binary loaded up. VisionFive is an
(broken) XMODEM-CRC transfer, Pico is a UF2 file over USB, Ox64 is some custom Bouffalo
Lab tool (although I think it's just a wrapper on top of some standard
XMODEM/Kermit/etc. type protocol), and then the Omega2 I haven't even really explored
raw boot yet, it's got OpenWRT on it so I've just been hacking on the existing
OS thus far, getting more familiar with the board, my hunch is it's probably a
UF2-ish thing since it's main UART is over USB like the Pico.
RISC-V presents some complications given the privilege model, what with the
"master" mode vs the "supervisor" mode, as opposed to other chips
where supervisor and master are essentially one in the same. Where I'm torn is if I
want to have OpenSBI in the mix just to go with what is ubiquitous in RISC-V land, or even
try to handle that matter with my own code. That wouldn't necessarily have an analog
on all the other platforms. Then there's hypervisor stuff, what with RISC-V having
the extension and other chips having something akin to this, but it not being universal.
The simple answer is to just get everything, regardless of details into a
"supervisor" state, ensure necessary interrupts are forwarded to this state if
another, higher one exists, and enter into this supervisor state with MMU/VM turned off.
Then theoretically each machine can start from here by setting up memory, then device
inits, then FS and other subsystem init, and finally process init.
Anywho, I'm kinda at a standstill on this project right now while I work on a few
other things, namely a disassembly of Dragon Quest for the Famicom (embedded console games
are a lot like operating systems) and manual page diffing stuff, but I'm hoping to
carve out some time this summer, maybe even a little coding retreat from work for a few
weeks, to hammer out a true project plan on paper so I can start working on more of this
in earnest. I'm not sure yet if I'll be headed down the "get UNIX
going" or "get my kernel going" route first when I get there, but either
way, I'm sure we'll have plenty to talk about in the coming year.
- Matt G.
------- Original Message -------
On Thursday, April 20th, 2023 at 8:57 AM, Paul Ruizendaal <pnr(a)planet.nl> wrote:
Hi Matt,
I’ve responded on list about the early unix development process as I understand it, but I
want to avoid discussing things that are not directly related to the history of Unix.
Hence this PM as well.
Where I'm trying to put this sort of
knowledge into use is I'm starting to spec out a kernel bootstrap for the RPi Pico
and Pine64 Ox64 boards (ARM32 and RISCV64 respectively) that is not only sufficient to
start a V7-ish kernel on each, but that are ultimately based on the same design, varying
literally only where the hardware strictly necessitates it, but similar enough that
reading the two assembly files side by side yields essentially the exact same discrete
operations.
I have a similar interest, working with early Unix and modern RiscV hardware for a
compare and contrast experience.
- My development targets are (i) an FPGA based RV32 SoC implementation, (ii) a Sipeed D1
RV64GC board and shortly (iii) a Pine64 Pinetab-V.
- My software targets are: (a) xv6-rv, (b) SysIII, (c) Linux, (d) experiments around
SysIII
Linux is for me a secondary target, just for comparison and to see if ideas are “Linux
capable”. I’m not overly interested in Arm at the moment.
My ideas are still evolving, but currently more or less along the below lines:
- Boot rom loads SPL, this is custom in each case and set by the SoC's designers.
- SPL initialises DRAM system and loads next stage. Unfortunately, this too would seem to
be quite system specific, but the BSP should provide the baseline for this. As BSP’s are
often a mess, milage may vary.
- The next stage is a hybrid of BBL, OpenSBI and Virtio. The idea is to provide a
standard abstraction layer that all of my software targets can work with. This idea is
used for the FPGA target and allows booting a Linux kernel with just the generic Virtio
device drivers (so far just disk and console).
- The last layer is the classical OS layer. If I get it right, each OS can run on all h/w
targets without customisation.
At the moment I’m playing with USB, and how that might layer into the structure of V7,
SysIII or 8th Edition -- and also the above.