Page 1 of 1

Writting Your own BOOT Sector

Posted: Wed Mar 07, 2007 12:26 pm
by Jim

Code: Select all


;************************************************************************
;*
;*	Description: This is a BOOT sector source Code, for compiling with NASM
;*	How to Compile?: < NASM -f bin BOOT.asm -o BOOT.bin > 
;*  Comments: This Boot sector is compatible with the FAT file system.
;*  How to Get NASM?: Ask Google! (NASM is a free ASM compiler).
;*
;*  Enjoy!!!
;************************************************************************

[BITS 16]	;//Use 16 bit assembler.
;************************************************************************

ORG 7C00h      ;//Because BIOS loads the OS to
                       ;// address 0:7C00h, so ORG 7C00h 
                       ;// makes that the reference to date and code
                       ;// are with the right offset (7c00h).
                       
 
;************************************************************************
                       
                       ;// CS = 0 / IP = 7C00h // SS = ? / SP = ?
                       ;// You are now at address 7c00.
JMP Start              ;//Here we start the, BIOS gave us now the control.
 
 
 
 
;************************************************************************
;* Here goes all the data of the program.
;************************************************************************


;//BIOS Parameter Block

	OSName							db 'SZK-OS..';//8 byte.
	BytesPerSector_BPB				dw 512
	SectorsPerCluster				db 1
	ReservedSectors					dw 1
	NumberOfFATCopies				db 2
	NumberOfPossibleRootEntries		dw 224
	Small_NumberOfSectors			dw 2880 ;//18 * 80 * 2
	MediaDscriptor					db 0F0h ;//Fixed disk 0xF8.
	SectorsPerFAT					dw 9
	SectorsPerTrack_BPB				dw 18
	NumberOfHeads					dw 2
	HiddenSectors					dd 0
	Large_NumberOfSectors			dd 0

;//Extended BIOS Parameter Block

	DriveNumber						db 0	;//0x80 for hard disks
	Reserved						db 0
	ExtendedBootSignature			db 29h ;//Extended boot signature 
										   ;//(0x29). This is a signature 
										   ;// byte that indicates that the 
										   ;// following three fields in the 
										   ;// boot sector are present.
	VolumeSerialNumber				dd 123456h
	VolumeLabel						db '1234567890_'	;//11 byte.
	FileSystemType					db 'FAT12   '		;//8 byte.


;************************************************************************

;//Messages Strings. 
szErrorReadingDrive    db  'Error Reading Drive, Press any Key to reboot...',0
szHelloWorld		   db  'Hello World!...',0


;************************************************************************
nTracksToRead	db 3	;//Read 3 Tracks (1 Track = 512*18 = 9,216 bytes)(Modify this value to how much Tracks you want to 

read).

;************************************************************************

;//For Screen manipulation.
xCursor db 0
yCursor db 0

;************************************************************************

;//
nSide   db 1	;//Start Reading the other side.
nTrack  db 0	;//Track 0
nSector db 16	;//33 sectors are reserved (1 Boot sector + 2 FAT's (9*2) + Directory (14)).
;//for Hard disks - nTrack  dw 0

;************************************************************************
nTrays  db 0

;************************************************************************
;*Pointer to the download area.
pOS                    dw   0h    ;//Points to were to download the Operating System. 

;************************************************************************
;*Disk Paremeter Table.
StepRateAndHeadUnloadTime                     db      0DFh
HeadLoadTimeAndDMAModeFlag                    db      2h
DelayForMotorTurnOff                          db      25h
BytesPerSector                                db      2h    ;// (1 = 256) //(2 = 512 bytes)
SectorsPerTrack                               db      18    ;// 18 sectors in a track.
IntersectorGapLength                          db      1Bh
DataLength                                    db      0FFh
IntersectorGapLengthDuringFormat              db      54h
FormatByteValue                               db      0F6h
HeadSettlingTime                              db      0Fh
DelayUntilMotorAtNormalSpeed                  db      8h
  
;************************************************************************
;// Here the Boot Sector starts.
;************************************************************************
 
 
Start:
		DB 0EAh	;//(0EAh = Op code of Far jmp)				
								;//This is for bugy Bios that loads the OS 
		DW BootSectorContinue	;// to CS:IP = 7C0h:000 but we want that 
		DW 0					;// it would be CS:IP = 0:7C00 
								;// (This points to the same place in the RAM 
								;// the only different is that its CS and IP 
								;// are different).
		
BootSectorContinue:
 
CLI     ;//Clear Interrupt Flag so while setting up the stack any interrupt would not be fired.
 
        MOV AX,50h            ;//lets have the stack start at 500h
        MOV SS,AX             ;//SS:SP = 50h:1000h
        MOV SP,1000h           ;//Lets make the stack 4,096 bytes.

  
        MOV AX,CS              ;//Set the data segment = CS = 0 
        MOV DS,AX
        
        MOV AX,7E0h           ;//Make ES=7E0h . This points to were we would download
        MOV ES,AX             ;// the stage 2 of the OS loader.

        PUSH DL		;//Save the Boot Drive number, for future use
 
 
STI     ;//Set Back the Interrupt Flag after we finished setting a stack frame.
 
		CALL ClearScreen
		
		LEA WORD AX,[szHelloWorld]	;//Print Hello World!
		CALL PrintMessage
		CALL GetKey
                       
        CALL SetNewDisketteParameterTable     ;//SetNewDisketteParameterTable()
        
        
		CALL DownloadOS 
		CALL GetKey           ;//Call GetKey()

        
        CALL GiveControlToOS  ;//Give Control To OS.
        
 
;************************************************************************
;//Prints a message to the screen.
;************************************************************************
PrintMessage:
 
        MOV DI,AX				;//AX holds the address of the string to Display.
        MOV BYTE [xCursor],1	;//Column.
        
ContinuPrinting:
 
        CMP BYTE [DI],0    ;//Did we get to the End of String.
        JE EndPrintingMessage  ;//if you gat to the end of the string return.
        
        MOV AH,2               ;//Move Cursor
        MOV BYTE DH,[yCursor]  ;//row.
        MOV BYTE DL,[xCursor]  ;//column.
        MOV BH,0               ;//page number.
        INT 10h
        INC BYTE [xCursor]
        
        MOV AH,0Ah             ;//Display Character Function.
        MOV AL,[DI]            ;//character to display.
        MOV BH,0               ;//page number.
        MOV CX,1               ;//number of times to write character
        INT 10h
        
        
               
        INC DI					;//Go to next character.
        
        JMP ContinuPrinting		;//go to Print Next Character.
               
EndPrintingMessage:
        
        INC BYTE [yCursor]		;//So Next time the message would be printed in the second line.
        
        CMP BYTE [yCursor],25
        JNE dontMoveCorsurToBegin
        MOV BYTE [yCursor],0
        
dontMoveCorsurToBegin:
        RET
        
               
;************************************************************************
;//Waits for the user to press a key.
;************************************************************************
GetKey:
 
        MOV AH,0
        INT 16h ;//Wait for a key press.
        RET
        
;************************************************************************
;//Gives Control To Second Part Loader.
;************************************************************************
GiveControlToOS:
         
   
		DB 0EAh			;//FAR JMP op code.
		DW 0h 			;//
		DW 7E0h			;//

        
;************************************************************************
;//Set New Disk Parameter Table
;************************************************************************
SetNewDisketteParameterTable:
 
        LEA WORD DX,[StepRateAndHeadUnloadTime]   ;//Get the address of the Disk Parameters Block. 
        
 
        
        
                       ;//Int 1E (that is in address 0:78h)-(1Eh x 4 = 78h).
                       ;// holds the address of the disk parameters 
                       ;// block, so now change it to 
                       ;// our parameter black.
        MOV WORD [0078h],DX			;//DX holds the address of our Parameters block.
        MOV WORD [007Ah],0000		;//Assuming DS = 0.
        
 
        MOV AH,0    ;//Reset Drive To Update the DisketteParameterTable.
        MOV DL,DriveNumber
        INT 13H
        
        
        ret
        
;************************************************************************
;//DownloadOS
;************************************************************************
DownloadOS:
  
         
ContinueDownload:
        
        CMP BYTE [nSector],19		;//Did we get to end of track.
        JNE ContinueReadingDisk
        MOV BYTE [nSector],1		;//And Read Next Sector(Sectors Start with 1 not 0).
		
		CMP BYTE [nSide],0			;//Check which side we are reading.
		JE  ChangeDiskSide			;//If nSide =0 ,Change side.
		MOV BYTE [nSide],0			;//If nSide =1 ,Change back side.
		MOV BYTE AL,[nTracksToRead] ;//Get nTracks to read
        CMP BYTE [nTrack],AL		;//Did we finish reading???
        JE  EndDownloadingOS
                
        INC BYTE [nTrack]			;//If we got to end of track, Move to next track.
		JMP ContinueReadingDisk
		
ChangeDiskSide:
		INC BYTE [nSide]			;//If nSide =0 ,Change side.
		
        
ContinueReadingDisk:
                
        ;ReadSector();
        CALL ReadSector
        
		INC BYTE [nSector]      ;<=== <Read Next Sector>.
		
        
        JMP ContinueDownload	;//If didn't yet finish Loading OS.
        
EndDownloadingOS:
 
        RET
        
        
;************************************************************************
;//Read Sector.
;************************************************************************
ReadSector:
 
        MOV BYTE [nTrays],0		;//Set nTrays=0
        
TryAgain:
 
        MOV AH,2				;//Read Function.
        MOV AL,1				;//Read 1 Sector.
        MOV BYTE CH,[nTrack]	;//Track n (For Hard disk the upper 9-10 bits of Track number are in the upper 2 bits of CL).
        MOV BYTE CL,[nSector]	;//Remember: Sectors start with 1, not 0.
        MOV BYTE DH,[nSide]		;//Side n
        MOV BYTE DL,[DriveNumber]	;//Drive n (floppy's start with 0, Hard disks start with 0x80, and CD-ROM with 0xE0).	
        MOV WORD BX,[pOS]		;//ES:BX points to the address to were to store the sector.
        INT 13h
        
 
        CMP AH,0				;//Int 13 return Code is in AH.
        JE EndReadSector		;//if 'Success' (AH = 0) End function.
 
        MOV AH,0				;//Else Reset Drive . And Try Again...
        MOV BYTE DL,[DriveNumber]
        INT 13h
        CMP BYTE [nTrays],3		;//Check if you tried reading more then 3 times.
        
        JE DisplayError			;// if tried 3 Times Display Error.
        
        INC BYTE [nTrays]
        
        JMP TryAgain		;//Try Reading again.
        
DisplayError:
        LEA WORD AX,[szErrorReadingDrive]
        Call PrintMessage
        Call GetKey
        MOV AH,0			;//Reboot Computer.
        INT 19h
        
 
EndReadSector:
        ADD WORD [pOS],512  ;//Move the pointer (ES:BX = ES:pOS = 0:pOS) 512 bytes.
                               ;//Here you set the variable pOS (pOS points to were BIOS 
                               ;//Would load the Next Sector).
                               
        RET

;************************************************************************
;//Clear Screen.
;************************************************************************
ClearScreen
 
        MOV AX,0600h   ;//Scroll All Screen UP to Clear Screen.
        MOV BH,07
        MOV CX,0
        MOV DX,184Fh   
        INT 10h
        
        MOV BYTE [xCursor],0  ;//Set Cursor Position So next write would start in the beginning of screen.
        MOV BYTE [yCursor],0
 
        RET
        
;************************************************************************
;//Put a 55AAh (BOOT sector signature) at the end of the BOOT sector.
;************************************************************************
MakeABOOTSectorSigneture:
 
      TIMES 510-($-$$) DB 0 ;//Fills spare space with zeros.
      DW 0xAA55				;//This is the BOOT Sector Signature.
;************************************************************************
;*

Posted: Wed Mar 07, 2007 12:50 pm
by Combuster

Posted: Sat Mar 10, 2007 8:15 am
by inflater
In real mode, a boot sector can the simplest thing in a whole OS development. This is my new RSFS boot sector:

Code: Select all

; RSFS bootloader

org 0x7C00
use16

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Boot sector starts here ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        jmp             start
        nop
bsOemName               DB      "RSFSBOOT"      ; 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 ;its stored in here 00 for A:, 0x80 for C:
bsUnused                DB      ?               ; 0x25
bsExtBootSignature      DB      ?               ; 0x26
bsSerialNumber          DD      ?               ; 0x27
bsVolumeLabel           DB      "NO NAME    "   ; 0x2B
bsFileSystem            DB      "RSFS 1.0"      ; 0x36

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Boot sector code starts here ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

start:
push cs
pop ds
push ds
pop es

mov ax,0003h
int 10h
mov si,rsfs_display
call print

mov si,rsfs_load
call print

@@crcagain:
mov ah,04h ;crc test
mov al,10  ;boot sektor a PXLDR zaberaju len 10 sektorov na 0. stope
xor dx,dx
mov ch,0
mov cl,1
mov dl,[bsDriveNumber]
int 13h
mov si,rsfs_dot
call print
jc @@crc_chyba

@@readagain:
mov ah,02h
mov al,8
xor dx,dx
mov ch,0
mov cl,2
mov dl,[bsDriveNumber]
mov bx,0100h
mov es,bx
mov bx,0000h
int 13h
mov si,rsfs_dot
call print
mov dl,[bsDriveNumber]
jc @@read_chyba

jmp far 0100h:0000h

@@crc_chyba:
xor ax,ax
xor dx,dx
int 13h
mov si,rsfs_dot
call print
jc @@kritchyba
jnc @@crcagain

@@read_chyba:
xor ax,ax
xor dx,dx
int 13h
mov si,rsfs_dot
call print
jc @@kritchyba
jnc @@readagain

@@kritchyba:
mov si,rsfs_error
call print
xor ax,ax
int 16h
jmp far 0x0F000:0x0FFF0

print:
mov ah,0eh
stringloop:
lodsb
cmp al,00
je endstring
int 10h
jmp stringloop
endstring:
ret

rsfs_display db 13,10,'RSFS bootloader pre PortixOS',13,10,13,10
             db 'Cakajte prosim, zavadza sa systemove jadro.',13,10
             db 'Ak sa nenacita do 10 sekund, restartujte pocitac a skuste to znova.',0

rsfs_load    db 13,10,13,10,'Zavadzam OS.',0
rsfs_dot     db '.',0

rsfs_error   db 13,10,13,10,'Chyba: Nemozno resetovat radic pruzneho disku.'
             db 13,10,'Stlacte ENTER na restart...',0
drivenum db 0

times 56 db 0
;signatura END OF BOOT SECTOR
dw 0xaa55