Lowlevel
		Lowlevel => Lowlevel-Coding => Thema gestartet von: noob 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!!
			 
			
			- 
				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 ;)