Autor Thema: bootloader...  (Gelesen 4824 mal)

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« am: 27. April 2006, 20:02 »
hi!

koennte mir einer von euch bitte einen beispielcode fuer einen bootloader zeigen denn eine beliebige anzahl von sektoren in ner schleife einzeln liest und dann ausfuert? ich komm hier einfach nicht weiter!!!!

DANKE!!

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 27. April 2006, 20:16 »
Dies ist der mein alter Bootloader, den ich aus verschiedenen Quellen zusammengebastelt hab. Er hat schon lange keine Aktualisierung mehr erfahren, weil ich ihn nicht mehr nutze. Das meiste von dem Code hab ich verbrochen, allerdings die Funktion readsector stammt von jemand anderen. Hab ich aber vergessen.

Ich möchte jetzt nicht für diesen Post irgendwelche Veränderungen vornehmen, weil ich die dann testen müsste und so weiter. Aber ich kann sagen was der Code in dieser Form tut:
1. (nach ein bisschen Heruminitialisiere) wird load_kernel aufgerufen, dass 50 Sektoren nach 0x1000:0x0000 (-> KERNELSEG) lädt.
2. Dann werden Selektoren mit 4 gigabyte limit und basis 0 in die jeweiligen Segmentregister geladen und in den Protected Mode geschaltet
3. Danach wird nach 0x08:0x10000 gesprungen.

Das letzte mal als ich ihn getestet habe (die Datei ist vom November 2003), hat er noch funktioniert und meinen Kernel schön in den RAM geladen.

Wie gesagt ich lasse von dem Code die Finger. Du darfst sehen, wie du damit zurecht kommst. Vermutlich musst du den gesamten Protected Mode Kram löschen und auf das FAT12 Zeug kannst du wohl auch verzichten. (Achtung: Wenn du das löschst musst du in readsector das mit [sc_b4_prt] und so weiter anpassen! Die %defines sind Aliase für die FAT12-Header Einträge. Am besten du nimmst einfach feste Werte.)

; The following %define directives declare the parts of the FAT12 "DOS BOOT
; RECORD" that are used by this code, based on BP being set to 7C00.
;
%define sc_p_clu bp+0Dh ;byte  Sectors per cluster
%define sc_b4_fat bp+0Eh ;word  Sectors (in partition) before FAT
%define fats bp+10h ;byte  Number of FATs
%define dir_ent bp+11h ;word  Number of root directory entries
%define sc_p_fat bp+16h ;word  Sectors per FAT
%define sc_p_trk bp+18h ;word  Sectors per track
%define heads bp+1Ah ;word  Number of heads
%define sc_b4_prt bp+1Ch ;dword Sectors before partition
%define drive bp+24h ;byte  Drive number


org 0x7C00
[BITS 16]

jmp start


OSEOMName DB 'IncOS   ' ; System Name
BytesPerSector DW 512 ; Bytes pro Sektor
SectorsPerCluster DB 1 ; Sektoren pro Cluster
ReservedSectors DW 1 ; Dieser Sektor
FATTables DB 2 ; Anzahl der FAT Tabellen
RootEntries DW 224 ; Einträge im Hauptverzeichniss
CountSectors DW 2880 ; Anzahl der Sektoren auf der Disk
DiskMediaType DB 240 ; Diskettentyp (1,44 MB)
FATTableSize DW 9 ; Anzahl der Sektoren pro FAT
SectorsPerTrack DW 18 ; Anzahl der Sektoren pro Spur
DriveHeads DW 2 ; Anzahl der Köpfe
HiddenSectors DD 0 ; Versteckte Sektoren
LGSectors DD 0 ; ?
DriveNumber DB 0 ; Laufwerk A:
NTDrtyFlg DB 0 ; ?
ExBPSign DB 29h ; ?
SerialNumber DD 0 ; Seriennummer
DiskLabel DB 'IncOS      ' ; Datenträgerbezeichnung
FileSystem DB 'FAT12   ' ; Dateisystem

SIZEOFKERNEL equ 0
KERNELSEG equ 0x1000

start:
cli
xor ax, ax
mov ds, ax
mov ss, ax
mov sp, 0x7C00
mov bp, sp
mov [drive], dl ;Drive number

mov si, msg_loading
call print

call printdot

call load_kernel

call printdot

call kill_motor

call printdot

mov ax, cs
mov ds, ax
lgdt [gdt_ptr]

call printdot

mov eax, cr0
or al, 1
mov cr0, eax

mov ax, sys_data_sel
mov ds, ax
mov es, ax
mov ss, ax
mov esp, 0x1000

jmp dword sys_code_sel:0x10000

hang:
jmp hang

kill_motor:
push dx
mov dx, 0x3f2
xor al, al
out dx, al
pop dx
ret

gdt:
; null descriptor
dd 0, 0

sys_code_sel equ $-gdt
; code descriptor
dw 0FFFFh ; maximum limit 0FFFFFh (1 meg or 4 gig)
dw 0 ; linear base address
db 0
db 9Ah ; present,ring 0,code,non-conforming,readable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0

sys_data_sel equ $-gdt
; data descriptor
dw 0FFFFh ; maximum limit 0FFFFFh (1 meg or 4 gig)
dw 0 ; linear base address
db 0
db 92h ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0
gdt_end:

gdt_ptr:
dw gdt_end - gdt - 1 ; GDT limit
dd gdt ; linear address of GDT; gets patched aboves


load_kernel:
mov dx, 0
mov ax, 1
mov si, 50
mov di, KERNELSEG / 32

call readsector

ret



readsector:
;
; Input:
;    dx:ax = sector within partition
;    si    = sector count
;    di    = destination segment / 32
;
; The sector number is converted from a partition-relative to a whole-disk
; (LBN) value, and then converted to CHS form, and then the sectors are read
; into (di*32):0.
;
; Output:
;    dx:ax  updated (sector count added)
;    di     updated (sector count added)
;    si = 0
;    bp, ds preserved
;    bx, cx, es modified

.1:
push dx ;(high) relative sector
push ax ;(low) relative sector

add ax, [sc_b4_prt] ;Convert to LBN
adc dx, [sc_b4_prt+2]

mov bx, [sc_p_trk] ;Sectors per track
div bx ;AX = track ;DX = sector-1
sub bx, dx ;Sectors remaining, this track
cmp bx, si ;More than we want?
jbe .2 ;No
mov bx, si ;Yes: Transfer just what we want
.2:
inc dx ;Sector number
mov cx, dx ;CL = sector ;CH = 0
cwd ;(This supports up to 32767 tracks
div word [heads] ;Track number / Number of heads
mov dh, dl ;DH = head

xchg ch, al ;CH = (low) cylinder  ;AL=0
ror ah, 1 ;rotate (high) cylinder
ror ah, 1
add cl, ah ;CL = combine: sector, (high) cylinder

sub ax, di
and ax, byte 0x7F ;AX = sectors to next 64Kb boundary
jz .3 ;On a 64Kb boundary already
cmp ax, bx ;More than we want?
jbe .4 ;No
.3:
xchg ax, bx ;Yes: Transfer just what we want
.4:
push ax ;Save length
mov bx, di ;Compute destination seg
push cx
mov cl, 5
shl bx, cl
pop cx
mov es, bx
xor bx, bx ;ES:BX = address
mov dl, [drive] ;DL = Drive number
mov ah, 2 ;AH = Read command


int 13h ;Do it
jc error
pop bx ;Length
pop ax ;(low) relative sector
pop dx ;(high) relative sector
add ax, bx ;Update relative sector
adc dl, dh
add di, bx ;Update destination
sub si, bx ;Update count
jnz .1 ;Read some more

ret


error:
mov si, msg_error
call print

xor ax, ax
int 0x16

jmp hang

;       print
;       gibt einen ASCIIZ-String aus
;       in:     ds:si -> string
;       out:    -
print:
mov ah, 0x0e
cld
print_do:
lodsb
cmp al, 0
jz print_done
int 0x10
jmp print_do
print_done:
ret

printdot:

mov ah, 0x0e
mov al, '.'
int 0x10

ret


msg_loading db 'Loading IncOS.', 0
msg_error db 'ERROR! Press any key to reboot!', 13, 10, 0

Kernelseg db KERNELSEG


times 0x1FE+$$-$ db 0

db 0x55, 0xAA


Sehr geil der Code. Ich rege mich ja immer auf über Leute, die ihre Bootloader mit Print-Funktionen pflastern. Dabei war ich gar nicht besser ;)
Dieser Text wird unter jedem Beitrag angezeigt.

 

Einloggen