Minimal OS - BGU



Minimal OS

Last update: ‏2003-2-21

Back to research page.

Content

Content 1

Introduction 1

Architecture of 80x86 processor 1

1. The booting procedure 1

2. Memory Architecture of 80x86 2

3. The assembly procedure 2

4. Runtime program format 3

5. Interrupts 3

6. Interrupt “Routing” 3

Start Minimal OS 4

1. General Idea 4

2. Installation of EasyOS 4

3. Start playing 5

4. Another tries 5

Reference 6

Introduction

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.

Architecture of 80x86 processor

The booting procedure

From [IA64]

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 () 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].

Memory Architecture of 80x86

From [Irvine_1999]: p. 32

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).

The assembly procedure

From [Irvine_1999]: p. 60

[Source File] ->

(assembler) ->

[object file] ->

(linker with [libraries]) ->

[executable program] ->

(OS loader - decodes header & loads to memory) ->

CPU execution & [output]

Runtime program format

From [Irvine_1999]: p. 519

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

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.

Interrupts

From [Hyde_1996]

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:



yal:

Google: CDROM mapping to linear address space.

Outlook: Asm links.

Interrupt “Routing”

From [Norton 1996]: p. 389

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 ; Get the vector value for int ??h

int 21h ; 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 ; Ask to set table

mov al, ??h ; 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.

Start Minimal OS

General Idea

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 2nd 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 Customize -> Tools -> New Tool:

Command: nasmw

Arguments: $(FileName).asm -o $(FileName).bin -f bin

Initial Directory: $(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 )

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 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: thestarman3/asm/index.html

There is: Debug tutorial, good help file with x86 commands and stuff about MBR.

Watchdog: Liskov paper assumes it too:

Program Source code: loader2.asm

Memory layout for Sonix:

|0 |Interrupt vector table |

|1000 |2nd stage loader |

|7C00 |1st stage loader |

|10000 |OS |

|A0000 |Watchdog handler - ROM |

|A0100 |OS Image – ROM |

Reference

|[Bochs] A highly portable open source IA-32 (x86) PC emulator written in C++ |

| |

|Download: |

|[Boot] Simple Tutorial to boot programming. |

| |

|Another one: |

|[C Kernel] Writing Kernel in C |

| |

|Local Copy: Writing a Kernel in C.htm |

|[Carter] Paul A. Carter, PC Assembly Language |

|Author (Old Site): |

|Download book pdf: |

|at: (may related downloads) |

|New Version (12/02) |

| |

|[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. |

| |

|[EasyOS] Download- |

| |

|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: |

|Howto: |

|[IA64] Mosberger D. & Eranian S., ia-64 linux kernel, HP Book |

|[MultiProgrammig] Multi-Programming in DOS |

| |

|Code: |

|Local (if used move it to cs site): Mpdos.zip |

|[NASM] – a free assembler |

| |

| |

|IDE: |

|[OSD] - Operating System Development Site with many links |

| |

|boot: |

|[OSDev Newbiew] OSDev Newbie HQ – quick tutorial |

| |

|[OS-FAQ] Write Your Own Operating System [FAQ] |

| |

|Local: os-faq.zip |

|[UseEasyOS] Writing your own operating system by thewomble |

| |

|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: |

|(user: English, pass: Each) |

|Assembler Links: |

|[MenuetOS] Open-Source realtime graphical OS on 1 floppy written in assembly. |

| |

|Another mini loader: |

|[MASM] Microsoft’s assembler, ver. 6.13 comes with [Irvine_1999] and can be downloaded with the mentioned password. |

|MSDN Reference: |

|Manual: |

|Howto download page: |

|Configure Visual Studio 6: |

|[Boot Links] |

|Explanation + Code + Protected mode jump: |

| Process.htm |

|This is from a gut who developed a small OS called HAL OS: |

|Simple one, with small c program for placing the boot sector on disk. |

| |

|Local: gbootsect.txt |

|Taken from: |

|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. |

| |

|[JOSH] Nice build yourself an OS tutorial: |

|Local: josh/index.htm |

|[Hyde 1996] The Art of Assembly Language Programming |

| |

|or: |

|(There is also a 32 bit version overthere) |

|Chaining Interrupt Service Routines: |

| |

| |

More links:

Dictionary of subject related terms:



OS Develop Links:



SPIN educational operating system:

OSD - ?



simple os with bootcopy

clicker32

Another sourceforge project, with someone’s thesis in ps format.



Digital Systems Construction / Nisan & Schocken / Spring 2002 IDC Course





Assembly Links:

User Timer Tick:





WebSter: The Art of Assembly Language Programming (High Level Assembly)





16 bit versions:

COM files tutorial:



Book with interrupts:*



Links:





Interrupt List





Nasm:



LaTeX links:

The Yossi Gil LaTeX Guide for Graduate Students:

WinEdt: PC tex files editor:

MikTex: PC tex compiler:

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download