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.


Overview



    You want an operating system.  Unless you live for patching binary code as it is running, you probably need one.  And you want it to be fast, so that you can run as many applications as possible.  And you want it to run as many programs as possible.  You don't want to have to get a new port of every old DOS program you own -- the OS should run them for you.  As a programmer, you want a simple assembler-level API, solid mid-level tools, and a good C/C++ compiler.  As a coder, you probably want to be able to modify the kernel and play with how it works.

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.

Progress



  The current kernel is version 0.1.6.  If you have an earlier test kernel, you're living in the past, man!  All the source code has been changed, as well as the entire system structure.  The new architecture is based on ideas that were coming to mind on the edge of the old Moo32 kernel.  The previous system was too tangled to support the new design, however.  Hopefully, this revision will remain clean enough to provide the powerful base neccesary to provide the stability and extensibility that is demanded by the MPI model.  Cross your fingers!

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 responsible for several important tasks.  First, it must get the processor into 32-bit protected mode and set up the Interrupt Descriptor Table (IDT) and the Global Descriptor Table (GDT).  Next, it must start up some sort of disk driver.  The current MLK is designed to load the kernel from floppy disk, for development purposes.  A Moo32 system would typically use a hard disk driver in place of the floppy driver to load the kernel image from fixed storage.  A finalized version of the MLK should have support for both floppy and hard disks, so that it can load a backup image in case of fixed disk image failure.

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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Download


  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.



 
 
 
kernelc.zip
Test version of the MLK kernel.  Far from finalized.
cm32xrdf.zip
CM32 compiler with hacks to create NASM-able assembler output.
reading.zip
Same as documentation found in the Reading section of this page.
 

Reading


Moo32 Plugin Interface
AFiS Directory Structure
RDOFF Specification (from NASM documentation)

Moo32 Plugin Interface

On-The-Fly Call Gate Change Service Not Found Gate Protection Level Violations AFiS Directory Structure RDOFF 1.1 Specification

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