Message-ID: <3303F85B.6699@rangenet.com> Date: Thu, 13 Feb 1997 23:30:03 -0600 From: Dan Hedlund Reply-To: markiv AT rangenet DOT com Organization: Range Net MIME-Version: 1.0 To: Liam CC: djgpp AT delorie DOT com Subject: Re: Boot loader References: <199702121712 DOT RAA11984 AT mx2 DOT rmplc DOT co DOT uk> Content-Type: multipart/mixed; boundary="------------A3E364E18EF" This is a multi-part message in MIME format. --------------A3E364E18EF Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Liam wrote: > > If you write a boot loader, is it limited to 512 bytes( 1 sector)? > So apart from containig the boot header information, would the > boot loader have to load a file from disk to continue the loading > process? With out having DOS loaded, will this leave you > with using the BIOS interupts? > Also, does NASM support the PROC directive? > Cheers > Liam I've writen a boot loader that loads a DOS file into memory, and runs it. To compile it type: djasm bootstra.asm bootstra.bin bootstra.map Then move bootstra.bin into the boot sector, and boot the computer. It loads "bootrm.bin" into memory, and runs it. -- ***** *** ** ** Dan M. Hedlund ** ** ***** *** ** ** ** ** ** **** ** http://www.rangenet.com/markiv ** ** ** ** ** ** ** ** ** ******* ** **** ** ** ** ** ** *** ** ** ** ** ** ** ***** ** ** ** ** --------------A3E364E18EF Content-Type: text/plain; charset=us-ascii; name="Bootstra.asm" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Bootstra.asm" ; Dos Disk Structure ; ; Name: Length in Sectors ; ; Boot Loader [RsvdSectors] ; File Allocation Table [SectorsFAT] * [NumFATs] ; Root Directory 32 * [NumDirs] / 512 ; Data ... ; ; BIOS_Sector = (DOS_Sector % [SectorsTrack]) + 1 ; BIOS_Track = (Dos_Sector / [SectorsTrack]) / [NumHeads] ; BIOS_Head = (Dos_Sector / [SectorsTrack]) % [NumHeads] ; ; Dos_Sector = ([SectorsCluster] * (Cluster - 2)) + offset Data ; .type "bin" .start ; Jmp RealStart .db 0xe9 .dw RealStart - 3 OEM: .db 0, 0, 0, 0, 0, 0, 0, 0 ; OEM name and version BytesSector: .dw 0x200 ; bytes per sector SectorsCluster: .db 1 ; sectors per cluster RsvdSectors: .dw 1 ; number of reserved sectors NumFATs: .db 2 ; number of FAT's on disk NumDIRs: .dw 0x00e0 ; number of root directory entries NumSectors: .dw 0x0b40 ; number of sectors MD: .db 0xf0 ; media descriptor byte SectorsFAT: .dw 0x0009 ; sectors per fat SectorsTrack: .dw 0X0012 ; sectors per track NumHeads: .dw 2 ; number of heads HumHidSectors: .dd 0 ; number of hidden sectors NumSectors2: .dd 0 ; (DOS4+) number of sectors if NumSectors = 0 Drive: .db 0 ; (DOS4+) physical drive number .db 0 ; (DOS4+) reserved Sig: .db 0x29 ; (DOS4+) signature byte SerialNo: .dd 0 ; (DOS4+) volume serial number VolLabel: .db "Hello World" ; (DOS4+) volume label .db 0, 0, 0, 0, 0, 0, 0, 0 ; (DOS4+) reserved .db 0, 0 RealStart: mov ax, 0x9000 ; 64k stack at 0x9000:0 mov ss, ax mov sp, 0 jmpf 0x7c0 : new_csip new_csip: push cs pop ds pushf mov ah, 0x60 push ax popf pushf pop ax popf cmp ah, 0x60 je ok386 mov si, Error386 jmpl ErrorMessage ok386: pushw 0xb800 pop gs mov ax, 0x8000 mov es, ax mov fs, ax xor bx, bx ; Load the FAT mov ax, [RsvdSectors] ; to 0x8000:0x0000 mov si, [SectorsFAT] call ReadSectors mov bx, 0x8000 ; Load the Root Directory mov ax, [SectorsFAT] ; to 0x8000:0x8000 mov cl, [NumFATs] mov ch, 0 mul cx add ax, [RsvdSectors] mov si, [NumDIRs] shr si, 4 mov [StartSector], ax add [StartSector], si call ReadSectors shl si, 9 add si, bx @L3: ; find "BOOTRM.BIN" - "BOOTRM BIN" cmp si, bx je @L2 cmpd es: [bx + 00], 0x544f4f42 ; "BOOT" jne @L4 cmpd es: [bx + 04], 0x20204d52 ; "RM " jne @L4 cmpw es: [bx + 08], 0x204e4942 ; "BIN " jne @L4 mov si, es: [bx + 26] ; First FAT entry jmp LoadRM @L4: add bx, 32 jmp @L3 @L2: mov si, ErrorFile jmpl ErrorMessage LoadRM: mov cx, 0x1000 mov es, cx xor bx, bx mov ax, [BytesSector] ; paragraphs per cluster mov cl, [SectorsCluster] mov ch, 0 mul cx shr ax, 4 xchg si, ax mov cx, 0x1000 LoadRMloop: mov es, cx add cx, si call ReadCluster mov di, ax add di, ax add di, ax shr di, 1 test ax, 1 mov ax, fs: [di] jnz odd even: and ax, 0x0fff jmp EOcontinue odd: shr ax, 4 EOcontinue: cmp ax, 0x0ff0 jle LoadRMloop ; callf 0x1000:0 .db 0x9a .dw 0 .dw 0x1000 movd gs: [4], 0x12345678 Done: jmp Done ; Read Cluster ; AX - Cluster ReadCluster: pusha sub ax, 2 mov dh, 0 mov dl, [SectorsCluster] mov si, dx mul dx add ax, [StartSector] call ReadSectors popa ret ; Read Several Sectors ; AX - Dos Starting Sector ; SI - Number of Sectors ; ES:BX - Buffer ReadSectors: pusha @L1: call ReadSector inc ax add bx, [BytesSector] dec si jnz @L1 popa ret ; Read One Sector ; AX - Dos sector ; ES:BX - Buffer ReadSector: pusha call Dos2Phys mov si,3 ; three reties rs_loop: mov ax,0x0201 ; read one sector int 0x13 ; bios disk services jnc rs_exit ; carry set=error, not set=hunky dory dec si ; does not affect carry flag jz rs_error ; oop's sumpin wong wit du disk mov ah,0 ; reset the disk system before we try again int 0x13 ; bds jmp rs_loop ; play it again, sam rs_error: mov si, ErrorDisk jmp ErrorMessage rs_exit: popa ret ; Dos Sector to Physical Sector ; ; AX - Dos Sector ; DX - Head ; CH:CL : - track:cylinder - for int13 Dos2Phys: push ax push bx mov dx, 0 divw [SectorsTrack] mov bx, dx inc bx mov dx, 0 divw [NumHeads] mov bh, al shl ah, 6 or bl, ah mov cx, bx mov dh, dl mov dl, 0 pop bx pop ax ret ErrorMessage: mov ax, 0xb800 mov es, ax xor di, di em1: lodsb or al, al jz em2 stosb mov al, 0x0f stosb jmp em1 em2: jmp em2 ErrorDisk: .db "Error reading disk!", 0 ErrorFile: .db "Cannot load bootrm.bin!", 0 Error386: .db "80386 required!", 0 ; obligatory bios doodad (int 19 won't recognize us without this) .org 0x1fe ; this will catch any overflow (code getting too big) .dw 0xaa55 ; bios validation flag .align 512,0 ; error checking, will cause the bin file to go to ; 1024 bytes if there is any overflow above. .bss ; no bytes will be generated from this point on StartSector: .dw 0 --------------A3E364E18EF--