bootloader: (fast 1 zu 1 aus dem lowlvl mag)
org 0x7C00 ; Unsere Startadresse
; -----------------------------------------
; Unser Bootloader
; -----------------------------------------
start:
; Erst brauchen wir einen Stack.
cli ; Keine Interrupts!
mov ax, 0x9000 ; Stackadresse
mov ss, ax ; SS = 9000 (unser Stack)
mov sp, 0 ; SP = 0000 (der Stackpointer)
sti ; Interrupts zulassen
; Bootlaufwerk aus DL speichern
mov [bootdrv], dl
;Lade unseren Kernel
call load
;Springe zu diesem Kernel
mov ax, 0x1000 ; Die Adresse des Programms
mov es, ax ; Segmentregister updaten
mov ds, ax
push ax
mov ax, 0
push ax
retf
; ----------------------------------------------
; Funktionen und Variablen
; ----------------------------------------------
bootdrv db 0 ;Das Bootlaufwerk
loadmsg db "Loading...",13,10,0
; Einen String ausgeben:
putstr:
lodsb ; Byte laden
or al,al
jz short putstrd ; 0-Byte? -> Ende!
mov ah,0x0E ; Funktion 0x0E
mov bx,0x0007 ; Attribut-Byte (wird nicht benötigt)
int 0x10 ; schreiben
jmp putstr ; Nächstes Byte
putstrd:
retn
; Lade den Kernel vom Bootlaufwerk
load:
; Diskdrive reset (Interrupt 13h, 0)
push ds ; Sichere DS
mov ax, 0 ; Die gewünschte Funktion (reset)
mov dl, [bootdrv] ; Dieses Laufwerk ist gewünscht
int 13h ; Den Interrupt ausführen
pop ds ; DS wiederherstellen
jc load ; Geht nicht? -> Noch mal!
load1:
mov ax,0x1000 ; ES:BX = 10000
mov es,ax
mov bx, 0
; Sektoren lesen (Interrupt 13h, 2)
mov ah, 2 ; Funktion 2 (Lesen)
mov al, 12 ; Lese 12 Sektoren
mov cx, 2 ; Cylinder=0, Sector=2
mov dx, 0 ; Head=0, Laufwerk=0
int 13h ; ES:BX = Daten vom Laufwerk
jc load1 ; Fehler? Noch mal!
mov si,loadmsg
call putstr ; Meldung ausgeben
retn
times 512-($-$$)-2 db 0 ; Dateilänge: 512 Bytes
dw 0AA55h ; Bootsignatur
kernel: (auch zu großen teilen ausm lowlvl mag, nur bischen umgeändert zum rumspielen)
; ---------------------------------------------------
; Makros
; ---------------------------------------------------
%macro printf 1
mov al, 0x01
mov si, %1
int 0x21
%endmacro
%macro getstr 1
mov al, 0x02
mov di, %1
int 0x21
%endmacro
%macro shcmp 1
mov di, shpuf ; string 1 = shellpuffer (muss nullterminiert sein)
mov si, %1 ; string 2 = befehl
call compstr ; strings vergleichen
cmp ah, 0 ; wenn alles gleich
%endmacro
; ---------------------------------------------------
; Unser Kernel
; ---------------------------------------------------
mov ax, 1000h ; Segmentregister updaten
mov ds, ax
mov es, ax
start:
mov si, msg
call putstr ; Schicke Bootmessage :)
call regint
printf msg_1 ; Noch eine Message :D
call shell
printf msg_2 ; Noch eine Message :D
call getkey ; Warte auf einen Tastendruck
jmp reboot ; Reboot
; -------------------------------------------------
; Funktionen und Variablen
; -------------------------------------------------
msg db 13,10,"system is booting...",13,10,0
msg_1 db "loading shell...",13,10,0
msg_2 db "press any key for reboot",13,10,0
shpuf db 0 ; shell-variablen
times 254 db 0
shellmsg db "dave shell 0.01 is ready",13,10,0
sh_reboot db "reboot",13,10,0
sh_fuck db "fuck",13,10,0
sha_you db "you!",13,10,0
sh_files db "files",13,10,0
sha_files db "Ist die Floppy-Diskette mit FAT12 formatiert? (j)a, (n)ein",13,10,0
format_start dw 0 ; diskettenformatierung
db 0 ; JmpBoot
db "noreos " ; OSName
dw 0xFF ; BystesPerSec
db 1 ; SecPerClus
dw 1 ; RsvdSecCnt
db 2 ; NumFATs
dw 224 ; RootEntCnt
dw 2880 ; TotSec
db 0xF0 ; MediaType
dw 9 ; FATSize
dw 18 ; SecPerTrack
dw 2 ; NumHeads
dd 0 ; HiddenSec
dd 0 ; TotSec32
db 0 ; DrvNum
db 0 ; Reserved
db 0x29 ; BootSig
dd 0 ; VolumeID
times 11 db 20h ; VlumeLabel
db "FAT12"
times 3 db 20h ; FileSysType
times 448 db 0 ; Dateilänge: 512 Bytes
dw 0AA55h ; Bootsignatur
times 9216 db 0 ;
; Stringausgabe
putstr:
lodsb ; Byte laden
or al,al
jz short putstrd ; 0-Byte? -> Ende!
mov ah,0x0E ; Funktion 0x0E
mov bx,0x0007 ; Atrribut-Byte
int 0x10 ; schreiben
jmp putstr ; nächstes Byte
putstrd:
retf
; Warte auf einen Tastendruck
getkey:
mov ah, 0 ; Funktion 0
int 016h ; Ausführen
retf
; Rebooten (HEX Dump).
reboot:
db 0EAh
dw 0000h
dw 0FFFFh
_int0x21:
_int_0x21_ser0x01: ; string ausgeben
cmp al, 0x01
jne _int0x21_ser0x01_end
_int0x21_ser0x01_start:
lodsb
or al, al
jz _int0x21_end
mov ah, 0x0E
mov bh, 0x00
mov bl, 0x07
int 0x10
jmp _int0x21_ser0x01_start
_int0x21_ser0x01_end:
_int_0x21_ser0x02: ; string in shpuf einlesen
cmp al, 0x02
jne _int0x21_ser0x02_end
mov cx, 0
_int0x21_ser0x02_start:
call getkey ; zeichen einlesen
mov ah,0x0E ; Funktion 0x0E
mov bx,0x0007 ; Atrribut-Byte
int 0x10 ; zeichen wieder ausgeben (echo)
stosb ; in den shell-puffer schreiben
inc cx
cmp cx, 253
jz _int0x21_ser0x02_full
cmp al, 13 ; wenn enter gedrückt wurde
jz _int0x21_ser0x02_term
jmp _int0x21_ser0x02_start
_int0x21_ser0x02_full:
mov al, 13
mov ah,0x0E ; Funktion 0x0E
mov bx,0x0007 ; Atrribut-Byte
int 0x10 ; cr ausgeben
stosb ; cr an shpuf anfügen
_int0x21_ser0x02_term:
mov al, 10
mov ah,0x0E ; Funktion 0x0E
mov bx,0x0007 ; Atrribut-Byte
int 0x10 ; nl ausgeben
stosb ; nl an shpuf anfügen
mov al, 0
stosb ; nullterminieren
jmp _int0x21_end
_int0x21_ser0x02_end:
_int0x21_end:
iret
regint:
push dx
push es
xor ax, ax
mov es, ax
cli
mov word [es:0x21*4], _int0x21
mov [es:0x21*4+2],cs
sti
pop es
pop dx
retf
shell:
printf shellmsg ; shell geladen message ausgeben
shell_start:
getstr shpuf ; load string in shellpuffer
shcmp sh_reboot
jz shell_end ; shell beenden
shcmp sh_fuck
jz shella_fuck ; fuck - you!
shcmp sh_files ; dateien
jz shella_files
jmp shell_start
shell_end:
retf
shella_fuck:
printf sha_you
jmp shell_start
shella_files:
printf sha_files
call getkey
mov ah, 6Ah
cmp ah, al
jz shella_files_fat12 ; ist Die Diskette schon mit FAT12 formatiert?
mov ah, 3
mov al, 19
mov ch, 0
mov cl, 0
xor dx, dx
mov ax, ds
mov es, ax
mov bx, format_start
int 13h
shella_files_fat12:
jmp shell_start
compstr:
compstr_start:
mov ah,[si]
mov dh,[di]
cmp ah, dh
jnz compstr_term
inc si
inc di
mov ah, [di]
or ah, ah
jz compstr_end
jmp compstr_start
compstr_term:
mov ah, 1
compstr_end:
retf