Discussion:
[N8VEM: 17326] RomWBW boot sequence and making bootable media
j***@public.gmane.org
2014-02-14 23:45:35 UTC
Permalink
Hi all,

Since I'm waiting on the chance to build my own SBC v2, I've been playing
around with the simh emulator. I'm interested in some bare metal / OS
programming in C with sdcc.

I originally intended to write my own ROM and boot loader, but I have since
discovered RomWBW. It very elegantly handles all the disk and terminal IO
for the N8VEM Z80 machines and it seems silly not to take advantage of it,
especially since that way compatibility with CP/M is retained.

I've read most of the documentation on the Wiki, including the RomWBW
Architecture manual, and I've also skimmed the source code
(RomWBW/Source/loader.asm in particular), but Z80 asm is not my strongest
point. I have a few questions:

How does booting from a disk work?

How are bootable disks / disk images laid out? I got far enough to
understand that it checks for a checksum (0xa55a) but beyond that I'm lost.
I saw a reference to a writeimg utility by Douglas Goodall that creates
bootable images (?) but I can't find it anywhere.

Is the boot process process specific to loading CP/M or can RomWBW load and
run any binary/OS? Is there a size limit to the binary it will load?

What I'm hoping to do is write a small script or program to create a
bootable disk image with my binary and then be able to pop it into the SBC
(either emulated or eventually real with an SD card) and have it boot that
and run my program. Is this plausible with RomWBW?

I apologize if these questions have already been answered somewhere;
there's so much good work and development that I bet it'll take me a long
time to get up to speed!

Thanks in advance,

Joel
--
You received this message because you are subscribed to the Google Groups "N8VEM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to n8vem+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/***@public.gmane.org
To post to this group, send email to n8vem-/JYPxA39Uh5TLH3MbocFF+G/***@public.gmane.org
Visit this group at http://groups.google.com/group/n8vem.
For more options, visit https://groups.google.com/groups/opt_out.
Wayne Warthen
2014-02-15 03:20:35 UTC
Permalink
This post might be inappropriate. Click to display it.
j***@public.gmane.org
2014-02-15 22:46:46 UTC
Permalink
This post might be inappropriate. Click to display it.
Wayne Warthen
2014-02-16 01:45:25 UTC
Permalink
Hi Joel,

Nice progress. I think you have figured out ore than you are giving
yourself credit for! Most of the 3 sector header is useless information.
Only the last of the 3 sectors contains anything that the loader cares
about. In fact, the only data the loader really cares about are those 6
bytes at the end which are three words (1) the location to load the os
image in memory, (2) the ending address to load, and (3) the address to
jump to after loading. As you surmised, BOOT_INFO_LOC is not used by the
loader. In fact, at present, the loader does not even check for the 0x5AA5
header signature. Aside from those last 6 critical bytes, the rest of the
header is currently informational and you don't need to worry about it for
your purposes.

Setting a target load location of 0x8000 is problematic because the loader
runs from that location, so you are attempting to load on top of running
code. Consider 0x8000 to 0x0x8FFF to be reserved for the operation of the
loader at this point.

Good luck!

--Wayne
Post by j***@public.gmane.org
Hi Wayne,
Thanks for getting back to me so quickly.
I would say that my attempt is a qualified success thus far. It now boots
my code directly, which is great.
As you noticed, there is "header" data prepended that includes the marker
code as well as information about where to load the system image in memory
and how big it is. The loader reads the header data to figure out how big
and where the system image goes, then it reads sectors sequentially and
loads the image and transfers control to the cold start entry of CBIOS.
Take a look at prefix.asm in the source directory for a definition of the
header data.
In theory, the boot loader is OS agnostic. As long as the disk contains
an appropriate header in the first couple sectors, the loader will refer to
it to determine how many sectors to put in memory and where to place them.
I say "in theory" because I have never tried to use it outside of loading
CP/M OS images.
Between this and a hex dump of a prebuilt .sys file, I was able to piece
together enough of the header to get the ROM to boot my disk directly, at
least under SIMH. The header I've created is laid out like this (hex dump,
0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
*
0000580: 5aa5 0000 0000 0000 0000 0000 0000 0000 Z...............
0000590: 0000 0000 0000 0000 0000 0000 0000 0000 ................
*
00005e0: 0000 0002 0503 1355 6e6c 6162 656c 6564 .......Unlabeled
00005f0: 2044 7269 7665 2024 0000 00c0 00ff 00c0 Drive $........
So the 1st and 2nd 512 byte sectors are empty, and at byte 384 (decimal)
of the 3rd sector, we have the header 0x5aa5, then more zeroes.
Then at byte 487 of the 3rd sector there's 16 bytes which is an ASCII
drive name terminated with $, then at byte 504 there's the "BOOT_INFO_LOC"
pointer which I've ignored and set to zero (is this a problem?).
Finally at byte 506 there are six bytes which are 3 word values of: the
starting point in memory of the loaded binary (c000 in my case), the end
point in memory of the loaded binary (I've simply chosen ff00 which loads
more than is necessary, but works), and finally the entry point (also c000
in my case).
I know my solution is something of a dirty hack (I'm ignoring a number of
things I don't understand yet), but I'm posting it to the mailing list in
case it helps someone else down the line.
I'm sure what I have provided is only a teaser, but let me know if it
helps and I can answer further questions.
I do have a couple more questions.
Am I ignoring anything with my hacked together header that'll cause
trouble (BOOT_INFO_LOC pointed at 0 maybe)?
What is the "metadata" header for? I've simply zeroed it out here, which
seems to work but I'd like to know if that's problematic...
When I set a target of 0x8000 (first byte of high memory) instead of
0xc000 as above, the ROM will load the binary but it seems to break HBIOS
in some way (rst 08 goes nowhere). Is that value too low? I know the ROM
was designed for loading CP/M which usually starts at 0xd000...
Once my code isn't so embarrassing, I'll post it. I'm writing a set of C
routines for using the HBIOS functions (read and write characters and disk
blocks), maybe someone will have some use for that.
Thanks again!
-- Joel
--
You received this message because you are subscribed to the Google Groups "N8VEM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to n8vem+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/***@public.gmane.org
To post to this group, send email to n8vem-/JYPxA39Uh5TLH3MbocFF+G/***@public.gmane.org
Visit this group at http://groups.google.com/group/n8vem.
For more options, visit https://groups.google.com/groups/opt_out.
Loading...