Code: Select all
[BITS 16]
? equ 0
ImageLoadSeg equ 60h
[SECTION .text]
[ORG 0]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Boot sector starts here ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
jmp short start
nop
bsOemName DB "EIGHTCHR" ; 0x03
;;;;;;;;;;;;;;;;;;;;;
;; BPB starts here ;;
;;;;;;;;;;;;;;;;;;;;;
bpbBytesPerSector DW ? ; 0x0B
bpbSectorsPerCluster DB ? ; 0x0D
bpbReservedSectors DW ? ; 0x0E
bpbNumberOfFATs DB ? ; 0x10
bpbRootEntries DW ? ; 0x11
bpbTotalSectors DW ? ; 0x13
bpbMedia DB ? ; 0x15
bpbSectorsPerFAT DW ? ; 0x16
bpbSectorsPerTrack DW ? ; 0x18
bpbHeadsPerCylinder DW ? ; 0x1A
bpbHiddenSectors DD ? ; 0x1C
bpbTotalSectorsBig DD ? ; 0x20
;;;;;;;;;;;;;;;;;;;
;; BPB ends here ;;
;;;;;;;;;;;;;;;;;;;
bsDriveNumber DB ? ; 0x24
bsUnused DB ? ; 0x25
bsExtBootSignature DB ? ; 0x26
bsSerialNumber DD ? ; 0x27
bsVolumeLabel DB "NO NAME " ; 0x2B
bsFileSystem DB "FAT12 " ; 0x36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Boot sector code starts here ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
cld
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; How much RAM is there? ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
int 12h ; get conventional memory size (in KBs)
shl ax, 6 ; and convert it to paragraphs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reserve some memory for the boot sector and the stack ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub ax, 512 / 16 ; reserve 512 bytes for the boot sector code
mov es, ax ; es:0 -> top - 512
sub ax, 2048 / 16 ; reserve 2048 bytes for the stack
mov ss, ax ; ss:0 -> top - 512 - 2048
mov sp, 2048 ; 2048 bytes for the stack
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Copy ourself to top of memory ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov cx, 256
mov si, 7C00h
xor di, di
mov ds, di
rep movsw
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Jump to relocated code ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push es
push word main
retf
main:
push cs
pop ds
mov [bsDriveNumber], dl ; store boot drive number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reserve some memory for a FAT12 image (6KB max) and load it whole ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax, [bpbBytesPerSector]
shr ax, 4 ; ax = sector size in paragraphs
mov cx, [bpbSectorsPerFAT] ; cx = FAT size in sectors
mul cx ; ax = FAT size in paragraphs
mov di, ss
sub di, ax
mov es, di
xor bx, bx ; es:bx -> buffer for the FAT
mov ax, [bpbHiddenSectors]
mov dx, [bpbHiddenSectors+2]
add ax, [bpbReservedSectors]
adc dx, bx ; dx:ax = LBA
call ReadSector
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reserve some memory for a root directory and load it whole ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov bx, ax
mov di, dx ; save LBA to di:bx
mov ax, 32
mov si, [bpbRootEntries]
mul si
div word [bpbBytesPerSector]
mov cx, ax ; cx = root directory size in sectors
mov al, [bpbNumberOfFATs]
cbw
mul word [bpbSectorsPerFAT]
add ax, bx
adc dx, di ; dx:ax = LBA
push es ; push FAT segment (2nd parameter)
push word ImageLoadSeg
pop es
xor bx, bx ; es:bx -> buffer for root directory
call ReadSector
add ax, cx
adc dx, bx ; adjust LBA for cluster data
push dx
push ax ; push LBA for data (1st parameter)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Look for a COM/EXE program to be load and run ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov di, bx ; es:di -> root entries array
mov dx, si ; dx = number of root entries
mov si, ProgramName ; ds:si -> program name
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Looks for a file with particular name ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Input: DS:SI -> file name (11 chars) ;;
;; ES:DI -> root directory array ;;
;; DX = number of root entries ;;
;; Output: SI = cluster number ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FindName:
mov cx, 11
FindNameCycle:
mov si,dots ; Store our String
lodsb
mov ah, 0Eh
mov bx, 7
int 10h
cmp byte [es:di], ch
je FindNameFailed ; end of root directory
pusha
repe cmpsb
popa
je FindNameFound
add di, 32
dec dx
jnz FindNameCycle ; next root entry
FindNameFailed:
jmp ErrFind
FindNameFound:
jmp Found
mov si, [es:di+1Ah] ; si = cluster no.
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load entire a program ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
ReadNextCluster:
call ReadCluster
cmp si, 0FF8h
jc ReadNextCluster ; if not End Of File
;;;;;;;;;;;;;;;;;;;
;; Type checking ;;
;;;;;;;;;;;;;;;;;;;
;cli ; for stack adjustments
;mov ax, ImageLoadSeg
;mov es, ax
;cmp word [es:0], 5A4Dh ; "MZ" signature?
;je RelocateEXE ; yes, it's an EXE program
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Setup and Run COM program ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax, es
sub ax, 10h ; "org 100h" stuff :)
mov es, ax
mov ds, ax
mov ss, ax
xor sp, sp
push es
push word 1000h
jmp Run
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Relocate, setup and run EXE program ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RelocateEXE:
mov ds, ax
add ax, [ds:08h] ; ax = image base
mov cx, [ds:06h] ; cx = reloc items
mov bx, [ds:18h] ; bx = reloc table pointer
jcxz RelocationDone
ReloCycle:
mov di, [ds:bx] ; di = item ofs
mov dx, [ds:bx+2] ; dx = item seg (rel)
add dx, ax ; dx = item seg (abs)
push ds
mov ds, dx ; ds = dx
add [ds:di], ax ; fixup
pop ds
add bx, 4 ; point to next entry
loop ReloCycle
RelocationDone:
mov bx, ax
add bx, [ds:0Eh]
mov ss, bx ; ss for EXE
mov sp, [ds:10h] ; sp for EXE
add ax, [ds:16h] ; cs
push ax
push word [ds:14h] ; ip
Run:
mov dl, [cs:bsDriveNumber] ; let program know boot drive
sti
retf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reads a FAT12 cluster ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Inout: ES:BX -> buffer ;;
;; SI = cluster no ;;
;; Output: SI = next cluster ;;
;; ES:BX -> next addr ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ReadCluster:
mov bp, sp
lea ax, [si-2]
xor ch, ch
mov cl, [bpbSectorsPerCluster]
; cx = sector count
mul cx
add ax, [ss:bp+1*2]
adc dx, [ss:bp+2*2]
; dx:ax = LBA
call ReadSector
mov ax, [bpbBytesPerSector]
shr ax, 4 ; ax = paragraphs per sector
mul cx ; ax = paragraphs read
mov cx, es
add cx, ax
mov es, cx ; es:bx updated
mov ax, 3
mul si
shr ax, 1
xchg ax, si ; si = cluster * 3 / 2
push ds
mov ds, [ss:bp+3*2] ; ds = FAT segment
mov si, [ds:si] ; si = next cluster
pop ds
jnc ReadClusterEven
shr si, 4
ReadClusterEven:
and si, 0FFFh ; mask cluster value
ReadClusterDone:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Reads a sector using BIOS Int 13h fn 2 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Input: DX:AX = LBA ;;
;; CX = sector count ;;
;; ES:BX -> buffer address ;;
;; Output: CF = 1 if error ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ReadSector:
pusha
ReadSectorNext:
mov di, 5 ; attempts to read
ReadSectorRetry:
pusha
div word [bpbSectorsPerTrack]
; ax = LBA / SPT
; dx = LBA % SPT = sector - 1
mov cx, dx
inc cx
; cx = sector no.
xor dx, dx
div word [bpbHeadsPerCylinder]
; ax = (LBA / SPT) / HPC = cylinder
; dx = (LBA / SPT) % HPC = head
mov ch, al
; ch = LSB 0...7 of cylinder no.
shl ah, 6
or cl, ah
; cl = MSB 8...9 of cylinder no. + sector no.
mov dh, dl
; dh = head no.
mov dl, [bsDriveNumber]
; dl = drive no.
mov ax, 201h
; al = sector count
; ah = 2 = read function no.
int 13h ; read sectors
jnc ReadSectorDone ; CF = 0 if no error
xor ah, ah ; ah = 0 = reset function
int 13h ; reset drive
popa
dec di
jnz ReadSectorRetry ; extra attempt
jmp short ErrRead
ReadSectorDone:
popa
dec cx
jz ReadSectorDone2 ; last sector
add bx, [bpbBytesPerSector] ; adjust offset for next sector
add ax, 1
adc dx, 0 ; adjust LBA for next sector
jmp short ReadSectorNext
ReadSectorDone2:
popa
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Error Messaging Code ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
ErrRead:
mov si, MsgErrRead
jmp Print
ErrFind:
mov si, MsgErrFind
jmp Print
Found:
mov si, MsgFound
Print:
mov ah, 0Eh
mov bx, 7
lodsb
int 10h
jmp $ ; hang
;;;;;;;;;;;;;;;;;;;;;;
;; String constants ;;
;;;;;;;;;;;;;;;;;;;;;;
dots db ".",0
MsgErrRead db "X",13,10,0
MsgErrFind db "N",13,10,0
MsgFound db "Y",13,10,0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Fill free space with zeroes ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
times 510-($-$$) db 0 ; Fill up the file with zeros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Name of a program to be load and run ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ProgramName db "KERNEL BIN" ; name and extension must be padded
; with spaces (11 bytes total)
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; End of the sector ID ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
dw 0AA55h
I changed it only a bit and verified that it still finds the com (ASM) BIN but it still does not find mine (C) BIN. Perhaps it is with my linking, here is my code:...N
Code: Select all
c:\djgpp\bin\gcc -ffreestanding -c main.c -o main.o
c:\djgpp\bin\gcc -c video.c -o video.o
c:\djgpp\bin\gcc -c ports.c -o ports.o
c:\djgpp\bin\gcc -c gdt.c -o gdt.o
c:\djgpp\bin\gcc -c idt.c -o idt.o
c:\djgpp\bin\gcc -c irq.c -o irq.o
c:\djgpp\bin\gcc -c isrs.c -o isrs.o
c:\djgpp\bin\gcc -c timer.c -o timer.o
c:\djgpp\bin\gcc -c kb.c -o kb.o
c:\djgpp\bin\ld -e _main -Ttext 0x1000 -o kernel.o main.o hal.o video.o ports.o gdt.o idt.o irq.o isrs.o timer.o kb.o
c:\djgpp\bin\ld -i -e _main -Ttext 0x1000 -o kernel.o main.o hal.o video.o ports.o gdt.o idt.o irq.o isrs.o timer.o kb.o
c:\djgpp\bin\objcopy -R .note -R .comment -S -O binary kernel.o kernel.bin
c:\djgpp\bin\makeboot a.img x86boot.bin kernel.bin