ramdisk boot from ROM

28 views
Skip to first unread message

Douglas Miller

unread,
May 15, 2023, 7:59:00 PM5/15/23
to SEBHC
I am separating this discussion out from other threads in the hopes it
gets the necessary attention.

One of the issues with booting from ramdisk is you have something that
is allocated and formatted by an OS but we're asking for the ROM to know
how to access it for booting. Since loading the bootstrap never requires
knowing about filesystems, we have a manageable task. But, one potential
issue is that different OSes may have different memory requirements
(currently it is CP/M 3 and MP/M) and so their ramdisk cannot start in
the same location as used by HDOS or Heath CP/M, and their normal
operation requires using an area that others consider their ramdisk.

In addition, we want to allow ramdisk "users" (OSes) to sub-divide their
RAM area however they like. Since the ROM cannot know about that, the
ROM only loads the first sectors from the defined ramdisk area, and has
no knowledge of how an OS might have partitioned it. The unit number and
boot string are already passed to the bootstrap code (for all devices),
so that bootstrap code is the best place to determine which partition to
actually boot. This is the convention already established for harddisks,
and should apply for ramdisk as well.

I'm thinking of a couple ways forward:

A) The ROM is hardcoded to boot ramdisk from 010000, meaning that any OS
using more than 64K cannot have a bootable ramdisk. This also ignores
the problem that running an OS using more than 64K will trash the
ramdisk used by any other OS. Not to mention that there may be ramdisk
conflicts/collisions, such as booting HDOS (and using the RD0:) after
having setup a CP/M ramdisk.

B) The new monitor ROM defines byte(s) in the config area that define
reserved memory and/or ramdisk boundaries. This requires that any OS
using a ramdisk (and extra memory) must check the data and honor it. It
also means we need to find a way for older monitor ROMs (systems) to
work (and for the OS to handle the case of running on an older system).

C) We find some other method for defining the RAM layout, like a
reserved block (page) of RAM. This has additional challenges because
this scheme would have to handle the case where memory is not
initialized, presumably containing random data. Perhaps the first OS to
create a ramdisk "claims" the memory, and (for example) a subsequent
attempt to boot (say) MP/M will fail since MP/M won't have the memory it
needs. Or the CP/M 3 ramdisk won't get created because that memory area
has been claimed by (say) HDOS. A lot would need to be worked out.

Of these solutions, I probably hate (B) the least - but we'd need to
come up with a story for how this works on a system without the extended
monitor ROM (how the same OS drivers will detect and handle that case).
At this point, I'm thinking we don't want to maintain multiple driver
versions (and thus OS images) for the different cases. Doing something
like that would mean you cannot (for example) move a CF card from one
machine to another, unless both machines have the same vintage of ROM.

norberto.collado koyado.com

unread,
May 16, 2023, 5:03:45 PM5/16/23
to se...@googlegroups.com
I agree that it should boot regardless of the ROM monitor and seamless to the OS. 

From: se...@googlegroups.com <se...@googlegroups.com> on behalf of Douglas Miller <durga...@gmail.com>
Sent: Monday, May 15, 2023 4:58:57 PM
To: SEBHC <se...@googlegroups.com>
Subject: [sebhc] ramdisk boot from ROM
 
--
You received this message because you are subscribed to the Google Groups "SEBHC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sebhc+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sebhc/d72c31c0-baff-ef20-cb1e-8ae7c0b1e541%40gmail.com.

smb...@gmail.com

unread,
May 16, 2023, 6:16:14 PM5/16/23
to SEBHC
Taking a slightly different perspective on it, a separation of concerns.

The MonitorROM's sole responsibility with respect to the Ramdisk is to boot it. That is, to load pages off the Ramdisk into memory and execute them. It doesn't care how big the Ramdisk is. It doesn't care what OS is on the Ramdisk. It doesn't even care whether the Ramdisk is valid instructions or is random gibberish (though the result of executing random gibberish is undesirable). It does need to know one thing, and that is where the Ramdisk starts in memory, because it has to know what sectors to fetch.

The HDOS Ramdisk Driver and INIT don't care about whether the Ramdisk is bootable or not. They don't care whether Newmon is installed or some other ROM. They don't care whether the user uses other operating systems, though they may get perturbed if some other clumsy operating system damages their Ramdisk. They do care about where the Ramdisk starts, in as much as they don't want to put the Ramdisk on top of their own executable 64K of memory. If the user wants to reserve additional memory (and the user may wish to do so, lest CP/M clobber his Ramdisk), the user could tell the Ramdisk Driver and INIT to do this via a `SET RD: START <n>` command. It's best that the user be deliberate and explicit about this and tell the driver what the user wants to happen. The driver will remember.

So what remains is to have some means for INIT to tell MonitorROM where the Ramdisk starts. It can do this by putting a magic value ("IAMARAMDISK!") at a well-known offset in the Ramdisk's boot sector. It takes no additional overhead (i.e. no special page) to do so as there's spare room in the Ramdisk's boot sector for the magic value. There's also enough spare room to store the length of the Ramdisk (and implicitly the start of the next potential Ramdisk) if that would be useful. When MonitorROM goes to load the Ramdisk, it checks to see if "IAMARAMDISK!") is present at the well-known offset in the boot sector. If so, it boots it. If not, then it skips ahead in 64K increments until it finds it. After 32 attempts, it has exhausted the maximum size of RD0 and it gives up and tells the user RD0 does not exist.

The advantage of this is that the user does not need to coordinate anything between HDOS and the Monitor ROM.

The disadvantage is that by unfortunate coincidence, someone could put `IAMARAMDISK!" at the special offset and cause a Ramdisk to be detected when there is none. That's unlikely to do accidentally. More plausible is someone creating a Ramdisk, then loading CP/M and obliterating part of the Ramdisk but leaving "IAMARAMDISK!" intact. If the user does this, it's his fault. He should have reserved the extra space. We could try to mitigate this by checksumming the sector, or even two sectors (boot loader is 512 bytes?).

Alternatively, I don't think option B, making the Ramdisk start explicit in the boot monitor, is a bad idea. However,  the OS shouldn't care what boot monitor was used. The OS should assume that the driver's options (i.e. the `SET RD: START <n>` command) was performed correctly by the user.

Scott

Douglas Miller

unread,
May 16, 2023, 8:20:28 PM5/16/23
to se...@googlegroups.com

I would assume this also means that the "boot helper" programs (RDBOOT.ABS, RDBOOT.H8T) would employ the same algorithm to locate the start of the ramdisk area.

One drawback is that one can't have part of the ramdisk for HDOS and part for CP/M. I guess one way around that would be to further define this "IAMRAMDISK!" sector to contain partitioning information, so that HDOS and CP/M can locate their designated areas to use. This might fall to the bootstrap code to handle, similar to how the various HDD bootstraps do it. The ROM only locates the "IAMRAMDISK!" sector and loads the bootstrap. The bootstrap then looks at information like unit number and boot string and decides what "partition" to actually boot. This bootstrap need not know whether it is booting HDOS or CP/M - it is just the same standard boot procedure (load the first 0A00H bytes of the partition and jump to them). In other words, each partition (if bootable) looks like the boot sectors of a floppy. The drivers would also have to consult this "IAMRAMDISK!" sector in order to locate the partition(s) they are allowed to use. This, again, is similar to the HDD drivers (at least the MMS style) where the "magic sector" is read to determine where the partitions exist. We'll need to make sure all the boot steps honor the partitioning, if it exists. We can easily create a standalone program (loaded from VDIP or tape) that assists in creating the partition information, perhaps making things more convenient. Theoretically, the same code base could be used for all versions, including .ABS and .COM (with a little effort).

smb...@gmail.com

unread,
May 17, 2023, 5:36:19 PM5/17/23
to SEBHC
What does RDBOOT.ABS do?

Yeah, I was thinking we could include a small amount of partition information alongside "IAMARAMDISK!". We have spare room, but it's not unlimited. If we're frugal, we can come up with some form of partition table. It could just be a set of (kind, 16k-pages) tuples. "Kind" could be set to an int that maps to "reserved", "hdos", "cpm", etc. Two bytes per partition would suffice.

If someone builds the 8MB board, I'd assume they would give a whole 2MB ramdisk to HDOS and a whole 2MB ramdisk to CP/M, and have 4MB to spare (for more Ramdisks!). However, if someone is using the 512K board, then I can see the logic in being able to divide that 512K into smaller pieces. 

Scott

Douglas Miller

unread,
May 17, 2023, 7:27:09 PM5/17/23
to se...@googlegroups.com

Ok, so trying to summarize the "rules" so far:

1) The start of ramdisk area is designated by the "IAMARAMDISK!" (or other key/cookie) block and will be found only on 64K boundaries. OSes (CP/M 3, MP/M) may not use memory beyond (and including) this block for their program memory.

2) The "IAMARAMDISK!" block is 512 bytes long (or TBD?).

* I might suggest that this block contain the primary bootstrap, so may begin with a JMP before the cookie and be longer than 512 bytes.

* In fact, the length of this block might be simply defined by (bounded by) the location of the first partition.

3) The key/cookie is followed by a partition table (format TBD, but includes a "type") (and other information?). This might be embedded - at a well-defined location - in the bootstrap code there.

Partitions must begin on 16K boundaries (are defined by a MMU "page" number).

* This effectively means that the primary bootstrap and partition table are in a 16K page that is otherwise not used. This would allow for "after market" primary bootstraps that did fancy things like present a menu and allow the user to choose what to boot.

4) All OS drivers must honor the partition table and only use memory designated as their "type".

5) Boot (ROM, Tape, etc) will load the "IAMARAMDISK!" block (TBD) into 2280H and jump to it.

The bootstrap contained therein is responsible for locating the desired unit/partition (as specified by AIO.UNI and the boot string), loading that partition's bootstrap, and continuing the boot.

* I expect the primary bootstrap to be the same for all OSes. OS-specific bootstraps are put in the target partition to be booted (secondary bootstraps).

I'm envisioning that the "H8-8M-MMU" board can function as a variable-capacity memory solution, providing anywhere from 512K to 32M (in 512K increments). Therefor, I'm thinking we don't want to restrict any of this to merely 512K or 8M, but design it such that any capacity is supported, and even allow for expansion (addition of more memory later, amending the partition table to match).

Does this sound like a starting point?

smb...@gmail.com

unread,
May 17, 2023, 10:34:42 PM5/17/23
to SEBHC
This all sounds good, Douglas. I would suggest we shorten "IAMARAMDISK!" down to something a little smaller. Maybe a 32-bit value. Then again, "IAMARAMDISK!" is pretty darn unlikely to collide. :D

JMPing over the magic value and partition table was exactly what I had in mind.

Note my prior comments though on it being inconvenient for the 8MB RAM Board if a Ramdisk spans a 2MB boundary, so we might want to build that restriction in to the partitioning scheme.

Regarding the 512 bytes of room we have to work with, the boot code in the init module is from 042.240 to 044.200, which is 480 bytes. The current "readonly driver" (necessary to boot HDOS) fills 322 bytes of that space, leaving 158 bytes remaining that are currently empty. So we have lots of room, unless we start making the readonly driver more complicated, in which case we start eating up that 158 bytes with more instructions. Still, 158 bytes to play with seems like plenty for our purposes.

Scott

Reply all
Reply to author
Forward
0 new messages