Page 1 of 2

Bootloader

Posted: Tue Nov 17, 2009 7:11 pm
by ChrisSkura
i'VE BEEN WRITING MY OWN BOOTLOADER FROM A TUTORIAL I saw and when I compile it it doesn't load the kernel but I don't know why.

this is stage 1:

Code: Select all


;*********************************************
;	Boot1.asm
;		- A Simple Bootloader
;
;	Operating Systems Development Series
;*********************************************

bits	16						; we are in 16 bit real mode

org	0						; we will set regisers later

start:	jmp	main					; jump to start of bootloader

;*********************************************
;	BIOS Parameter Block
;*********************************************

; BPB Begins 3 bytes from start. We do a far jump, which is 3 bytes in size.
; If you use a short jump, add a "nop" after it to offset the 3rd byte.

bpbOEM			db "My OS   "			; OEM identifier (Cannot exceed 8 bytes!)
bpbBytesPerSector:  	DW 512
bpbSectorsPerCluster: 	DB 1
bpbReservedSectors: 	DW 1
bpbNumberOfFATs: 	DB 2
bpbRootEntries: 	DW 224
bpbTotalSectors: 	DW 2880
bpbMedia: 		DB 0xf8  ;; 0xF1
bpbSectorsPerFAT: 	DW 9
bpbSectorsPerTrack: 	DW 18
bpbHeadsPerCylinder: 	DW 2
bpbHiddenSectors: 	DD 0
bpbTotalSectorsBig:     DD 0
bsDriveNumber: 	        DB 0
bsUnused: 		DB 0
bsExtBootSignature: 	DB 0x29
bsSerialNumber:	        DD 0xa0a1a2a3
bsVolumeLabel: 	        DB "MOS FLOPPY "
bsFileSystem: 	        DB "FAT12   "

;************************************************;
;	Prints a string
;	DS=>SI: 0 terminated string
;************************************************;
Print:
			lodsb				; load next byte from string from SI to AL
			or	al, al			; Does AL=0?
			jz	PrintDone		; Yep, null terminator found-bail out
			mov	ah, 0eh			; Nope-Print the character
			int	10h
			jmp	Print			; Repeat until null terminator found
	PrintDone:
			ret				; we are done, so return

;************************************************;
; Reads a series of sectors
; CX=>Number of sectors to read
; AX=>Starting sector
; ES:BX=>Buffer to read to
;************************************************;

ReadSectors:
     .MAIN
          mov     di, 0x0005                          ; five retries for error
     .SECTORLOOP
          push    ax
          push    bx
          push    cx
          call    LBACHS                              ; convert starting sector to CHS
          mov     ah, 0x02                            ; BIOS read sector
          mov     al, 0x01                            ; read one sector
          mov     ch, BYTE [absoluteTrack]            ; track
          mov     cl, BYTE [absoluteSector]           ; sector
          mov     dh, BYTE [absoluteHead]             ; head
          mov     dl, BYTE [bsDriveNumber]            ; drive
          int     0x13                                ; invoke BIOS
          jnc     .SUCCESS                            ; test for read error
          xor     ax, ax                              ; BIOS reset disk
          int     0x13                                ; invoke BIOS
          dec     di                                  ; decrement error counter
          pop     cx
          pop     bx
          pop     ax
          jnz     .SECTORLOOP                         ; attempt to read again
          int     0x18
     .SUCCESS
          mov     si, msgProgress
          call    Print
          pop     cx
          pop     bx
          pop     ax
          add     bx, WORD [bpbBytesPerSector]        ; queue next buffer
          inc     ax                                  ; queue next sector
          loop    .MAIN                               ; read next sector
          ret

;************************************************;
; Convert CHS to LBA
; LBA = (cluster - 2) * sectors per cluster
;************************************************;

ClusterLBA:
          sub     ax, 0x0002                          ; zero base cluster number
          xor     cx, cx
          mov     cl, BYTE [bpbSectorsPerCluster]     ; convert byte to word
          mul     cx
          add     ax, WORD [datasector]               ; base data sector
          ret
     
;************************************************;
; Convert LBA to CHS
; AX=>LBA Address to convert
;
; absolute sector = (logical sector / sectors per track) + 1
; absolute head   = (logical sector / sectors per track) MOD number of heads
; absolute track  = logical sector / (sectors per track * number of heads)
;
;************************************************;

LBACHS:
          xor     dx, dx                              ; prepare dx:ax for operation
          div     WORD [bpbSectorsPerTrack]           ; calculate
          inc     dl                                  ; adjust for sector 0
          mov     BYTE [absoluteSector], dl
          xor     dx, dx                              ; prepare dx:ax for operation
          div     WORD [bpbHeadsPerCylinder]          ; calculate
          mov     BYTE [absoluteHead], dl
          mov     BYTE [absoluteTrack], al
          ret

;*********************************************
;	Bootloader Entry Point
;*********************************************

main:

     ;----------------------------------------------------
     ; code located at 0000:7C00, adjust segment registers
     ;----------------------------------------------------
     
          cli						; disable interrupts
          mov     ax, 0x07C0				; setup registers to point to our segment
          mov     ds, ax
          mov     es, ax
          mov     fs, ax
          mov     gs, ax

     ;----------------------------------------------------
     ; create stack
     ;----------------------------------------------------
     
          mov     ax, 0x0000				; set the stack
          mov     ss, ax
          mov     sp, 0xFFFF
          sti						; restore interrupts

     ;----------------------------------------------------
     ; Display loading message
     ;----------------------------------------------------
     
          mov     si, msgLoading
          call    Print
          
     ;----------------------------------------------------
     ; Load root directory table
     ;----------------------------------------------------

     LOAD_ROOT:
     
     ; compute size of root directory and store in "cx"
     
          xor     cx, cx
          xor     dx, dx
          mov     ax, 0x0020                           ; 32 byte directory entry
          mul     WORD [bpbRootEntries]                ; total size of directory
          div     WORD [bpbBytesPerSector]             ; sectors used by directory
          xchg    ax, cx
          
     ; compute location of root directory and store in "ax"
     
          mov     al, BYTE [bpbNumberOfFATs]            ; number of FATs
          mul     WORD [bpbSectorsPerFAT]               ; sectors used by FATs
          add     ax, WORD [bpbReservedSectors]         ; adjust for bootsector
          mov     WORD [datasector], ax                 ; base of root directory
          add     WORD [datasector], cx
          
     ; read root directory into memory (7C00:0200)
     
          mov     bx, 0x0200                            ; copy root dir above bootcode
          call    ReadSectors

     ;----------------------------------------------------
     ; Find stage 2
     ;----------------------------------------------------

     ; browse root directory for binary image
          mov     cx, WORD [bpbRootEntries]             ; load loop counter
          mov     di, 0x0200                            ; locate first root entry
     .LOOP:
          push    cx
          mov     cx, 0x000B                            ; eleven character name
          mov     si, ImageName                         ; image name to find
          push    di
     rep  cmpsb                                         ; test for entry match
          pop     di
          je      LOAD_FAT
          pop     cx
          add     di, 0x0020                            ; queue next directory entry
          loop    .LOOP
          jmp     FAILURE

     ;----------------------------------------------------
     ; Load FAT
     ;----------------------------------------------------

     LOAD_FAT:
     
     ; save starting cluster of boot image
     
          mov     si, msgCRLF
          call    Print
          mov     dx, WORD [di + 0x001A]
          mov     WORD [cluster], dx                  ; file's first cluster
          
     ; compute size of FAT and store in "cx"
     
          xor     ax, ax
          mov     al, BYTE [bpbNumberOfFATs]          ; number of FATs
          mul     WORD [bpbSectorsPerFAT]             ; sectors used by FATs
          mov     cx, ax

     ; compute location of FAT and store in "ax"

          mov     ax, WORD [bpbReservedSectors]       ; adjust for bootsector
          
     ; read FAT into memory (7C00:0200)

          mov     bx, 0x0200                          ; copy FAT above bootcode
          call    ReadSectors

     ; read image file into memory (0050:0000)
     
          mov     si, msgCRLF
          call    Print
          mov     ax, 0x0050
          mov     es, ax                              ; destination for image
          mov     bx, 0x0000                          ; destination for image
          push    bx

     ;----------------------------------------------------
     ; Load Stage 2
     ;----------------------------------------------------

     LOAD_IMAGE:
     
          mov     ax, WORD [cluster]                  ; cluster to read
          pop     bx                                  ; buffer to read into
          call    ClusterLBA                          ; convert cluster to LBA
          xor     cx, cx
          mov     cl, BYTE [bpbSectorsPerCluster]     ; sectors to read
          call    ReadSectors
          push    bx
          
     ; compute next cluster
     
          mov     ax, WORD [cluster]                  ; identify current cluster
          mov     cx, ax                              ; copy current cluster
          mov     dx, ax                              ; copy current cluster
          shr     dx, 0x0001                          ; divide by two
          add     cx, dx                              ; sum for (3/2)
          mov     bx, 0x0200                          ; location of FAT in memory
          add     bx, cx                              ; index into FAT
          mov     dx, WORD [bx]                       ; read two bytes from FAT
          test    ax, 0x0001
          jnz     .ODD_CLUSTER
          
     .EVEN_CLUSTER:
     
          and     dx, 0000111111111111b               ; take low twelve bits
         jmp     .DONE
         
     .ODD_CLUSTER:
     
          shr     dx, 0x0004                          ; take high twelve bits
          
     .DONE:
     
          mov     WORD [cluster], dx                  ; store new cluster
          cmp     dx, 0x0FF0                          ; test for end of file
          jb      LOAD_IMAGE
          
     DONE:
     
          mov     si, msgCRLF
          call    Print
          push    WORD 0x0050
          push    WORD 0x0000
          retf
          
     FAILURE:
     
          mov     si, msgFailure
          call    Print
          mov     ah, 0x00
          int     0x16                                ; await keypress
          int     0x19                                ; warm boot computer
     
     absoluteSector db 0x00
     absoluteHead   db 0x00
     absoluteTrack  db 0x00
     
     datasector  dw 0x0000
     cluster     dw 0x0000
     ImageName   db "KERNEL  BIN"
     msgLoading  db 0x0D, 0x0A, "Loading Boot Image ", 0x0D, 0x0A, 0x00
     msgCRLF     db 0x0D, 0x0A, 0x00
     msgProgress db ".", 0x00
     msgFailure  db 0x0D, 0x0A, "ERROR : Press Any Key to Reboot", 0x0A, 0x00
     
          TIMES 510-($-$$) DB 0
          DW 0xAA55


kernel.bin

Code: Select all



;*********************************************
;	Stage2.asm
;		- Second Stage Bootloader
;
;	Operating Systems Development Series
;*********************************************

org 0x0					; offset to 0, we will set segments later

bits 16					; we are still in real mode

; we are loaded at linear address 0x10000

jmp main				; jump to main

;*************************************************;
;	Prints a string
;	DS=>SI: 0 terminated string
;************************************************;

Print:
	lodsb					; load next byte from string from SI to AL
	or			al, al		; Does AL=0?
	jz			PrintDone	; Yep, null terminator found-bail out
	mov			ah,	0eh	; Nope-Print the character
	int			10h
	jmp			Print		; Repeat until null terminator found
PrintDone:
	ret					; we are done, so return

;*************************************************;
;	Second Stage Loader Entry Point
;************************************************;

main:
	cli					; clear interrupts
	push			cs		; Insure DS=CS
	pop			ds

	mov			si, Msg
	call			Print

	cli					; clear interrupts to prevent triple faults
	hlt					; hault the syst

;*************************************************;
;	Data Section
;************************************************;

Msg	db	"Preparing to load operating system...",13,10,0




Re: Bootloader

Posted: Tue Nov 17, 2009 7:18 pm
by NickJohnson
ChrisSkura wrote:i'VE BEEN WRITING MY OWN BOOTLOADER FROM A TUTORIAL ...
Isn't that a bit of an oxymoron?

Seriously though, you should at least attempt to do some debugging so you know which part of that 200-line thing you posted people should look at.

Re: Bootloader

Posted: Tue Nov 17, 2009 7:25 pm
by ChrisSkura
I tried figuring out what was wrong by outputting different strings after certain steps were completed but I couldn't find anything. it just wouldn't load my kernel

Re: Bootloader

Posted: Tue Nov 17, 2009 8:04 pm
by neon
Hello,

Whats the name of your kernel file (exactly) on disk? Is it not finding it, or not loading it? Or, is it loading it, but not executing it? Or, if its executing it, but not working in your "kernel". There are alot more questions that I can ask and are basic troubleshooting skills. Please try to narrow down the problem as much as possible, post your bochs crash log, and let us know the above information.

There is no "does not load the kernel". At most, there will either be an error somewhere (narrow down where its at in the bootloader to the section of code causing it.) or it will load at least a part of your kernel.

Re: Bootloader

Posted: Tue Nov 17, 2009 9:07 pm
by ChrisSkura
my kernel is called kernel.bin and I think it's something in my bootloader because when my kernel loads, it's suppose to output something like:

"loading operating system. . ."

but it doesn't.

Re: Bootloader

Posted: Tue Nov 17, 2009 10:03 pm
by neon
Hello,

I managed to assemble and build the system from your code and it worked fine for me. This makes me believe the problem might be your toolchain and/or how you are building and/or booting your system. Please describe - in detail - how you are building and booting the system.

Re: Bootloader

Posted: Tue Nov 17, 2009 11:11 pm
by djsilence
From what tutorial of BrokenThorn is it? See, you declared absolete-values after code (in BrokenThorn tutorials it is before)... If there is nothing different else, so maybe is it a problem? (I know that it sounds stupid) :D

Re: Bootloader

Posted: Wed Nov 18, 2009 7:09 am
by ChrisSkura
it's from the bootloader tutorial number 4

I assemble the bootloader like this:

Code: Select all

c:\nasm.exe c:\boot.asm -f bin -o a:\boot.bin
and the kernel like this

Code: Select all

c:\nasm.exe c:\kernel.asm -f bin -o a:\kernel.bin
and then I copy them onto my floppy disk and the type in

Code: Select all

debug a:\boot.bin
w 100 0 0 1

Re: Bootloader

Posted: Wed Nov 18, 2009 7:21 am
by Love4Boobies
How about also copying the kernel to the floppy disk?

Re: Bootloader

Posted: Wed Nov 18, 2009 7:34 am
by ChrisSkura
do I also have to type in this?

Code: Select all

debug a:\kernel.bin
w 100 0 0 1

Re: Bootloader

Posted: Wed Nov 18, 2009 7:58 am
by neon
Hello,

Using DEBUG like that copies your file to the 1st sector (bootsector) on disk. You do not need to copy the bootloader file on disk (copy a: bootsect), just write it to the 1st sector. (Although I personally do it in Neptune for a backup under the name bootsect.bak but thats different then what you are doing.)

All other files can be copied over like copy yourfile A:\. For example...

Code: Select all

c:\nasm.exe c:\boot.asm -f bin -o a:\boot.bin

debug a:\boot.bin
w 100 0 0 1

copy kernel.bin A:\
...You can also just copy it via drag-and-drop, copy-and-paste, ctrl+c + ctrl+v, so many possible ways...

Re: Bootloader

Posted: Wed Nov 18, 2009 12:58 pm
by ChrisSkura
I copy it the same way (drag and drop) and I save my bootloader to the first sector but it still doesn't work

Re: Bootloader

Posted: Wed Nov 18, 2009 1:20 pm
by neon
Post bochs log please and any errors you get. Also post your boot disks directory contents - exact filenames please. (This is also a suggestion: Start putting as much details as you can in your posts. I hate seeing posts that read "it doesnt work" because it provides no details whatsoever. Help us help you, else we will not be able to help.)

Re: Bootloader

Posted: Wed Nov 18, 2009 1:57 pm
by ChrisSkura
k, I am not using Bochs because It doesn't find anything on my floppy disk. I test my bootloader off startup and it prints out

Loading Boot image . . . . . . . . . . . . . . . . . . . . . . . . . .

it doesn't load my kernel. it just waits a couple of seconds and then quits and proceeds with loading ms-windows.

Re: Bootloader

Posted: Wed Nov 18, 2009 1:58 pm
by ChrisSkura
the bootloader name is

boot.bin

and the kernel's name is

kernel.bin