Hello visitor! This page is horribly out of date, but to see the end results of this train of thought, please check out my newer OS project SOBS at http://stout.hampshire.edu/~men99/index.html. Enjoy, and feel free to send me an email.
You don't want DOS. Even with DPMI, DOS is just hack after hack. You want solid code, and you want multithreading.
You don't want Windows. God, do you ever not want Windows.
You don't want NT, either. In fact, you don't want a damn thing made by Microsoft.
OS/2? What's that?
Linux is nice, isn't it? But you don't want a monolithic kernel anymore. The world is into microkerneling now, and you want to spare as much memory as possible for your own programs.
Hrm... running out of options.
At the moment, development is currently being done on the loader kernel. This is a pseudo-Moo32 compliant kernel that already knows basic things about its environment. Its sole purpose in life is to get the real Moo32 kernel off disk, into memory, set up with a few plugins, and activated. As a result, the Moo32 Loader Kernel (MLK) does not follow the MPI plugin standards. Any changes to the MLK must be compiled into it. Being without plugins, the MLK has basic device drivers built in to it. The current MLK has drivers for the following chips:
The MLK is also equipped with a US-encoded keyboard driver and a basic shell. The shell is exists only for test purposes at the moment, but the finalized MLK will contain a modified version of the same shell, equipped with a memory and disk hex editor, basic information and analysis commands, and the ability to load alternate kernel images or start the kernel in single-user mode.
The MLK should remain under 64k in size. This requirement allows
MLKs to be written that allow the booting of the Moo32 kernel from a different
operating system, such as DOS. By limiting the size to 64k, it is
ensured that the MLKs can be written as DOS COM files.
Last night, I scratched out what seems to be the first feasible memory
map for the operating system. Here it is:
System Memory (PL0)
( a ) linear address 0x00000000
( b ) moo32 kernel.
( c ) linear address 0x08000000
( d ) global symbol table.
( e ) linear address 0x40000000
( f ) kernel plugin objects.
Library Memory (PL3)
( g ) linear address 0x80000000
( h ) libraries (libc, etc)
Application Memory (PL3)
( i ) linear address 0xc0000000
( j ) application A (.text and .data
sections)
( k ) application B (.text and .data sections)
( l ) linear address 0xc8000000
( m ) heap A (expands upward)
( n ) heap B (expands upward)
( o ) stack A (expands downward)
( p ) stack B (expands downward)
( q ) linear top 0xffffffff
The current MLK is availible
for download. Note that this is far from complete... it simply loads
up the drivers listed above and starts the basic
shell. The currently supported commands are: "cls", "ver",
"mem", and "ls". ls only works if a Moo32fs disk
is in drive A:, however.
There is a bug that surfaces from time to time, as well. Every once in awhile, the kernel will load but the keyboard will not work. If you can isolate the conditions around this bug, please, let me know!
KERNEL.COM must be run from a clean DOS prompt. It does not use DOS, and sets up its own descriptor tables, which prevents it from running under Windows, 95, NT, EMM386 or any other extended/expanded memory manager. You must turn off all of these before running the program.
![]() |
|
Test version of the MLK kernel. Far from finalized. |
![]() |
|
CM32 compiler with hacks to create NASM-able assembler output. |
![]() |
|
Same as documentation found in the Reading section of this page. |
Moo32 Plugin Interface
AFiS Directory Structure
RDOFF Specification (from NASM documentation)
// Directory format
struct dirsector {
dirheader header;
direntry entries[7];
};
struct dirheader {
dword majik0;
// Magic number 0xa1b2c3d4
dword majik1;
// Magic number (0 for root, 1 for normal)
byte name[48];
// Subdirectory name
sector backlink; // 0 if first in directory
sector forelink; // 0 if last in directory
};
struct direntry {
byte name[52];
dword type; // 0 if
non-existant / erased
dword size;
sector start;
};
// File format
struct filesector0 {
byte name[48];
sector forelink;
sector backlink;
dword size; // data bytes in this node
dword nul;
byte data[448]; // First sector of file
has 448 bytes of data
};
struct filesector {
sector forelink;
sector backlink;
dword size; // data bytes in this node
dword nul;
byte data[496]; // Other sectors have 496 bytes
of data.
};
/*
The SAM is arranged as a 512 byte bitmap on floppy disks.
Bit 0 of byte 0
corresponds to lba sector 0, bit 1 to sector 1, etc. 2 megabytes
can be
mapped with one SAM sector.
*/
RDOFF is the format to be used in writing Moo32 kernel plugins. It's simplicity and relocation ability combine to make it an ideal format. The following text is from \rdoff\rdoff.txt in the nasm distributions.
I seem to keep writing this document... I don't know what keeps
happening to it. Anyway, this one will hopefully stay around for
a
while.
RDOFF is a relocatable object file format whose design goals were
mainly to keep it simple, so that an RDOFF object can be loaded
and
executed by a very small piece of code (primarily so that it can
be
used by the microkernel of an operating system to store system
modules, which can then go on to load and execute more complex
object
files, eg ELF, if so desired), yet still be able to be cope with
everything required by the operating system; linkage of multiple
modules together (possibly with automatic loading of new libraries
that are referred to by the object) at load time, allowing static
or
dynamic linking as required by the application.
The overall format of the file is summarised in this table:
Length (bytes) Description
6 Contains the string 'RDOFF1'
(little-endian targets),
or 'RDOFF' followed by the single byte 0x01
(big-endian targets).
4 Length of the header section
? Header section (see above
for length)
4 Length of code section (.text)
? Code section
4 Length of data section (.data)
? Data section
Segments are referred to as numbers. Imported labels are implicitly
at offset zero from a segment; each is assigned a segment number
when
it is imported. Segments in the object file itself are numbered:
0 - text segemnt
1 - data segment
2 - bss segment
The header consists of a sequence of records, each of which is
preceded by a byte to represent its type.
These records are one of the following types:
1: Relocation Record
--------------------
This record points to an address that will need either
relocation or linkage to an external segment when the object
is loaded or linked.
Length Description
1 Type identifier (must be 1)
1 Segment number (0 or 1) plus 64 if the reference
is
relative (and thus does not require relocation with
the base of the code, only by the difference between
the start of this segment, and the segment referred to
(see below)
4 Offset from start of segment of item requiring reloc.
1 Length of item (1, 2, or 4 bytes...)
2 Segment number to which reference is made.
2: Import Symbol Record
-----------------------
This record defines a segment to start at the location of
a
named symbol; this symbol may need to be fetched from an
external library.
Length Description
1 Type identifier (must be 2)
2 Segment number to allocate
? String containing label (null terminated, max length
=
32 chars)
3: Export Symbol Record
-----------------------
This record defines a symbol, to which external modules can
link using the above record type.
Length Description
1 Type identifier (must be 3)
1 Segment containing symbol (0,1 or 2)
4 Offset of symbol within segment
? String containing label (null terminated, max length
=
32 chars)
4: Import Library Record
------------------------
This record tells the loader that an extra library should
be
loaded and linked to the module at either load- or run-time
(load time is easier, run-time is good, though...)
Length Description
1 Type identifier (must be 4)
? Name of library (null terminated string, max len
= 128)
5: Reserve BSS Bytes
--------------------
This record tells the loader how much memory to reserve after
the executable code loaded from the object file for the BSS
segment (referred to as segment number 2).
A loader can safely assume that there will only be one of
these records per module, but the linker probably cannot...
NASM will only output one, but other utilities may be written
that do, and future versions of NASM may output more than
one.
Length Description
1 Type identifier (must be 5)
4 Number of bytes to reserve