One thing I needed to verify was that copyraw has copied the all sectors correctly. Here are the copyraw source and its log. I can see it is all correct.
1. Before anything, it reads sector 0 to DAP area.
2. Open boot.bin first and overwrites DAP (minutes 64 bytes to preserve) to sector 0.
3. Opens the exp.exe and skip over first 2x512 chunks since it is DOS header area.
Also on exp.exe, I placed code segment before any other segment (DATA, STACK) so that CODE segment is immediately after DOS header.
From the copyraw.log, I can see it all copied correctly, by printing first few bytes of 512 chunk just copying and reading back and print. Using hiew disassembler, I can see those bytes are correct. (I just pasted the entire source code for copyraw.asm and its log below.
Code: Select all
;
include macros.inc
include disk.inc
; re-defined the part of disk.inc here so that no need to include
; disk.asm,
DAP_OFFSET_SIZE = 0
DAP_OFFSET_UNUSED = 1
DAP_OFFSET_NO_SECTORS = 2
DAP_OFFSET_BUFFER_PTR = 4
DAP_OFFSET_SECTOR_START = 8
sta segment para stack use16 'stack'
sta ends
; here we define variables bootloader.
data segment para public 'data'
fileName db "boot.bin", 0
dosHdrBuffer db 512 dup (36h)
mbrBuffer db 512 dup (37h) ; mbr write buffer.
mbrReadBuffer db 512 dup (35h) ; mbr read first and partition table is copied to mbrBuffer
filePointer dw ?
readSize dw ?
; here we define variables for file being loaded. will be kernel.
fileName1 db "exp.exe$"
mbrBuffer1 db 512 dup (38h)
filePointer1 dw ?
readSize1 dw ?
counter dd 0
; disk access packet area.
dap db 16 dup(31h)
data ends
code segment para public use16 'code'
assume cs:code, ds:data,ss:sta
M_EXTERNDEF
; code to be copy mbr code to 1st sector of HDD (sector No. 0).
; this will open boot.bin (bootloader) file and reads first 1024
; (should read entire file) bytes into pre-defined buffer and will copy
; the entire file content (minus DOS header) into Disk 80h sector 0.
main proc far
; do not run from windows, prevent accidental erase of MBR in case it is allowed.
mov eax, cr0
test eax, 01
jz mainLab1
M_PRINTF "\nCan not run from protected mode."
jmp mainExit
mainLab1:
; Read sector 0 first. Doing so will help preserve the partition table
; when we write back after loading boot.bin and overwrite first 200h-64 bytes.
mov dl, 80h ; disk 0
mov si, DATA
mov ds, si
lea si, dap ; (DS:SI) = SEG:OFF pointer to dap.
; Prepare DAP area.
mov cx, 1 ; (CX) = No. of sectors.
mov di, DATA
mov es, di
lea di, mbrBuffer ; (DS:SI) = SEG:OFF pointer to dap.
mov byte ptr ds:[si+DAP_OFFSET_SIZE], 10h
mov byte ptr ds:[si+DAP_OFFSET_UNUSED], 00h
mov word ptr ds:[si+DAP_OFFSET_NO_SECTORS], cx
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR], di
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR+2], es
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START], 0h
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START+4], 0h ; set starting sector No for upper 48 lba.
; Issue read DOS function to read into region defined by DAP area.
mov ah, 42h ; (AH) = fcn No. for extended disk read.
int 13h ; (AH) = return code if error reading.
jnc mainLab1a
M_PRINTF "\nRead sector 0 failure. Exiting (Error code): "
M_PRINTBYTE ah
jmp mainExit
mainLab1a:
M_PRINTF "\nRead sector 0 success."
M_PRINTSTR_1616_NL es, di, 0, 020h
; Open bootstrap file. Will copy first 512-64 bytes overwriting the DAP area.
mov ah, 3dh ; (AH) = file open int 21h code.
sub al, al ; (AL) = RO mode.
mov dx, DATA
mov ds, dx
lea dx, fileName ; (DS:DX) = pointer to filename string.
M_PRINTF "\nbootloader file (boot.bin): "
M_PRINTSTR_1616_NL ds, dx, 1, 7
int 21h ; (AX) = file handle.
jnc mainLab2
M_PRINTF "\nFailure opening boot.bin file (error code): "
M_PRINTWORD ax
jmp mainExit
; Read till the end or up to 1024 - 64 (dos header + mbr - partition table size)
; into buffer if FF pointer is successful.
mainLab2:
M_PRINTF "\nSuccess opening file boot.bin (fileHandle), reading: "
M_PRINTWORD ax
mov filePointer, ax ; save file pointer.
mov ah, 3fh ; (AH) = file read int 21h code.
mov bx, filePointer ; (BX) = file pointer.
mov cx, 400h - 64 ; (CX) = 1024 - bytes but leave partition table area.
mov dx, DATA
mov ds, dx
lea dx, dosHdrBuffer ; (DS:DX) = 16:16 buffer to read into.
int 21h ; (AX) = No. of bytes read if success.
jnc mainLab3
M_PRINTF "\nFailed to read boot.bin file (Error code): "
M_PRINTWORD ax
jmp mainExit
; copy to disk 80h sector 0. Since the first 200h bytes of read is dosheader
; we point the DS:SI to right after dosHeaderBuffer which is mbrBuffer
; which itself is 512 bytes.
mainLab3:
M_PRINTF "\nRead success for boot.bin (No. of bytes): "
M_PRINTWORD ax
mov readSize, ax ; save read size.
mov dl, 80h ; disk 0
; Start writing DAP area back to sector 0.
mov si, DATA
mov ds, si
lea si, dap ; (DS:SI) = SEG:OFF pointer to dap.
mov di, DATA
mov es, di
lea di, mbrBuffer ; (DS:SI) = SEG:OFF pointer to dap.
M_PRINTF "\nData to write to sector 0: "
M_PRINTSTR_1616 es, di, 0, 020h
mov byte ptr ds:[si+DAP_OFFSET_SIZE], 10h
mov byte ptr ds:[si+DAP_OFFSET_UNUSED], 00h
mov word ptr ds:[si+DAP_OFFSET_NO_SECTORS], 1
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR], di
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR+2], es
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START], 0h
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START+4], 0h ; set starting sector No for upper 48 lba.
M_PRINTF "\nDap: "
M_PRINTSTR_1616 ds, si, 0, 010h
mov ah, 43h ; (AH) = fcn No. for extended disk write.
sub al, al ; (AL) = close write check. Not sure what it means.
int 13h ; (AH) = return code if error writing.
jnc mainLab4
M_PRINTF "\nWrite to sector 0 failure. Exiting (Error code): "
M_PRINTBYTE ah
jmp mainExit
; open loading file.
mainLab4:
M_PRINTF "\nSuccess writing sector 0. Readback test: "
; perform a sector 0 readback:
mov dl, 80h ; disk 0
mov si, DATA
mov ds, si
lea si, dap ; (DS:SI) = SEG:OFF pointer to dap.
; prepare DAP area.
mov cx, 1 ; (CX) = No. of sectors.
mov di, DATA
mov es, di
lea di, mbrBuffer ; (DS:SI) = SEG:OFF pointer to dap.
mov byte ptr ds:[si+DAP_OFFSET_SIZE], 10h
mov byte ptr ds:[si+DAP_OFFSET_UNUSED], 00h
mov word ptr ds:[si+DAP_OFFSET_NO_SECTORS], cx
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR], di
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR+2], es
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START], 0h
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START+4], 0h ; set starting sector No for upper 48 lba.
mov ah, 42h ; (AH) = fcn No. for extended disk read.
int 13h ; (AH) = return code if error writing.
jnc mainLab5
M_PRINTF "\nReadback failure for sector 0. Exiting (Error code): "
M_PRINTBYTE ah
mainLab5:
M_PRINTF "\nReadback success for sector 0. "
M_PRINTSTR_1616_NL es, di, 0, 020h
M_PRINTF "\nClosing bootloader file"
mov ah, 3eh
mov bx, filePointer
int 21h
jnc mainLab6
M_PRINTF "\nWARNING: Failed to close file using handle: "
M_PRINTWORD filePointer
mainLab6:
M_PRINTF "\nClose file attempt is done"
; start copying the bootable application.
M_PRINTF "\nCopying the application file to raw sectors."
mov ah, 3dh ; (AH) = file open int 21h code.
sub al, al ; (AL) = RO mode.
mov dx, DATA
mov ds, dx
lea dx, fileName1 ; (DS:DX) = pointer to filename string.
int 21h ; (AX) = file handle.
jnc mainLab2a
M_PRINTF "\nFailed to open application file (error code): "
M_PRINTWORD ax
jmp mainExit
; read 200h chunk at a time and keep writing until it is done.
; however skip the first 200h chunk since this is the DOS header.
mainLab2a:
M_PRINTF "\nFile open success (fileHandle), reading 200h byte chunk at a time: "
M_PRINTWORD ax
mov filePointer1, ax ; save file pointer.
mov dword ptr counter, 0 ; initialize counter.
mainLoop1a:
M_PRINTF "\nLoop No. "
M_PRINTDWORD counter
mov ah, 3fh ; (AH) = file read int 21h code.
mov bx, filePointer1 ; (BX) = file pointer.
mov cx, 200h ; (CX) = 512 bytes per read.
mov dx, DATA
mov ds, dx
lea dx, mbrBuffer1 ; (DS:DX) = 16:16 buffer to read into.
int 21h ; (AX) = No. of bytes read if success.
jnc mainLab3a
M_PRINTF "\nFailed to read application file (Error code): "
M_PRINTWORD ax
jmp mainExit
; Write current read into disk sector. skip if it is first read chunk
; since it is dos header.
mainLab3a:
M_PRINTF "\nRead success for application file (No. of bytes): "
M_PRINTWORD ax
mov readSize, ax ; save read size.
or ax, ax ; read size = 0?
jz mainExit ; leave if so.
cmp dword ptr counter, 2 ; is it 3r read?
jb mainSkipFirstRead ; if first/second read, jump over since dos header.
; Not the first/second read, start writing.
M_PRINTF "\nWriting from application area to sector"
M_PRINTDWORD counter
mov dl, 80h ; disk 0
mov si, DATA
mov ds, si
lea si, dap ; (DS:SI) = SEG:OFF pointer to dap.
mov di, DATA
mov es, di
lea di, mbrBuffer1 ; (DS:SI) = SEG:OFF pointer to dap.
M_PRINTF "\nData to write: "
M_PRINTSTR_1616 es, di, 0, 020h
mov byte ptr ds:[si+DAP_OFFSET_SIZE], 10h
mov byte ptr ds:[si+DAP_OFFSET_UNUSED], 00h
mov word ptr ds:[si+DAP_OFFSET_NO_SECTORS], 01h
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR], di
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR+2], es
mov eax, counter ; (EAX) = counter, serves as sector write No. too.
dec eax ; (EAX) = start with sector 1.
M_PRINTF "\nWriting to sector No: "
M_PRINTDWORD eax
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START+4], 0 ; set starting sector No for upper 48 lba.
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START], eax
M_PRINTF "\nDAP area: "
M_PRINTSTR_1616 ds, si, 0, 020h
mov ah, 43h ; (AH) = fcn No. for extended disk write.
int 13h
jnc mainLab4a
M_PRINTF "\nWrite failure. Exiting (Error code): "
M_PRINTBYTE ah
jmp mainExit
mainLab4a:
M_PRINTF "\nSuccess writing sector. Readback test: "
; Perform a sector N readback:
mov dl, 80h ; disk 0
mov si, DATA
mov ds, si
lea si, dap ; (DS:SI) = SEG:OFF pointer to dap.
; prepare DAP area.
mov di, DATA
mov es, di
lea di, mbrBuffer1 ; (DS:SI) = SEG:OFF pointer to dap.
mov byte ptr ds:[si+DAP_OFFSET_SIZE], 10h
mov byte ptr ds:[si+DAP_OFFSET_UNUSED], 00h
mov word ptr ds:[si+DAP_OFFSET_NO_SECTORS], 1h
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR], di
mov word ptr ds:[si+DAP_OFFSET_BUFFER_PTR+2], es
mov eax, counter ; (EAX) = counter, serves as sector write No. too.
dec eax ; (EAX) = disk sector No. = counter - 1.
M_PRINTF "\nReadback sector No: "
M_PRINTDWORD eax
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START], eax
mov dword ptr ds:[si+DAP_OFFSET_SECTOR_START+4], 0h ; set starting sector No for upper 48 lba.
mov ah, 42h ; (AH) = fcn No. for extended disk read.
int 13h ; (AH) = return code if error writing.
jnc mainLab5a
M_PRINTF "\nReadback failure. Exiting (Error code): "
M_PRINTBYTE ah
mainLab5a:
M_PRINTF "\nReadback success. "
M_PRINTSTR_1616_NL es, di, 0, 020h
mainSkipFirstRead:
inc dword ptr counter
jmp mainLoop1a
mainExit:
M_PRINTF "\nClosing application file"
mov ah, 3eh
mov bx, filePointer1
int 21h
jnc mainExit1
M_PRINTF "\nWARNING: Failed to close file using handle: "
M_PRINTWORD filePointer
mainExit1:
mov ax, 4c00h
int 21h
main endp
code ends
end main
;COPYRAW.LOG:
Read sector 0 success.
0701:0209: BE 00 B8 8E DE 2B F6 B9 : 10 00 B8 30 0E 88 04 FE
0701:0219: C0 FE C0 3C 39 72 02 B0 : 30 83 C6 02 E2 EF B2 80
bootloader file (boot.bin):
boot.bi
Success opening file boot.bin (fileHandle), reading: 0005
Read success for boot.bin (No. of bytes): 0258
Data to write to sector 0:
0701:0209: BE 00 B8 8E DE 2B F6 B9 : 10 00 B8 30 0E 88 04 FE
0701:0219: C0 FE C0 3C 39 72 02 B0 : 30 83 C6 02 E2 EF B2 80
Dap:
0701:081D: 10 00 01 00 09 02 01 07 : 00 00 00 00 00 00 00 00
Success writing sector 0. Readback test:
Readback success for sector 0.
0701:0209: BE 00 B8 8E DE 2B F6 B9 : 10 00 B8 30 0E 88 04 FE
0701:0219: C0 FE C0 3C 39 72 02 B0 : 30 83 C6 02 E2 EF B2 80
Closing bootloader file
Close file attempt is done
Copying the application file to raw sectors.
File open success (fileHandle), reading 200h byte chunk at a time: 0005
Loop No. 00000000
Read success for application file (No. of bytes): 0200
Loop No. 00000001
Read success for application file (No. of bytes): 0200
Loop No. 00000002
Read success for application file (No. of bytes): 0200
Writing from application area to sector00000002
Data to write:
0701:0615: B8 95 04 8E D8 BE 00 B8 : 83 C6 20 8E DE 2B F6 B9
0701:0625: 10 00 B8 41 00 88 04 FE : C0 3C 45 72 02 B0 41 83
Writing to sector No: 00000001
DAP area:
0701:081D: 10 00 01 00 15 06 01 07 : 01 00 00 00 00 00 00 00
0701:082D: 00 00 00 74 65 73 74 20 : 73 74 72 69 6E 67 20 69
Success writing sector. Readback test:
Readback sector No: 00000001
Readback success.
0701:0615: B8 95 04 8E D8 BE 00 B8 : 83 C6 20 8E DE 2B F6 B9
0701:0625: 10 00 B8 41 00 88 04 FE : C0 3C 45 72 02 B0 41 83
Loop No. 00000003
Read success for application file (No. of bytes): 0200
Writing from application area to sector00000003
Data to write:
0701:0615: 80 C2 07 B4 02 CD 21 58 : 5A 5A 52 8C DA 80 E2 FF
0701:0625: 52 50 8A D2 C0 EA 04 80 : E2 0F 80 C2 30 80 FA 39
Writing to sector No: 00000002
DAP area:
0701:081D: 10 00 01 00 15 06 01 07 : 02 00 00 00 00 00 00 00
0701:082D: 00 00 00 74 65 73 74 20 : 73 74 72 69 6E 67 20 69
Success writing sector. Readback test:
Readback sector No: 00000002
Readback success.
0701:0615: 80 C2 07 B4 02 CD 21 58 : 5A 5A 52 8C DA 80 E2 FF
0701:0625: 52 50 8A D2 C0 EA 04 80 : E2 0F 80 C2 30 80 FA 39
Loop No. 00000004
Read success for application file (No. of bytes): 0200
Writing from application area to sector00000004
Data to write:
0701:0615: 76 03 80 C2 07 B4 02 CD : 21 58 5A 52 50 8A D2 80
0701:0625: E2 0F 80 C2 30 80 FA 39 : 76 03 80 C2 07 B4 02 CD
Writing to sector No: 00000003
DAP area:
0701:081D: 10 00 01 00 15 06 01 07 : 03 00 00 00 00 00 00 00
0701:082D: 00 00 00 74 65 73 74 20 : 73 74 72 69 6E 67 20 69
Success writing sector. Readback test:
Readback sector No: 00000003
Readback success.
0701:0615: 76 03 80 C2 07 B4 02 CD : 21 58 5A 52 50 8A D2 80
0701:0625: E2 0F 80 C2 30 80 FA 39 : 76 03 80 C2 07 B4 02 CD
Loop No. 00000005
Read success for application file (No. of bytes): 0200
Writing from application area to sector00000005
Data to write:
0701:0615: EB 0F 74 68 69 73 20 69 : 73 20 65 78 74 46 63 6E
0701:0625: 24 8C CE 8E DE 8D 36 02 : 06 2A C9 B5 01 0E E8 3C
Writing to sector No: 00000004
DAP area:
0701:081D: 10 00 01 00 15 06 01 07 : 04 00 00 00 00 00 00 00
0701:082D: 00 00 00 74 65 73 74 20 : 73 74 72 69 6E 67 20 69
Success writing sector. Readback test:
Readback sector No: 00000004
Readback success.
0701:0615: EB 0F 74 68 69 73 20 69 : 73 20 65 78 74 46 63 6E
0701:0625: 24 8C CE 8E DE 8D 36 02 : 06 2A C9 B5 01 0E E8 3C
Loop No. 00000006
Read success for application file (No. of bytes): 0200
Writing from application area to sector00000006
Data to write:
0701:0615: 50 8A D2 C0 EA 04 80 E2 : 0F 80 C2 30 80 FA 39 76
0701:0625: 03 80 C2 07 B4 02 CD 21 : 58 5A 52 50 8A D2 80 E2
Writing to sector No: 00000005
DAP area:
0701:081D: 10 00 01 00 15 06 01 07 : 05 00 00 00 00 00 00 00
0701:082D: 00 00 00 74 65 73 74 20 : 73 74 72 69 6E 67 20 69
Success writing sector. Readback test:
Readback sector No: 00000005
Readback success.