024
06.03.2007, 19:42 Uhr
~mathi
Gast
|
kann man eigentlich beim nachfolgenden Code(mein Bootloader) einen Teil kopieren,der den den Kernel ladet und statt "KERNEL BIN" "test txt" einsetzten
struc BB ;FAT Boot block resb 0xD ;Things we ignore BB_clu resb 1 ;Sectors per cluster BB_res resw 1 ;Reserved sectors BB_fats resb 1 ;Number of FATs BB_root resw 1 ;Root directory entries resb 3 ;Things we ignore BB_fat resw 1 ;Sectors per fat BB_sec resw 1 ;Sectors per track BB_head resw 1 ;Heads endstruc
SEGMENT START USE16
;> cs = 0 ;>> dl = drive we were booted from
boot: jmp short start ;Standard start of boot sector nop resb 0x3B ;Skip over parameters (set by format)
start: cli ;{0} lgdt [cs:gdt] ;Load GDT mov ecx, CR0 ;Switch to protected mode inc cx mov CR0, ecx ;{5} .5: in al, 0x64 ;Enable A20 {4A} test al, 2 jnz .5 mov al, 0xD1 out 0x64, al .6: in al, 0x64 and ax, byte 2 jnz .6 mov al, 0xDF out 0x60, al
;> ah = 0 ;> dl = drive we were booted from
mov al, flat_data ;Selector for 4Gb data seg mov ds, ax ;{2} Extend limit for ds mov es, ax ;Extend limit for es dec cx ;Switch back to real mode mov CR0, ecx ;{5}
mov [boot], dl ;Save drive number we came from mov sp, 0x800 ;{1B}
xor eax, eax ;Segment mov ds, ax ; mov ss, ax mov es, sp ;Read directory at 800:0 {1C}
;> eax = 00000000
mov al, [boot+BB_fats] ;Number of FATs mul byte [boot+BB_fat] ;Times size of FAT add ax, [boot+BB_res] ;Plus Sectors before first FAT ;eax = LBN of Root directory movzx edi,word [boot+BB_root] ;Root directory entries push di ; used again later dec di ;Convert to number of sectors shr di, 4 ; 16 directory entries per sector inc di call read_sectors
;> eax = LBN of root directory ;> edi = length of root directory in sectors ;> [sp] = length of root directory in entries ;> esi = 00000000
lea ebp, [eax+edi] ;ebp = LBN of cluster 2
pop bx ;Root directory entries xor di, di ;Point at directory {1C} .20: mov si, file_name ;Name of file we want xor ecx, ecx mov cl, 11 a32 rep cmpsb ;Found the file? je found ;Yes add cl, 21 ;Offset to next directory entry add edi, ecx ;Advance to next entry dec bx ;Loop through all entries jnz .20
;Couldn't find file in directory boot_error: disk_error: mov ax, 0xE07 ;{3} int 10h jmp short $
;>> ecx = 00000000 ;> es = 800 ;> es:edi = Directory entry of file ;> ebp = LBN of cluster 2 ;> eax = 0000????
found: push word [es:edi+0xF] ;Starting cluster of file mov di, [boot+BB_fat] ;Size of FAT (in sectors) mov ax, [boot+BB_res] ;LBN of FAT call read_sectors
mov bx, 0x4000 mov es, bx ;es = 0x4000 mov edi, 0x100000-0x40000 ;{1D}{4B} One megabyte minus ES base .10:
;>> ecx = 0000???? ;> [sp] = Next cluster of file ;> esi = 0000???? ;>> edx = 0000???? ;> es:edi = Destination address ;> ebp = LBN of cluster 2 ;> ds = 0
xor eax, eax pop si ;Next cluster of file mov bx, si cmp si, 0xFF8 ;Valid cluster? jae eof ;No: assume end of file ;Yes: (c-bit set) rcr bx, 1 ;bx = 0x8000 + cluster/2 mov bx, [bx+si] ;Get word containing FAT entry jnc .11 ;Entry is low 12 bits shr bx, 4 ;Entry was high 12 bits .11: and bh, 0xF ;Mask to just 12 bits push bx ;Save cluster after next push di ;Save destination address {7} mov al, [boot+BB_clu] ;Size of each cluster mov di, ax ; (in sectors) dec si dec si mul esi ;Times cluster number minus 2 add eax, ebp ;Plus LBN of cluster 2 call read_sectors ;Read that cluster
;> ecx = 0000???? ;>> edx = 0000???? ;> di = Clustersize in sectors ;> esi = 0 ;>> ebp = LBN of cluster 2 ;> [sp] = Bottom 16-bits of destination address {7} ;>> [sp+2] = Following cluster ;> ds = 0 ;> es = 4000
mov cx, di ;Cluster size in sectors xchg ch, cl ;Cluster size in words pop di ;Restore destination address {7} es a32 rep movsw jmp short .10 ;Loop until end of file
;> eax = 0 ;> edx = 0000???? ;> bx = 0FF?
eof: mov dx, 0x9C00 mov es, dx ;es = 9C00 xor di, di ;{1E} Address of page tables WRT es mov dh, 4096/256 ;edx = 4096 .10: mov cx, 1024 mov al, 7 .20: stosd add eax, edx int 8 ;{8} loop .20 shr eax, 2 ;{4C} (first time only) 4Mb / 4 = 1Mb neg bl ;Done just one page? jns .10 ;Yes: do one more
cli ;{6}
mov eax, 0x9C007 ;First page tbl pointer in page dir stosd ;{1H} mov ax, (1024-3)*2 xchg ax, cx rep stosw mov ax, 0xD007 ;0FF800000 page tbl pointer stosd ;{1F} mov ah, 0xE0 ;Page directory self pointer stosd ;{1G} mov al, 0 mov CR3, eax ;Set up page directory mov eax, CR0 ;Turn on paging and protected mode or eax, 0x80000001 mov CR0, eax mov cl, flat_data ;Setup ds and es push cx ;{5} pop ds mov es, cx jmp dword 8:0xFF800000 ;Go read_sectors: ; Input: ; EAX = LBN ; DI = sector count ; ES = segment ; Output: ; EBX high half cleared ; DL = drive # ; EDX high half cleared ; ESI = 0 ; Clobbered: ; BX, CX, DH
push eax push di push es
.10: push eax ;LBN
cdq ;edx = 0 movzx ebx, byte [boot+BB_sec] div ebx ;EAX=track ;EDX=sector-1 mov cx, dx ;CL=sector-1 ;CH=0 sub bl, dl ;BX = max transfer before end of track cmp di, bx ;Do we want more than that? ja .20 ;Yes, do just this much now mov bx, di ;No, do it all now .20: mov esi, ebx ;Save count for this transfer.
inc cx ;CL=Sector number xor dx, dx mov bl, [boot+BB_head] div ebx ;EAX=cylinder ;EDX=head
mov dh, dl ;Head mov dl, [boot] ;Drive xchg ch, al ;CH=Low 8 bits of cylinder number; AL=0 shr ax, 2 ;AL[6:7]=High two bits of cylinder or cl, al ;CX = Cylinder and sector
mov ax, si ;Sector count mov ah, 2 ;Read xor bx, bx push ax int 13h pop ax jnc .30
int 13h ;If at second you don't succeed, give up jc near disk_error
.30: pop eax add eax, esi ;Advance LBN
push si shl si, 5 mov bx, es add bx, si ;Advance segment mov es, bx pop si
sub di, si ja .10
pop es pop di pop eax xor si, si ret
file_name db 'KERNEL BIN'
gdt start_gdt ;{9}
flat_code desc 0, 0xFFBFF, D_CODE+D_READ+D_BIG+D_BIG_LIM
flat_data desc 0, 0xFFFFF, D_DATA+D_WRITE+D_BIG+D_BIG_LIM |