Page 1 of 1

strange debugging results [solved]

Posted: Thu Sep 26, 2019 3:47 pm
by saltlamp
Hi, it's me again. This time, I have a strange issue that I'm not sure of how to correct.

So, I gave in and began trying to debug why my boot-sector code cannot find a certain file that I'm trying to load, and I discovered something strange.

So I have two files: IO.SYS and RMDOS.SYS, and IO.SYS has dummy code to see whether or not execution was properly transferred, and the RMDOS.SYS has a MZ header that I was messing around with. (It's just a header; it's not gonna be there later)

Now, I'm working under Windows, and I'm using the native copy command, trying to copy IO.SYS first, RMDOS.SYS second, and everything else last. Here is my disk image script,

Code: Select all

@ECHO OFF

IF NOT EXIST Z:\BIN MKDIR Z:\BIN

NASM Z:\SRC\BOOT.ASM     -o Z:\BIN\FLP144MB.BIN -f bin -O0
NASM Z:\SRC\IO.ASM       -o Z:\BIN\IO.SYS       -f bin -O0
NASM Z:\SRC\RMDOS.ASM    -o Z:\BIN\RMDOS.SYS    -f bin -O0
NASM Z:\SRC\COMMAND.ASM  -o Z:\BIN\COMMAND.COM  -f bin -O0

IF EXIST Z:\PEDOS1D0.IMG DEL Z:\PEDOS1D0.IMG

DD if=/dev/zero of=Z:\PEDOS1D0.IMG bs=512 count=2880
DD if=Z:\BIN\FLP144MB.BIN of=Z:\PEDOS1D0.IMG bs=512 count=1 seek=0

IMDISK -a -f Z:\PEDOS1D0.IMG -s 1440K -m A:

COPY Z:\BIN\IO.SYS       A:\IO.SYS
COPY Z:\BIN\RMDOS.SYS    A:\RMDOS.SYS
COPY Z:\BIN\COMMAND.COM  A:\COMMAND.COM

IMDISK -D -m A:
Now, shouldn't IO.SYS be the first file? It sure says so in one my hex-editors.

https://imgur.com/a/j6LSpbY

But, when I was debugging and did a memory dump in bochs, I got the start of the MZ header; the exact one that I put in RMDOS.SYS...

I tried reversing the files, so rmdos before io.sys, but after doing that, there's now just nothing there; a bunch of zeros.

This is what bochs originally debugged when I did a linear dump:
https://imgur.com/a/bHu30gd

Here is my current code, "BOOT.ASM":

Code: Select all

BIOSSEG	EQU 07C0H	; where the PC-BIOS reads the boot-sector.
BOOTSEG	EQU 0AE0H	; the segment where the boot-sector is relocated.
LOADSEG	EQU 0050H	; where the real-mode DOS system is read. 

DOSSECCNT	EQU 2	; how many sectors IO.SYS + RMDOS.SYS occupy

	USE16

        JMP  SHORT BEGLDR
        NOP
BPBBEG:
	DB "PEDOS1.0"
BYPRSC:	DW 512
SCPRCL:	DB 1
RVSCCN:	DW 1
FATCNT:	DB 2
RDECNT:	DW 224
	DW 2880
	DB 0F0H
SCPRTR:	DW 9
SCPRFT:	DW 18
TRPRCY:	DW 2
	DD 0
	DD 0
	DW 0
	DB 41
	DD 0
	DB "           "
	DB "FAT12   "
BPBEND:

;
; This code sets all necessary segment
; registers to known values, and copies
; the boot-sector to a higher memory
; address. This boot-sector assumes a
; non-standard CS:IP, DS, and SS.
;
;
; Before Relocation:
;
; CS = ????
; DS = 07C0
; SS = 0AE0
; ES = 0AE0
; ---------
; IP = ????
;
;
; After Relocation:
;
; CS = 0AE0
; DS = 0AE0
; SS = 0AE0
; ES = 0050
; ---------
; IP = ????
; 

BEGLDR:
	MOV  AX, BOOTSEG
	MOV  ES, AX
	CLI			; clear maskable interrupts
	MOV  SS, AX
	MOV  SP, 1024
	STI			; restore interrupts
	PUSH WORD BIOSSEG
	POP  DS
	MOV  CX, 256
	XOR  SI, SI	; DS:SI should be 07C0:0
	XOR  DI, DI	; ES:DI should be 0AE0:0
	CLD
	REP  MOVSW

; DS:SI = 07C0:0 ... 07C0:1FE
; ES:DI = 0AE0:0 ... 0AE0:1FE

SAVSRS:
	PUSH ES   ; We no longer need ES, so
	POP  DS   ; DS now becomes ES (0AE0)
RSTCPU:
	PUSH BOOTSEG
	PUSH WORD CHKDSK
	RETF

;
; Next, this code will check that this
; disk is a valid System disk, and then
; load the following files:
;
; - IO.SYS
; - RMDOS.SYS
;
; from the disk to the following
; memory locations:
;
; IO      .SYS = 0050:0
; RMDOS   .SYS = 0050:0+LEN(IO.SYS)
;

CHKDSK:
	MOV  AX, WORD LOADSEG
	MOV  ES, AX
	MOV  AX, 19	; Starting LBA of Root-Dir Table.
	MOV  CX, 1	; We only need the first two entries.
	XOR  BX, BX	; Read the above exactly past the boot-sector.
	XOR  DX, DX
	ADC  DX, 0	; Correct the LBA before reading.
	CALL REDSEC
FNDDOS:
	XOR  DI, DI		; ES:DI
	MOV  SI, WORD SYSFLE	; DS:SI
	MOV  CX, 11
	REPE CMPSB
	JE   LODDOS
DSKERR:
	MOV  SI, WORD ERRMSG
	JMP  PRNSTR
LODDOS:
	MOV  AH, 14
	MOV  AL, '!'
	INT  16
	JMP  SHORT $

;
; Finally, this code will cause a CS:IP
; reset via far-jumping to the DOS system
; entry point.
;

RUNDOS:
        PUSH 0050H
        PUSH 0000H
	RETF

;
; PRNSTR: Copy the char-string specified by SI
;         into video memory, and await a system
;         reset.
;
; IN: DS:SI = addr of char-string
;

PRNSTR:
	LODSB
	OR   AL, 0		; Strings must be null-terminated.
	JZ   SHORT SR2RET
	MOV  AH, 14
	MOV  BX, 0
	INT  16		; 10H
	JMP  SHORT PRNSTR
SR2RET:
	XOR  AX, AX
	INT  22		; After the error message has been
	INT  25		; displayed, await a system reset.
;
;
; REDSEC: Read the specified sectors into memory
;         at logical address ES:BX.
; IN:
;
; DX:AX	= head, track, sector value
; CX	= sector count
;

REDSEC:
	PUSHA
        DIV  WORD [SCPRTR]
        MOV  CX, DX
        INC  CX
        XOR  DX, DX
        DIV  WORD [TRPRCY]
        MOV  CH, AL
        SHL  AH, 6
        OR   CL, AH
        MOV  DH, DL
        MOV  DL, 0	; This binary is only for floppy disks.
        MOV  AX, 201H
        INT  19		; 13H
        JNC  SHORT NXTSEC
        JMP  DSKERR
NXTSEC:
        POPA
	DEC  CX
	JZ   SHORT SR1RET
	ADD  BX, WORD [BYPRSC]
	ADD  AX, 1
	ADC  DX, 0
	JMP  SHORT REDSEC
SR1RET:
        RET

; error message
ERRMSG:	DB "Non-System disk or disk error... Replace and try again when ready."
	DB 0
DOSFLE:	DB "RMDOS   SYS" ; The real-mode kernel component to PE-DOS.
SYSFLE:	DB "IO      SYS" ; I/O system. 
	

	TIMES 510 - ($ - $$) DB 0

        DW 0AA55H	; End of Boot Sector.
"IO.ASM":

Code: Select all

	USE16
	ORG  500H

	MOV  AH, 14 ; 0Eh
	MOV  AL, 'I'
	INT  16		; 10H
	MOV  AL, 'O'
	INT  16		; 10H
	MOV  AL, '.'
	INT  16		; 10H
	MOV  AL, 'S'
	INT  16		; 10H
	MOV  AL, 'Y'
	INT  16		; 10H
	MOV  AL, 'S'
	INT  16		; 10H

JMP SHORT $

TIMES 2048 - ($ - $$) DB 0
"RMDOS.ASM":

Code: Select all

	USE16
	ORG  7C00H
	
FLEHDR:
	DW "MZ"
	DW 0
	DW 0
	DW 0
	DW 0
	DW 0
	DW 0
	DW 0
	DW 0
	DW 0
	DW 0
	DW 0
	DW 0
	DW 0
HDREND:
KRNBEG:
	JMP  SHORT $
I have no idea why those things above happened. Does Windows copy files in a way that's, you know, 'different'? I'm seriously at a loss for ideas, so if you can help, I would greatly appreciate it! Sorry if I made an obvious error somewhere, but I'm really burnt out, so I'm probably just not noticing.

~Joe

Re: strange debugging results

Posted: Fri Sep 27, 2019 1:19 am
by Octocontrabass
saltlamp wrote:Now, shouldn't IO.SYS be the first file? It sure says so in one my hex-editors.
It is, but there's no guarantee it always will be. MS-DOS uses a special tool (SYS) to ensure IO.SYS will be where the bootloader expects it to be. DR-DOS uses a smarter bootloader.
saltlamp wrote:I have no idea why those things above happened.
You're not reading the right sectors from the disk.

What is SCPRTR short for? It looks like it's supposed to be "sectors per track" but that's not what it points to.

Re: strange debugging results

Posted: Fri Sep 27, 2019 10:24 am
by saltlamp
Octocontrabass wrote:
saltlamp wrote:Now, shouldn't IO.SYS be the first file? It sure says so in one my hex-editors.
It is, but there's no guarantee it always will be. MS-DOS uses a special tool (SYS) to ensure IO.SYS will be where the bootloader expects it to be. DR-DOS uses a smarter bootloader.
saltlamp wrote:I have no idea why those things above happened.
You're not reading the right sectors from the disk.

What is SCPRTR short for? It looks like it's supposed to be "sectors per track" but that's not what it points to.
Thanks for the reply. Yes, it means sectors per track. I got it and SCPRFT (sectors per fat) reversed. My bad.

I tried changing them, and nothing worked. Thanks for letting me know that MS-DOS used a special tool, because I had no clue. I thought it was just a normal copy, haha

Re: strange debugging results

Posted: Sat Sep 28, 2019 12:38 am
by Octocontrabass
saltlamp wrote:I tried changing them, and nothing worked.
Okay, but I can't help unless you explain what's happening now that you've (probably) fixed LBA to CHS calculations.

Re: strange debugging results

Posted: Sat Sep 28, 2019 1:02 am
by iansjack
Perhaps it's time to step through the program in a debugger to see where it is deviating from your expectations?

Re: strange debugging results

Posted: Sat Sep 28, 2019 1:44 am
by saltlamp
Octocontrabass: sorry, was heading to work and had to make a quick reply. The disk reading works as expected after I fixed that error.

I just debugged it about 3 times, to make sure that I am seeing it right, and checking my code like four times per each debug session.

Code: Select all

CHKDSK:
	PUSH LOADSEG
	POP  ES
	MOV  AX, 19	; Starting LBA after Root-Dir Table.
	MOV  CX, 1
	XOR  BX, BX	; Read the above exactly past the boot-sector.
	XOR  DX, DX
	ADC  DX, 0	; Correct the LBA before reading.
	CALL REDSEC
	XOR  DI, DI
	MOV  SI, WORD SYSFLE ; "IO      SYS"
	MOV  CX, 11
	REPE CMPSB
	JNE  DSKERR
	ADD  DI, 32      ; next entry, right?
	MOV  SI, WORD DOSFLE ; "RMDOS   SYS"
	MOV  CX, 11
	REPE CMPSB
	JE   LODDOS ; skip error code if no error, right?
DSKERR:
	MOV  SI, WORD MSG000
	JMP  PRNSTR
LODDOS:
	MOV  AH, 14 ; dummy code below.
	MOV  AL, '!'
	INT  16
	JMP  SHORT $
If I check for one file, it works. If I check for two, it fails...do tell me if my eyes deceive me. The debugger also claims that I'm doing a JZ, instead of a JE. Either nothing is wrong with the jump instruction, or I'm really inexperienced with this debugger (bochs).

Re: strange debugging results

Posted: Sat Sep 28, 2019 1:49 am
by Octocontrabass
saltlamp wrote:If I check for one file, it works. If I check for two, it fails...
CMPSB changes DI, but you assume it's still zero when you try to move to the next entry.

Re: strange debugging results

Posted: Sat Sep 28, 2019 1:54 am
by saltlamp
Octocontrabass wrote:
saltlamp wrote:If I check for one file, it works. If I check for two, it fails...
CMPSB changes DI, but you assume it's still zero when you try to move to the next entry.
God flipping dang it, I never knew that... So that's why most boot-loader push the DI register... plus it's working! okay, now I know this, and thanks for the help! seriously.

Re: strange debugging results

Posted: Sun Sep 29, 2019 10:33 am
by JAAman
saltlamp wrote:The debugger also claims that I'm doing a JZ, instead of a JE. Either nothing is wrong with the jump instruction, or I'm really inexperienced with this debugger (bochs).
JZ and JE are the same instruction (jump if eFLAGS.Z == 1)

the debugger just sees the opcode, and doesn't know which name you used to create it

JZ (Jump if Zero) is more explicit about what is being checked (the Z, or ZERO, flag)
JE (Jump if Equal) is more natural to use after a CMP

in just the same way, REPZ and REPE are the same instruction, as are REPNZ and REPNE (just depends on whether you want to call it Zero or Equal)