Well, after hours and hours of hard programming I have finished my Stage_1 bootloader. Thanks for all the advices and help.
Code: Select all
; Developed by Khronos
[bits 16] ; Real mode
[ORG 0] ; Origin address
jmp short start ; 2 bytes
nop ; No Operation (1 byte)
OEMLabel: db "KERNEL " ; 8 characters padded with spaces
BytesPerSector: dw 512 ; Bytes per sector
SectorsPerCluster: db 1 ; Sectors per cluster
ReservedSectors: dw 1 ; Reserved Sectors (for sector 0)
NumberOfFATs: db 2 ; Number of FAT´s
MaxRootEntries: dw 224 ; Number of Root Entries
NumberOfSectors: dw 2880 ; Number of sectors
DeviceDescriptor: db 0xF0 ; Device Descriptor 0xF0 => 1.44 MB floppy image
SectorsPerFAT: dw 9 ; Sectors Per FAT
SectorsPerTrack: dw 18 ; Sectors Per Track
Sides: dw 2 ; Sides of disk
HiddenSectors: dd 0 ; Number of Hidden Sectors
LengthOfSectors: dd 0 ; Length of sectors
DriveNo: db 0 ; Drive Number (0 or 1)
Flags: db 0 ; Additional flags
Signature: db 0x14 ; Signature, some number of 1 byte
VolumeID: dd 0xAABBCCDD ; Volume ID
VolumeLabel: db "DISCO TANIS " ; 11 characters padded with spaces
FileSystem: db "FAT12 " ; 8 characters padded with spaces
start:
jmp 07C0h:stage_1 ; CS = 07C0h
;*******************************************************************
;* STAGE 1
;*******************************************************************
stage_1:
mov ax, cs
mov es, ax ; ES = 07C0h
mov ds, ax ; DS = 07C0h
mov si, BootMsg
call print_string ; Print Boot Message
xor ah, ah ; Ah = 0, reset function
xor dl, dl ; DL = 0, Drive number 0
int 13h ; Reset Floppy Disk
jnc short read_root_directory ; If no errors, jump read_root_directory
jmp reboot ; else, reboot!
; Root Directory starts at LBA 19 with
; 15 sectors of size
read_root_directory:
mov ax, 1000h
mov es, ax ; ES = 1000h
;Vamos a leer el sector número 1
mov ax, 19 ; 19 = Root Directory
call lba2chs ; LBA to CHS
mov ah, 02h ; Read function
mov al, 0Fh ; Sectors to read
xor bx, bx ; ES:BX = 1000h:0000
xor dl, dl ; DL = 0, Drive 0
int 13h ;Read!
jnc short find_file ; If no errors, jump find_file
jmp reboot ; else, reboot!
find_file:
mov ax, 1000h
mov ds, ax ; DS = 1000h
mov bx, 4640 ; bx = (0Fh * 512) + 32
mov cx, -32
.loop:
mov dl, 1 ; DL = FALSE
sub bx, 32 ; BX - 32
or bx, bx
jz .endloop ; If BX = 0 then, jump .endloop
add cx, 32 ; CX += 32
mov si, cx
lodsb ; mov al, [SI]; inc si
cmp al, 'S'
jne short .loop
lodsb
cmp al, 'T'
jne short .loop
lodsb
cmp al, 'A'
jne short .loop
lodsb
cmp al, 'G'
jne short .loop
lodsb
cmp al, 'E'
jne short .loop
lodsb
cmp al, '_'
jne short .loop
lodsb
cmp al, '2'
jne short .loop
lodsb
cmp al, ' '
jne short .loop
lodsb
cmp al, 'B'
jne short .loop
lodsb
cmp al, 'I'
jne short .loop
lodsb
cmp al, 'N'
jne short .loop
xor dl, dl ; DL = TRUE
add si, 0Fh ; SI current Pos + 15
mov cx, [si] ; Get the Starting Cluster
.endloop:
or dl, dl
jz short read_fat ; If DL = TRUE then, jump read_fat
jmp reboot ; else, reboot!
read_fat:
; We will overwrite the Root Directory with the FAT
mov ax, 1000h
mov es, ax ; ES = 1000h
mov ax, 1 ; LBA = 1
push cx ; We save the Starting Cluster
call lba2chs
mov ah, 02h ; Function 02h: Read
mov al, 9 ; Sectors to read = SectorsPerFAT
xor dl, dl ; Drive = 0
xor bx, bx ; 1000h:0000
int 13h
jnc short read_data ; if no errors, then jump read_data
jmp reboot ; else, reboot!
read_data:
; FAT cluster 0 = media descriptor = 0F0h
; FAT cluster 1 = file cluster = 0FFh
; Cluster start = ((cluster number) - 2) * SectorsPerCluster + (start of user)
; = (cluster number) + 31
pop cx ; Restore the Starting Cluster
xor bx, bx ; BX = 0
push bx ; Push!
mov bx, 3000h
mov es, bx ; ES:BX = 3000h:0000
; Segment where we will load the stage_2
.loop:
mov si, 0000h ; SI Pointer to 1000h:0000
mov ax, cx ; AX = CX
mov bx, 2 ; BX = 2
div bl ; AH = AX MOD BL
or ah, ah
jz short .par ; If remainder = 0 then, jump .par
.impar: ; d = (n - 1 / 2) * 3 + 1
mov ax, cx ; AX = CX
dec ax
shr ax, 1
mov bx, 3 ; BX = 3
mul bx ; AX * 3
inc ax
add si, ax ; SI + AX
mov dx, [si] ; We get the 16 bits of FAT, but we only need 12 bits
shr dx, 4 ; DX >> 4
jmp short .next
.par: ; d = (n / 2) * 3
mov ax, cx ; AX = CX
shr ax, 1
mov bx, 3 ; BX = 3
mul bx ; AX * 3
add si, ax ; SI + AX
mov dx, [si] ; We get the 16 bits of FAT, but we only need 12 bits
and dx, 0x0FFF ; DX AND 0FFFh
.next:
mov ax, 31 ; AX = 31
add ax, cx ; AX = AX + CX (Starting or next cluster)
pop bx ; Restore BX
push dx ; Save next cluster
call lba2chs
mov ah, 02h ; Read function
mov al, 1 ; 1 sector to read
xor dl, dl ; Drive = 0
int 13h
pop dx ; Restore next cluster
cmp dx, 0x0FF8 ; Compare Next Cluster with 0x0FF8
jae short execute ; if dx >= 0x0FFF8 then, jump execute
add bx, 512 ; BX = BX + 512
push bx ; Save BX
mov cx, dx
jmp short .loop
execute:
jmp 3000h:0000
;**********************************************************;
; Print a string in screen
; SI => String pointer with NULL terminator
;**********************************************************;
print_string:
pusha
mov ah, 0Eh
.loop:
mov al, [si]
or al, al
jz short .end_loop
int 10h
inc si
jmp short .loop
.end_loop:
mov al, 13
int 10h
mov al, 10
int 10h
popa
ret
;**********************************************************;
; Convert LBA address to CHS address
; AX => LBA address
;
; CH <= Cylinder
; DH <= Head
; CL <= Sector
;**********************************************************;
lba2chs:
push bx ; Push bx
mov bx, ax ; Copy LBA in BX
;AX has the LBA value
mov dl, 18 ; BL = Sectors Per Track
div dl
xchg ax, bx
;BL = Temp = LBA / (Sectors Per Track)
;BH = LBA % (Sectors Per Track)
mov cl, bh
inc cl ; CL = Sector = [LBA % (Sectors Per Track)] + 1
xor ax, ax ; AX = 0
mov al, bl ; AL = Temp = LBA / (Sectors Per Track)
mov dx, 2
div dl
;AL = LBA / (Number of Heads)
;AH = LBA % (Number of Heads)
mov dh, ah ; Head
mov ch, al ; Cylinder
pop bx
ret
;**********************************************************;
; Print a error message, then wait for a keypress and reboot
;**********************************************************;
reboot:
mov ax, 07C0h
mov ds, ax ; DS = 07C0h
mov si, Error
call print_string
mov si, Reboot
call print_string
mov ax, 0
int 16h ; Wait for keystroke
mov ax, 0
int 19h ; Reboot the system
;**********************************************************;
; Variables
;**********************************************************;
BootMsg: db "Loading...", 0
Error: db "Missing or corrupt STAGE_2.BIN!", 0
Reboot: db "Press any key to reboot...", 0
;**********************************************************;
; EOF
;**********************************************************;
times 510-($-$$) db 0 ; Fill with zero´s
dw 0xAA55 ; Bootloader signature
Now, I will be activate large mode and begin the C kernel.
Please post the errors of my code or other advices. Thanks.