Last update: 2003-2-21
Back to research page .
After implementing a first draft of ‘Self-Stabilized Shell’, We understood that although it is a relevant small program it depends heavily on C library functions like
‘printf’ or no IPC mechanisms, which we currently cannot guarantee to be stabilized.
So we turn to a bottom-up fashion work.
I’ll write a minimal OS, preferably in assembler so I can prove it behaves as needed.
After booting this OS loads only one program.
Periodically this program is loaded again to RAM in order to insure code correctness of the running program.
This minimal OS can be than further expanded even with the C Run time library, in order to make it machine independent.
1) Hardware fires.
2) Firmware – a little software in ROM, checks hardware and look for bootable device.
3) Bootloader – find kernel & load it
4) Kernel - Bootstrap procedure: initialize subsystems like interrupts, memory, devices etc.
5) Login process.
6) Shell
From [ Irvine_1999 ] page 33, which focused on Intel 80x80 processors and the MS-
DOS booting procedure:
1) CPU loads ‘bootstrap loader’ from ROM BIOS.
2) This procedure is looking for bootable device.
3) Usually the ROM procedures are copied to faster RAM. (Which means it is a Stabilization candidate).
4) Loading various low-level routines (io.sys), and kernel routines
(msdos.sys).
5) Then initiating data structures for files and other devices (config.sys)
6) Loading the resident part of the command processor (command.com) to memory.
7) Executing user startup programs (autoexec.bat).
8) User can type name of programs on disk to be loaded & executed.
More links to good articles and code [ Boot_Links ].
8086 and 80888 could access 1 MB of memory, with 20 bit absolute addresses.
(Because the registers are only 16 bit long, the addresses are calculated from 2 registers with base and offset). The addresses range from 0 to FFFFF hexadecimal.
The first K contains the interrupt vector table.
Then software bios – routines for managing keyboard, console, printer & timer.
Then kernel & the resident part of the shell.
The ROM BIOS, which contains programs and data burned to it, is located at the end of this 1MB in addresses C0000-FFFFF.
80286 – Called the previous state ‘Real Mode’ and introduced protected mode which enables access to 16 MB of RAM.
80386 – ‘Virtual Mode’ each program an access 4GB of memory – with swapping.
Support processors (which have connection to the work):
Intel 8237 – DMA (We might change memory with it).
Intel 8259A – Interrupt Controller.
Intel 8254 – Timer ticks (System clock 18.2 times per seconds, memory refresh timer and clock).
[Source File] ->
(assembler) ->
[object file] ->
(linker with [libraries]) ->
[executable program] ->
(OS loader - decodes header & loads to memory) ->
CPU execution & [output]
When program is loaded to memory, the DOS OS creates a special 256-byte block
Program Segment Prefix.
The block contains various data including the command arguments.
There are two types of programs:
COM: unmodified binary image of machine language program..
It is loaded to memory by DOS to the lowest available segment address, prefixed by the PSP. The total size of the program can not cross 64KB. The code, data & stack segment are stored at the same physical (and logical) segment.
To link it with TASM: link /T <obj name>
EXE: Stored on disk with EXE header, which contain information of how to load and execute the program. EXE program may contain up to 65,535 segments.
Detailed explanation about Interrupts (hardware), Exceptions (sftware errors) & Traps
(software).
When interrupt occurs the hardware pushes the flag register and a far address back to the current PC address, also other interrupts are disabled.
Example of how to install ISR (Interrupt Service Routine) in raw assembly or using
DOS functions (The advantage of the latter is that some programs are getting notified about the change).
In order to implement switching between the program and the minimal OS, we will use the timer interrupt.
[ Hergert_1997 ] & [ Irvine_1999 ] details the interrupt routine:
1) Hardware Interrupt is signaled to the CPU by activating the INT pin.
2) Interrupt number is read from the data bus (In case of software interrupt the number comes with the INT instruction).
3) The flag, CS & IP registers are pushed to the stack (the IRET instructions pops them back) the interrupt flag is cleared to prevent other interrupts.
4) At the lowest address in memory resides the interrupt vector table; each entry contains a far address (CS + IP) of the corresponding interrupt routine.
5)
Currently we’re after INT 8 - Timer clicks (18.2 times per second),
This timer has the highest IRQ level (0) which means no other interrupt can interrupt it while in progress.
6) Install a new interrupt routine : INT21 function # 25
From [ INTEL 2002 ] Chap. 15 Interrupt and Exception Handling:
Details for protected mode. (Chap 16 deals with 8086 emulation).
Each exception is assigned an identification number called ‘vector’.
These vectors are used as pointers into the Interrupt Descriptor Table.
The vector range is 0-255, 0-31 are reserved for the IA-32 architecture.
There are 2 types: External & Software generated.
Starting from Pentium, processors have built in device for generating interrupts called
APIC (see chap. 8) it has Local Vector Table which can be programmed to replace the regular ones. Otherwise the 8259A is used through the bus.
Also stuff about exceptions.
The IDT can be located anywhere in the linear address space, and is located by the
CPU with the IDTR register. The entry for each vector is calculated by multiplying it by 8 (bytes).
The LIDT & RIDT instructions load & store to memory the the IDTR value (CPL must be zero!?).
Normally OS’s use this commands to install IDT (or switch one).
In protected mode there is a notion of interrupt task (opposed to interrupt gate), which means a context switch is performed when the interrupt occurs.
Chap 5.7 NMI:
Can be generated externally with the NIM pin, or internally (from Pentium) as message on the system bus or APIC bus with NIM mode.
When this arrives the interrupt handler at vector 2 is called immediately and other interrupts are disabled.
Watch dog:
PC Board with watchdog that generate RESET or NMI: http://www.dge.com.au/manuals/cm388trm.pdf
yal: http://www.walshcomptech.com/ohlandl/config/watchdog_timer.html
Google : CDROM mapping to linear address space.
Outlook : Asm links.
The procedure:
A) Address change in the interrupt vector table.
B) Writing a new procedure.
C) Call:
- pushf (the flag register, since usually these procedure return with IRET, which POPs this register).
Call with the right INT arguments.
Some code, that works with DOS interrupts:
; Get the table entry mov ah, 35h ; Ask for interrupt vector
mov al, ??h int 21h
; Get the vector value for int ??h
; Put address in ES:BX
; Save the old one mov word ptr original_int, bx mov word ptr original_int[2], es
; Set the new procedure address in table mov ah, 25h mov al, ??h
; Ask to set table
; set int??h to ds:dx mov dx, offset new_proc int 21h ; set int?? to new_proc
; Set in memory moc dx, offset unwanted_code int 27h ; Terminate but stay resident.
Boot process:
- PC Power up
- Memory address 0xFFFF is loaded to the IP register ad the command which resides there is executed. (This is where the BIOS is mapped).
- BIOS (Basic IO system) loads the first sector of a bootable device to memory address 7c00h, and set cpu IP register to that address.
- The sector contains a first stage boot loader, which set up a minimal file system
(FAT12) and loads from disk a 2 nd
stage loader.
- Boot loader Installs interrupt handler for time interrupts of the 8259 processor.
- Keep this handler in memory.
- Load actual program\kernel from disk.
The interrupt handler routine (called for every time tick): counter <- counter + 1 if couner = 0 then read program code from disk and update program code segment.
The handler itsef should be loaded from disk from time to time, and also the interrupt vector table.
The program’s location & size in memory must be fixed.
Downloaded and installed Easy OS [EasyOS] .
Installed Easy OS image on floppy and manage to boot with it.
The download contains the following files:
Setup.exe: Make a bootable disk (with root account)
Make.bat
: The same, but with a readable script, which assembles the sources and copies them to a floppy.
Nasm.exe: Free assembly [Nasm]
boot.asm
–sector 0: bootstrap - goes to sector 0 at the booting disk, just calls the next component.
This file must be at exactly 512 bytes size i.e. fill the whole sector.
This is because the sector must end with 2 bytes AA55h, which mark a valid bootstrap.
It will be loaded to memory address: 07C00.
This program only loads the next program to continue hardware initialization. bootinit.asm
– sectors 1-4: continue booting, serial peripherals initialization, calls kernel kernel.asm
– sector 5: file system, calling failsafe (next) since there is no gui. failsafe.asm
– sectors 6-9: simple menu for restarting etc. copyboot.exe
– a utility for copying sectors to boot floppy.
Usage example: copyboot boot.com 0.
With a manual about writing OS with EasyOS [Use EasyOS]
Added to the OS support for FAT12 file system and reading a simple program to memory and executing it.
Replacing the boot loader with a new one that reads a file from disk, loads it & executin it.
Steps to reproduce:
1) The boot loader is in bootsect.asm
.
2)
nasm bootsect.asm –f bin –o botsect.bin
3) Copy it with copyboot to sector 0.
4) Copy an executable with the name OSLOADER.COM to the disk.
(Just drag it to the diskette).
The example comes with funky.asm
that can be assembeled to this executable.
The article contains a simple graphic program in assembly.
Build it with nasm and copy it.
Alternatively the article ‘Writing Kernel in C’
[C Kernel] shows how to prepare an
‘hello world’ program in C and compile it with
Windows) so it can be loaded also.
I836 Emulator
Tried to run EasyOS on [Bochs] emulator, but did not succeed in making a disk
image for EasyOS.
(I managed to run the Linux example, also found documentation on how to make a new image but with Linux mount).
Contains a few examples for simple OS tasks, including multitasking.
Written mainly in C.
Installation:
1) Downloaded image from site (includes the partcopy tool).
2) Boot with win98 floppy.
3) Then: partcopy osd-disk.img 0 168000 -f0
This copies the grub loader with 7 little OS examples.
JOSH [ JOSH ] a real mode simple OS with interrupts & shell:
1) Compiled boot.asm
with nasm to boot.bin.
NASMW BOOT.ASM -o BOOT.BIN -f bin
(configured VS6 to do it: Tools -> Customize -> Tools -> New Tool:
Command: nasmw
Arguments:
Initial Directory:
$(FileName).asm -o $(FileName).bin -f bin
$(FileDir)
)
The boot loader initialize FAT 12 file system on diskette A and searches for kernel.bin.
2) Installed the boot loader on disk with:
Debug boot.bin
-W 100 0 0 1
-Q
3) Compiled the kernel :
It has [ORG 0] directive for putting the code at the beginning of memory target.
Also [bits 16] compiles it to real mode.
Changed the name to Sonix: ‘Sonix is not Unix’ or ‘Self-Stabilized OS not Linux’
4) Added interrupt handler for Int 8 – timer ticks in IA32 real mode.
SONIX
1) Took the 1ch (BIOS 8 calls it) interrupt routing example from [ Hyde_1996 ] chap.
17.4
2) Added a program that installs the ISR, and negotiate with it.
3) The ISR loads the programs code to memory every 1 sec. (after 5 seconds - it changes program code!!!).
4) Separated the ISR data to different segment in absolute memory location, in order for it to be at ROM in the future.
5) Checked the program under Windows and Dos5 (Downloaded bootdisk form bootdisk.com)
Diagram:
Kernel: Install Timer ISR
Load Program
TimerISR(every 55ms):
Update ms counter
If counter > 1000
Load Program to RAM
Print message
Increase second counter.
Program:
Initialize counters
Do forever //While second counter <= 10
Print flag value
Wait a little
Code: timer5.asm
Listing Files: timer5.lst
, TIMER5.MAP
(To produce listing file: >c:\masm613\bin\ml /nologo -c -Fl -Zi timer5.asm)
Compiled with masm6.13 under VC6.0 (C:\MASM613\BIN\ML.exe,
$(FileName).asm /Fl /Zi /Fm)
ISR Stabilization:
Variables:
MSEC – expected values 0..1045 (15X19)
Will take it as positive only.
if value is beyond 1000 it will load program, and will rest to zero.
Otherwise 55 is added and eventually it will reach 1000.
AX - Does not preserve value
Segment registers- Get values from ROM.
Program - ROM
Timer - Temporary (also DX & BX)
Stack - Does not affect ISR, but may affect program!!!
Things to do:
1) What about the 'hlt' command, can it break the stabilization?
Maybe I can run in debug mode and examine every coming command.
Maybe NMI interrupt handler can survive it?
Shlomi: Our CPU won’t have the ‘hlt’ command.
2) The interrupt vector table should be in ROM (at least the timer entry).
Maybe the protected mode IDTR can help, or vice versa.
3) I want to load the program from boot disk.
Meanwhile my boot disk only knows to load com files: Try to convert my program to com or learn to load EXE files. (what about other loader, like GRUB?).
4) The ISR memory should be more stable?!
What is the error source? If not permanent it will stabilize also.
Otherwise: maybe external source like watchdog.
5) The ISR should be in ROM, so I must continue in effort to separate it from other program.
6) Avoid using bios routine for screen updates.
7) Make program changes smarter (maybe by some key).
8) Masking interrupts: Watchdog with NMI?
Working with Debug:
Preparing the simple program (OS):
> Debug
-n program.bin
-a 200
0B06:0200 mov al,1
0B06:0202 inc al
0B06:0204 jmp 202
0B06:0206
-r bx
BX 0000
:0
-r cx
CX 0000
:6
-w ds:200
Writing 00006 bytes
-n watchdog.bin
-a 100
0B06:0100 mov si, 200
0B06:0103 mov di, 300
0B06:0106 mov cx, 100
0B06:0109 movsb
0B06:010A inc si
0B06:010B inc di
0B06:010C loop 109
0B06:010E jmp 300
0B06:0111
-r bx
BX 0000
:0
-r cx
CX 0000
:f
-w ds:100
Writing 0000F bytes
In the following link: www.geocities.com/thestarman3/asm/index.html
There is: Debug tutorial, good help file with x86 commands and stuff about MBR.
Watchdog: Liskov paper assumes it too: http://www.pmg.lcs.mit.edu/~castro/osdi2000/node2.html
Program Source code: loader2.asm
Memory layout for Sonix:
0
1000
7C00
Interrupt vector table
2 nd
stage loader
1 st
stage loader
10000
A0000
A0100
OS
Watchdog handler - ROM
OS Image – ROM
[Bochs] A highly portable open source IA-32 (x86) PC emulator written in C++ http://bochs.sourceforge.net/
Download: http://bochs.sourceforge.net/getcurrent.html
[Boot] Simple Tutorial to boot programming. http://www.nondot.org/sabre/os/files/Booting/nasmBoot.txt
Another one: http://www.geocities.com/mvea/bootstrap.htm
[C Kernel] Writing Kernel in C http://www.themoebius.org.uk/tutes/ckernel.html
Local Copy: Writing a Kernel in C.htm
[Carter] Paul A. Carter, PC Assembly Language
Author (Old Site): http://www.comsc.ucok.edu/~pcarter
Download book pdf: http://www.singlix.com/trdos/pcasm-book.pdf
at: http://www.singlix.com/trdos/specs.html
(may related downloads)
New Version (12/02) http://www.drpaulcarter.com/pcasm/ http://www.drpaulcarter.com/pcasm/pcasm-book.pdf
[DJGPP] DJGPP is a complete 32-bit C/C++ development system for Intel 80386
(and higher) PCs running DOS. It includes ports of many GNU development utilities. http://www.delorie.com/djgpp/
[EasyOS] Download- http://www.geocities.com/solarsistem/gif/files/easyos.zip
Local Copy: easyos.zip
[GRUB] GNU GRUB is a Multiboot boot loader. It was derived from GRUB, GRand
Unified Bootloader, which was originally designed and implemented by Erich Stefan
Boleyn.
Homepage: http://www.gnu.org/software/grub/
Howto: http://my.execpc.com/CE/AC/geezer/osd/boot/grub-how.txt
[IA64] Mosberger D. & Eranian S., ia-64 linux kernel, HP Book
[MultiProgrammig] Multi-Programming in DOS http://www.angelfire.com/myband/unix/os.htm
Code: http://www.angelfire.com/myband/unix/Projects/Mpdos.zip
Local (if used move it to cs site) : Mpdos.zip
[NASM] – a free assembler http://nasm.sourceforge.net/ http://sourceforge.net/projects/nasm
IDE: http://radasm.sonshinesoftware.com/
[OSD] - Operating System Development Site with many links http://my.execpc.com/CE/AC/geezer/osd/index.htm
boot: http://my.execpc.com/CE/AC/geezer/osd/boot/index.htm
[OSDev Newbiew] OSDev Newbie HQ – quick tutorial http://www.info.polymtl.ca/~bono/osdnhq.txt
[OS-FAQ] Write Your Own Operating System [FAQ] http://www.mega-tokyo.com/os/os-faq.html
Local: os-faq.zip
[UseEasyOS] Writing your own operating system by thewomble
http://www.free2code.net/tutorials/asm/os1
Local Copy: Writing your own operating system.htm
[Hergert 1997] PC Architecture from Assembly Language to C, chap. 10 – Interrupts
& IO.
[Irvine 1999] Assembly Language for Intel-Based Computers, ch. 15.3 p. 539
Web: http://www.nuvisionmiami.com/books/asm/
(user: English, pass: Each)
Assembler Links: http://www.nuvisionmiami.com/kip/asm.htm
[MenuetOS] Open-Source realtime graphical OS on 1 floppy written in assembly. http://www.menuetos.org/
Another mini loader: http://www.beroset.com/loader.html
[MASM] Microsoft’s assembler, ver. 6.13 comes with [
downloaded with the mentioned password.
MSDN Reference: http://msdn.microsoft.com/library/default.asp?url=/library/enus/vcmasm/html/vclrf_masm_atversion.asp
Manual: http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/index.html
Howto download page: http://users.easystreet.com/jkirwan/pctools.html
Configure Visual Studio 6: http://es.udmercy.edu/~canjarrm/271/271-tool.htm
[Boot Links]
Explanation + Code + Protected mode jump: http://www.christopherdeguise.com/projects/halos/documentation/HTMLFormat/Boot
Process.htm
This is from a gut who developed a small OS called HAL OS: http://www.christopherdeguise.com/projects/halos/
Simple one, with small c program for placing the boot sector on disk. http://gaztek.sourceforge.net/osdev/boot/gbootsect.txt
Local: gbootsect.txt
Taken from: http://gaztek.sourceforge.net/osdev/boot/polyos.html
Local: polyos.htm
[Norton 1996] Norton P & Socha J., Assembly Language for the PC, Hebrew Edition
1996.
[Intel 2002] The IA-32 Intel® Architecture Software Developer’s Manual, Volume 3:
System Programming Guide. http://developer.intel.com/design/pentium4/manuals/245472.htm
[JOSH] Nice build yourself an OS tutorial: http://www.ansanest.com/josh/
Local: josh/index.htm
[Hyde 1996] The Art of Assembly Language Programming http://cs.smith.edu/~thiebaut/ArtOfAssembly/artofasm.html
or: http://webster.cs.ucr.edu/Page_asm/ArtofAssembly/0_ArtofAsm.html
(There is also a 32 bit version overthere)
Chaining Interrupt Service Routines: http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH17/CH17-4.html#HEADING4-1
More links:
Dictionary of subject related terms: http://www.avp.ch/avpve/gloss.stm
OS Develop Links: http://www.openbg.net/sto/os/links.php
SPIN educational operating system: http://www-spin.cs.washington.edu/
OSD - ? http://mazzanetos.sourceforge.net/ simple os with bootcopy clicker32
Another sourceforge project, with someone’s thesis in ps format. http://osdev.neopages.net/links.php
Digital Systems Construction / Nisan & Schocken / Spring 2002 IDC Course http://www1.idc.ac.il/digitalCore/ http://www1.idc.ac.il/digitalCore/tools/
Assembly Links:
User Timer Tick: http://www.clipx.net/ng/bios/ng477.php
http://www.clipx.net/ng/bios/ng2c68.php
WebSter: The Art of Assembly Language Programming (High Level Assembly) http://webster.cs.ucr.edu/index.html
http://webster.cs.ucr.edu/Page_AoAWin/0_AoAHLA.html
16 bit versions: http://webster.cs.ucr.edu/Page_asm/0_ArtOfAsm.html
COM files tutorial: http://www.bigwig.net/jimmy/doscom.html
Book with interrupts:* http://oopweb.com/Assembly/Documents/ArtOfAssembly/VolumeFrames.html
Links: http://ultimateobject.com.asm.html http://oopweb.com/Assembly/Files/Assembly.html http://directory.google.com/Top/Computers/Programming/Languages/Assembly/x86/
FAQs,_Help,_and_Tutorials/
Interrupt List http://oopweb.com/Assembly/Documents/InterList/VolumeFrames.html http://www-2.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/WWW/files.html
Nasm: http://home.attbi.com/~fbkotler/
LaTeX links:
The Yossi Gil LaTeX Guide for Graduate Students: http://www.cs.technion.ac.il/~yogi/latex.html
WinEdt: PC tex files editor: www.winedt.com
MikTex: PC tex compiler: http://www.miktex.org