Information on How disks are made up.
When your computer starts up it will do a self-test and then tries to load the bootsector (512 bytes) of your hard drive/floppy disk in the memory at 0000h:7C00h, and jumps to 0000h:7C00h. You should make a 512 byte long code, but the last word of the 512 bytes should be AA55h because otherwise your computer will not detect that this is a valid bootsector code. It is safe to PUSH & POP things because SS:SP points to a special reserved stack area (256 bytes). Also go to this page for a more complete bootsector that will "walk" the root directory and FAT looking for a "kernel" file to load. It will find any given file in the root directory, load it, and execute it.
; Please note: This code is not ready to assemble. It
; is simply an example. You will need to add code to it
; to make it a usable boot sector
; Let's say we have just booted and are going to run a
; simple MBR that loads a boot off of a partition and does
; nothing more (very simple MBR):
ORG 00h
; please note that I use the 'C' style notation
; for hex digits only when it represents a
; physical memory address. All other hex values
; are represented as segment addresses or immediates.
; set up the "move this sector" out of the way
mov ax,07C0h ;
mov ds,ax ; ds:si points to 0x07C00
xor si,si ;
mov es,ax ; es:di points to 0x07C00 + 200h
mov di,200h ;
; now move us out of the way
mov cx,100h ; 256 words
rep
movsw
; now we could jump to the new code many different ways.
; Why not use a relative near jump.
; ($+3 to point to next instruction
; +200h) to point to next "sector" location
jmp ($+3+200h) ; this is a three byte jump
; or could use:
; jmp (offset StartHere + 200h)
; which would probably be better since some assemblers
; might *not* make the above jump a 3 byte jump?
StartHere:
; Now we are out of the way.
; Use a 4 iteration loop and find the active partition
; .....
; (code to give error if no active partition found
; could go here....)
; found active partition
; perspective registers are CHS coded
; set DL from partition record
; (this assumes partition is before the BIOS read limit)
; ES still points to 07C0h
mov ax,0201h ; read the sector
xor bx,bx ; ES:BX -> 07C0:0000h (0x07C00)
int 13h
; now simply jump back to 0x07C00
; we could use all kinds of ways.
; (1)
; jmp short 0 ; that is a zero, not an oh!
; ******** ERROR ******
; *This one rely's on CS = 07C0h, since we did not
; *make sure CS = 07C0h on boot up, we don't want
; *to use it.
; (2)
; remember that NBASM wants: jmp far 0000h,07C0h
jmp far 07C0:0000h ; a far jump
; This one does set up the CS:IP registers for
; the Partition Boot we loaded. However, the partition
; boot will also assume that CS:IP is *NOT* set to
; 07C0:0000h.
; This type of jmp just ensures that it will.
; (3)
; If we made sure we didn't destroy ES:BX above:
; push es
; push bx
; retf
; (4)
; Add your favorite way.
; plenty of room to place your 'print_string' code, etc.
; pad to partition table
partition_table ....
ID_Word ....
.end
Now how about a "Partition Boot"?
; Please note: This code is not ready to assemble. It
; is simply an example. You will need to add code to it
; to make it a usable boot sector
ORG 00h
; If we want a FAT compatible BOOT, we need
; jmp short xxxxx/nop
; to jump over a BPB
jmp short start
nop
; FAT BPB goes here
start:
; set up the data segment registers
mov ax,07C0h ;
mov ds,ax ;
mov es,ax ;
; To be a FAT compatible system, we need
; to check the "reserved area" part of the BPB
; to see how many sectors are used by the boot.
; For this example, let us assume that it is more
; than one.
; Now, most likely we didn't get all of this boot
; code to fit in one sector, so let us load
; the remaining sectors.
; If we guarantee that our read_sector routine is
; in the first sector, then it is already loaded
; by the bios or by the MBR code.
mov ax,1 ; LBA starting sector (zero based)
cwd ; (dx:ax)
mov cx,???? ; count of remaining sectors
mov bx,200h ; start placing them at 07C0:0200h
call read_sectors
; now, let us make sure there is enough room in the
; initial 200h bytes, so lets jump to 07C0:0200h
; (a near relative jump)
jmp short Start_Loader
read_sectors proc near
;
; this procedure takes an LBA sector number from DX:AX
; transforms it to CHS and reads CX count sectors
; to memory starting at ES:BX
; It makes sure we don't wrap BX to zero by adding to ES instead
; of BX each iteration.
; It reads one sector at a time to make sure the BIOS
; isn't one of those that can't read over a track end
;
read_sectors endp
; place other procedures and data here
; no need for a partition table
; pad to xxxx:0510
ID_WORD ; goes here
; this is actually at 07C0:0200h
Start_Loader:
; this is where you could start you loader code.
; please note that since we never assume anything
; about CS:IP and we set ORG to 00h above, we can
; simply use a relative call to the
; Read_Sectors
; routine above and any other routines that might
; be in the first sector.
; done. Loader should have taken over by now.
.end
The following is a simple program to place your new bootsector code to your floppy. ; ; Please note that this is a simple program included for the ; boot sector example. Once the boot sector example is ; written to the boot sector of a floppy disk, all data ; on this disk will be lost due to no BPB. ; ; ** This is for example only ** ; It assumes your boot image is named: boot.bin ; ; assemble with NBASM ; NBASM INSTALL .model tiny .code .186 org 100h start: mov ah,09h ; print start up string mov dx,offset StartS ; int 21h ; xor ah,ah ; get a key int 16h ; cmp al,79h ; if 'y' then continue je short Cont ; cmp al,59h ; if 'Y' then continue je short Cont ; ret ; else exit to DOS Cont: mov dl,al ; print the letter mov ah,06 ; int 21h ; mov ax,3D02h ; open image file mov dx,offset imgfile ; int 21h ; jnc short FileOK ; if no error cont mov ah,09h ; else print error string mov dx,offset ErrorS ; int 21h ; ret ; and return to DOS FileOK: mov bx,ax ; save handle mov ah,3Fh ; read from file mov cx,512 ; at most 512 bytes mov dx,offset Buffer ; in to our buffer int 21h ; mov cx,01 ; one sector to write xor al,al ; drive = a: xor dx,dx ; start at sector 0 mov bx,offset Buffer ; image file int 26h ; pop bx ; clean up stack mov dx,offset MErrorS ; Assume Error jc short MError ; carry = error mov dx,offset SuccessS ; Was not error MError: mov ah,09h ; int 21h ; .exit 00h StartS db 'Simple Boot sector installer.',13,10,13,10 db 'This program will install the BOOT.BIN file',13,10 db 'to the A: drive. Make sure that the BOOT.BIN is',13,10 db 'in the current directory.',13,10,13,10 db 'Also, this will only work with a 3« inch floppy disk.',13,10 db "Make sure that that's what's in the drive!",13,10,13,10 db '*** WARNING *** all data on floppy disk will be lost.',13,10,13,10 db 'Continue? [Y/N] ',24h imgfile db 'boot.bin',0 ErrorS db 13,10,10,'* Error opening BOOT.BIN *',24h MErrorS db 13,10,10,'**** Error writing to disk ****',24h SuccessS db 13,10,10,'Successfull',24h Buffer dup 512,? .end start All rights reserved Legal Notice Copyright © 1984-2008 Forever Young Software Return to My Home Page |