- Where in memory should I load the next chunk of data? - I needed to think about the memory arrangement.
- How was I going to actually present this combined chunk of code to VirtualBox? - I needed to find (or write) a tool to create a basic floppy image
- How do you load data from a floppy? - A look at the BIOS routines that are available in 16-bit real mode.
- How many chunks of data should I load?
- Should the amount of data loaded be dynamic or fixed?
Where to load my dataI made the assumption that the answers to these questions weren't all going to get resolved before making a start on the solution. So, if I'm never going to have all the things decided down before I start, then why not start and then go back and modify the stuff I've already written as needed. An iterative (dare I say 'Agile') process.
So I chose my memory map as the first thing to write down. A table of memory addresses and what will live there. It's not a difficult thing to envisage, writing down where all my kernel code and where all the user code would go, but it's a very difficult thing to start. Like other tasks I've spoken about, starting from a clean sheet of paper makes the job seem so much harder. So I started with what I knew: that my code had been loaded by the BIOS into 07C0h.
From there I started to build out a sensible allocation of blocks that should allow this first iteration to at least work, until I was in a position to refactor and fix. I knew, of all the things, this would end up being replaced by a more dynamic and intelligent process of allocation but without at least a stick in the ground, you can't pull yourself up (by those blessed bootstraps) any further.
I documented the layout in Excel, just so that I could have something to refer to and moved on to the next piece, writing my floppy image.
Laying out a floppyThis wan't actually too complicated, once I figured out that it didn't need to actually be 1.44MB big. I figured out that I could make a simple 512 byte file with just one sector (the boot sector) and as long as you didn't try to access any other sector, the VM would simply boot from it quite happily.
So all I did was build a simple Java app that would take a list of binary output files from NASM and stack them all together into a contiguous file. The only subtlety is to pad each input file out to the 512 byte boundary, so that the next file starts on the sector boundary.
I may go into more detail on this tool (or build a better one) in another post.
And the rest
From here, once I had figured out where to put the data that I load from the disk and how to present it to the VM as a 'floppy' image, the rest was pretty much just a case of grabbing the file from the image and loading it into contiguous memory locations.
This is where you start to realize the complexity of making this process of loading a file of arbitrary length. You need to be able to find out (or calculate) how long the file is, you then need to find a location in memory big enough for it to fit, then you need to do it.
And then ... when if the disk contains files that aren't in sequence in the image but rather scattered around the disk, you need to know which sector it starts in and where the other pieces are.
There's still a lot to do.