Page 1 of 1

boot-sector relocation not working [SOLVED]

Posted: Tue Sep 24, 2019 1:33 am
by saltlamp
Hi, I am having trouble trying to make my boot-sector relocation code work. The code:

Code: Select all

BIOSSEG	EQU 07C0H
BOOTSEG	EQU 0AE0H
LOADSEG	EQU 0050H

; ...
;
; Copy boot-sector to higher memory.
;

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, 512
	XOR  SI, SI	; DS:SI should be 07C0:0
	XOR  DI, DI	; ES:DI should be 0AE0:0
	CLD
	REP  MOVSB

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

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


;
; DISKERROR:	Display and error message, and
;		and await a system reset.
;

DSKERR:
	LEA  SI, [ERRMSG]
PRNSTR:
	LODSB
	OR   AL, 0
	JZ   SHORT DSKHLT
	MOV  AH, 14
	MOV  BL, 0
	JMP  SHORT PRNSTR
DSKHLT:
        XOR  AX, AX	; ! 'Restart' the PC-BIOS. !
        INT  22		; 16H
        INT  25		; 19H

;
; FINDFILE:	Search for the files 'IO.SYS'
;		and 'RMDOS.SYS'.
;
; Read the Root Directory into memory:
;

FNDFLE:
	MOV  AH, 14
	MOV  AL, '2'
	INT  16
	JMP  SHORT $
...
'FNDFLE' just contains dummy code to see if the jump worked. And I tried jumping to 'DSKERR' to makesure that the memory is correct, and DS:SI was not off.

The only thing that I can think off, after trying zero segments and with quite a number of attempts of retrying different ways, is that the pushing and popping with the segment registers is not correct, and that I should probably use the move instruction. That, or I am forgetting some other registers or something.

Anyway, just thought I'd ask. Thanks for any help :)

Re: boot-sector relocation not working

Posted: Tue Sep 24, 2019 2:19 am
by Octocontrabass
saltlamp wrote:'FNDFLE' just contains dummy code to see if the jump worked.
Are you sure the dummy code works? (Hint: BX is also an input to that particular BIOS function.)

Re: boot-sector relocation not working

Posted: Tue Sep 24, 2019 9:38 am
by MichaelPetch
The code you show that does the copy appears correct. Are you testing this on real hardware (like booting with USB?) or does this fail in an emulator or VM (Qemu, BOCHS, vbox, VMWare, etc)?

Re: boot-sector relocation not working

Posted: Tue Sep 24, 2019 11:31 am
by saltlamp
Octocontrabass wrote:
saltlamp wrote:'FNDFLE' just contains dummy code to see if the jump worked.
Are you sure the dummy code works? (Hint: BX is also an input to that particular BIOS function.)
True, true. To be sure, I just trued setting BX to 7 for first page and for the color white, it didn't do anything.

It also works if I don't perform the jump, it works perfectly, so idefk

Re: boot-sector relocation not working

Posted: Tue Sep 24, 2019 11:36 am
by saltlamp
MichaelPetch wrote:The code you show that does the copy appears correct. Are you testing this on real hardware (like booting with USB?) or does this fail in an emulator or VM (Qemu, BOCHS, vbox, VMWare, etc)?
I'm testing on virtualbox, and I'm booting from a floppy-disk.

Re: boot-sector relocation not working

Posted: Tue Sep 24, 2019 11:46 am
by MichaelPetch
Can you show us the complete code for this boot sector? I took your code, commented out the `LEA` instruction (since you didn't have the error message in your file), and then padded the disk to 510 bytes and wrote 0xaa55 for the disk signature. When I booted it as a floppy image in VirtualBox it printed `2` on the screen.

Re: boot-sector relocation not working

Posted: Tue Sep 24, 2019 11:04 pm
by saltlamp
MichaelPetch wrote:Can you show us the complete code for this boot sector? I took your code, commented out the `LEA` instruction (since you didn't have the error message in your file), and then padded the disk to 510 bytes and wrote 0xaa55 for the disk signature. When I booted it as a floppy image in VirtualBox it printed `2` on the screen.
Sure thing. Here is the rest:

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. 

	USE16
	ORG 7C00H

        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:

;
; POSTBIOS:	Ensure that all segment registers
;		are set to known values.
;
; Copy boot-sector to higher memory.
;

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
	XOR  SI, SI	; DS:SI should be 07C0:0
	XOR  DI, DI	; ES:DI should be 0AE0:0
	MOV  CX, 256
	CLD
	REP  MOVSW

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

SAVSRS:
	PUSH ES		; We no longer need ES, so
	POP  DS		; DS now becomes 0AE0.
RSTCPU:
	PUSH BOOTSEG
	PUSH WORD DSKERR
	RETF		; 0000:AE00+<FNDFLE>


;
; DISKERROR:	Display and error message, and
;		and await a system reset.
;

DSKERR:
	LEA  SI, [ERRMSG]
PRNSTR:
	LODSB
	OR   AL, 0
	JZ   SHORT DSKHLT
	MOV  AH, 14
	MOV  BL, 0
	JMP  SHORT PRNSTR
DSKHLT:
        XOR  AX, AX	; ! 'Restart' the PC-BIOS. !
        INT  22		; 16H
        INT  25		; 19H

;
; FINDFILE:	Search for the files 'IO.SYS'
;		and 'RMDOS.SYS'.
;
; Read the Root Directory into memory:
;

FNDFLE:
	MOV  BX, 7
	MOV  AH, 14
	MOV  AL, '2'
	INT  16
	JMP  SHORT $
	
	MOV  AX, 19
	LEA  BX, [DSKBUF]	; BX=7E00
	MOV  CX, 1
	XOR  DX, DX
	ADC  DX, 0
FNDSYS:
	JNE  DSKERR
FDNDOS:
	JNE  DSKERR


;
; READFILE:	Partially read the file
;		'IO.SYS' into memory.
;
; Read the FAT into memory:
;

REDFLE:
NXTCLU:
CLUODD:
REDNXT:
	JMP  NXTCLU

; Transfer CPU execution to io.sys
;
RUNDOS:
        PUSH  CS
        PUSH  WORD LOADSEG
	RETF


;
; 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
        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.
DSKBUF:

;
; The FAT and Root-Dir is read exactly
; after the boot-sector.
;

Re: boot-sector relocation not working

Posted: Tue Sep 24, 2019 11:25 pm
by saltlamp
Okay, I just tried it in VMWare, and it did not do anything helpful, so I don't think it's the vm's fault, honestly. I just cannot figure out where in my code that I may screwing up at, sadly.

Re: boot-sector relocation not working

Posted: Wed Sep 25, 2019 1:36 am
by Octocontrabass

Code: Select all

ORG 7C00H
You're telling the assembler that it should assume everything will be located starting at offset 0x7C00 in whichever segment.

Then all of your code assumes everything will be located starting at offset 0 in whichever segment.

Things should work a bit better once you tell the assembler what you're actually doing.

Re: boot-sector relocation not working

Posted: Wed Sep 25, 2019 10:40 am
by saltlamp
Octocontrabass wrote:

Code: Select all

ORG 7C00H
You're telling the assembler that it should assume everything will be located starting at offset 0x7C00 in whichever segment.

Then all of your code assumes everything will be located starting at offset 0 in whichever segment.

Things should work a bit better once you tell the assembler what you're actually doing.
I've tried it with the following, and still nothing works.

Code: Select all

ORG 7C00H

Code: Select all

ORG 0AE00H

Code: Select all

ORG 0

Code: Select all

ORG 7C0H

Code: Select all

ORG 0AE0H

Code: Select all

ORG 0

Code: Select all

// no org
What do you suggest?

Re: boot-sector relocation not working

Posted: Wed Sep 25, 2019 12:18 pm
by linguofreak
You have at one point:

Code: Select all

   PUSH WORD BIOSSEG
   POP  DS
and later on:

Code: Select all

RSTCPU:
   PUSH BOOTSEG
   PUSH WORD FNDFLE
   RETF
It's possible that your assembler is interpreting "PUSH BOOTSEG" as "PUSH BYTE BOOTSEG" (in other words "PUSH BYTE 0AE0h"), and instead of barfing on "PUSH BYTE" followed by a 16-bit constant, or reinterpreting it as "PUSH WORD 0AE0h", it's just truncating 0AE0h to the byte E0h and pushing that.

Re: boot-sector relocation not working

Posted: Wed Sep 25, 2019 12:31 pm
by saltlamp
linguofreak wrote:You have at one point:

Code: Select all

   PUSH WORD BIOSSEG
   POP  DS
and later on:

Code: Select all

RSTCPU:
   PUSH BOOTSEG
   PUSH WORD FNDFLE
   RETF
It's possible that your assembler is interpreting "PUSH BOOTSEG" as "PUSH BYTE BOOTSEG" (in other words "PUSH BYTE 0AE0h"), and instead of barfing on "PUSH BYTE" followed by a 16-bit constant, or reinterpreting it as "PUSH WORD 0AE0h", it's just truncating 0AE0h to the byte E0h and pushing that.
Hey, thanks for the reply!! I just tried what you mentioned, ensuring that everything on the stack is word-aligned ("PUSH WORD BOOTSEG", and any other thing on the stack), but nothing happened, unfortunately

Re: boot-sector relocation not working [SOLVED]

Posted: Wed Sep 25, 2019 1:05 pm
by saltlamp
Good news, everyone! I fixed the problem!

I was running the bochs debugger as my last resort before scrapping this boot-sector. And then I found, in the 'DSKERR' routine, I forgot to add 'int 13h/16'. :shock: :oops:

After doing that, I made a test to another function, and it works perfectly. thanks to anyone who tried to help, though, I really appreciate the help.