[SOLVED] Partially written string literals

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
eisdt
Member
Member
Posts: 31
Joined: Sat Nov 07, 2015 9:58 am
Location: Italy

Re: Partially written string literals

Post by eisdt »

Stamerlan wrote: On my machine bios don't touch anything in memory and code executed well.
What BIOS do you have, if I may ask?
intx13 wrote: If I get a chance later I'll write something that will read the MBR out of memory and write it back to the drive and we can see exactly what's happening.
I would love to see that.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Partially written string literals

Post by Brendan »

Hi,
intx13 wrote:
Stamerlan wrote: 2intx13 Did u find any docs where this bios behavior is described? On my machine bios don't touch anything in memory and code executed well.
If I get a chance later I'll write something that will read the MBR out of memory and write it back to the drive and we can see exactly what's happening.
I was thinking of something like this:

Code: Select all

    org 0x7C00

    jmp start

testArea1:
    times 200 db '.'

start:
    xor ax,ax
    mov ss,ax
    mov sp,ax
    mov ds,ax
    cld

    mov si,testArea1
    mov bp,start
    call doArea

    mov si,testArea2
    mov bp,end
    call doArea

.die:
    jmp .die


doArea:
    mov bx,0x0007
    mov ah,0x0E
.next:
    lodsb
    pusha
    int 0x10
    popa
    cmp si,bp
    jb .next
    ret

testArea2:
    times 510-($-$$) db '.'
end:
    dw 0xAA55
The theory is that it should print lots of '.' characters and nothing else; and you can adjust the number of characters in the first area if it crashes. If it doesn't just display '.' characters you'd be able to count the number of dots actually displayed to determine the effected address.

I just tested this, and it works fine in Bochs. :)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
eisdt
Member
Member
Posts: 31
Joined: Sat Nov 07, 2015 9:58 am
Location: Italy

Re: Partially written string literals

Post by eisdt »

Solved

Writing straight to the VGA display address worked exquisitely! :D Although this only addresses the problem of printing out messages, instead of the surrounding problem.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

eisdt wrote:Solved

Writing straight to the VGA display address worked exquisitely! :D Although this only addresses the problem of printing out messages, instead of the surrounding problem.
Well if it's a buggy INT10H implementation, yes, that's the solution. But if Brendan is right then that's not the solution, instead you should jump over the offending section (you can still use direct writing to VGA memory though).

I wrote the "copy MBR back to disk" and it works fine on QEMU, but what do you know, it doesn't write anything when running on the problem laptop, even when I know (by printouts) that it's calling INT13H. I'll try Brendan's approach next.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

Ok, I implemented something similar to Brendan's approach and it seems that bytes 0x7C18 through 0x7C1B (inclusive) are overwritten with non-printable bytes. Nothing else (in the first 400 bytes anyway) is modified.
User avatar
BASICFreak
Member
Member
Posts: 284
Joined: Fri Jan 16, 2009 8:34 pm
Location: Louisiana, USA

Re: Partially written string literals

Post by BASICFreak »

So BIOS is writing WORD [BPB_Physical sectors per track] and WORD [BPB_Number of heads]? Is it valid data for these fields?

It actually makes some sense, does this affect MBR or VBR or both?
BOS Source Thanks to GitHub
BOS Expanded Commentary
Both under active development!
Sortie wrote:
  • Don't play the role of an operating systems developer, be one.
  • Be truly afraid of undefined [behavior].
  • Your operating system should be itself, not fight what it is.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

BASICFreak wrote:So BIOS is writing WORD [BPB_Physical sectors per track] and WORD [BPB_Number of heads]? Is it valid data for these fields?

It actually makes some since, does this affect MBR or VBR or both?
I missed one, it's also overwriting one byte at 7C20.

I will try to get the values dumped here in a few minutes.
User avatar
BASICFreak
Member
Member
Posts: 284
Joined: Fri Jan 16, 2009 8:34 pm
Location: Louisiana, USA

Re: Partially written string literals

Post by BASICFreak »

intx13 wrote:
BASICFreak wrote:So BIOS is writing WORD [BPB_Physical sectors per track] and WORD [BPB_Number of heads]? Is it valid data for these fields?

It actually makes some since, does this affect MBR or VBR or both?
I missed one, it's also overwriting one byte at 7C20.

I will try to get the values dumped here in a few minutes.
Only one byte at offset 0x20? If it effects here it should be a DWORD as this is the [BPB_Large total logical sectors] area.
BOS Source Thanks to GitHub
BOS Expanded Commentary
Both under active development!
Sortie wrote:
  • Don't play the role of an operating systems developer, be one.
  • Be truly afraid of undefined [behavior].
  • Your operating system should be itself, not fight what it is.
Stamerlan
Member
Member
Posts: 25
Joined: Thu Nov 05, 2015 8:59 am
Location: Minsk, Belarus

Re: Partially written string literals

Post by Stamerlan »

2intx13 It's strange it changes Physical sectors per track (word at 0x7C18) and Number of heads (word at 0x7C1A) only.
I missed one, it's also overwriting one byte at 7C20.
I don't believe it's BPB it's very strange if it fixes only some parameters and don't touch another.
0x7C20: DWORD Large total logical sectors

2eisdt
What BIOS do you have, if I may ask?
American Megatrends Inc. Version: A06. It's laptop dell inspiron 3542

Have a nice day!
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

That's what I get for rushing - I got the offsets right, but calculated from 0x7C00, not the start of the "." filled area. Disregard my previous post, refer to this one instead.

Here are the offending bytes:

...
0x7C1C: 0x00
0x7C1D: 0x00
0x7C1E: 0x00
0x7C1F: 0x00
...
0x7C24: 0x00
...
Stamerlan
Member
Member
Posts: 25
Joined: Thu Nov 05, 2015 8:59 am
Location: Minsk, Belarus

Re: Partially written string literals

Post by Stamerlan »

That's what I get for rushing - I got the offsets right, but calculated from 0x7C00, not the start of the "." filled area. Disregard my previous post, refer to this one instead.

Here are the offending bytes:

...
0x7C1C: 0x00
0x7C1D: 0x00
0x7C1E: 0x00
0x7C1F: 0x00
...
0x7C24: 0x00
...
0x7C24 - BYTE Physical drive number - for hard disks it should be 0x80+
0x7C20 - DWORD Large total logical sectors - it shouldn't be 0.

I don't think it's BPB and I can find any docs about using this area
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Partially written string literals

Post by Brendan »

Hi,
Stamerlan wrote:
That's what I get for rushing - I got the offsets right, but calculated from 0x7C00, not the start of the "." filled area. Disregard my previous post, refer to this one instead.

Here are the offending bytes:

...
0x7C1C: 0x00
0x7C1D: 0x00
0x7C1E: 0x00
0x7C1F: 0x00
...
0x7C24: 0x00
...
0x7C24 - BYTE Physical drive number - for hard disks it should be 0x80+
0x7C20 - DWORD Large total logical sectors - it shouldn't be 0.

I don't think it's BPB and I can find any docs about using this area
I have the opposite problem - there's so many different versions of the BPB that it's hard to figure out which one the firmware might think it's using.

For one "nice" example, there's an interesting note on Wikipedia for "DOS 3.31 BPB" offset 0x01C that says:
Wikipedia wrote:Count of hidden sectors preceding the partition that contains this FAT volume. This field should always be zero on media that are not partitioned.[5][6][7] This DOS 3.31 entry is incompatible with a similar entry at offset 0x01C in DOS 3.0-3.3 BPBs. At least, it can be trusted if it holds zero, or if the logical sectors entry at offset 0x013 is zero.

If this belongs to an Advanced Active Partition (AAP) selected at boot time, the BPB entry will be dynamically updated by the enhanced MBR to reflect the "relative sectors" value in the partition table, stored at offset 0x1B6 in the AAP or NEWLDR MBR, so that it becomes possible to boot the operating system from EBRs.

(Some GPT boot loaders (like BootDuet) use boot sector offsets 0x1FA–0x1FD to store the high 4 bytes of a 64-bit hidden sectors value for volumes located outside the first 232-1 sectors.)
On the same page (lower down) in the "Extended BIOS Paramater Block" section, for offset 0x24 it says:
Wikipedia wrote:Physical drive number (0x00 for (first) removable media, 0x80 for (first) fixed disk as per INT 13h). Allowed values for possible physical drives depending on BIOS are 0x00-0x7E and 0x80-0xFE. Values 0x7F and 0xFF are reserved for internal purposes such as remote or ROM boot and should never occur on disk. Some boot loaders such as the MS-DOS/PC DOS boot loader use this value when loading the operating system, others ignore it altogether or use the drive number provided in the DL register by the underlying boot loader (e.g., with many BIOSes and MBRs). The entry is sometimes changed by SYS tools or it can be dynamically fixed up by the prior bootstrap loader in order to force the boot sector code to load the operating system from alternative physical disks than the default.

A similar entry existed (only) in DOS 3.2 to 3.31 boot sectors at sector offset 0x1FD.

If this belongs to a boot volume, the DR-DOS 7.07 enhanced MBR can be configured (see NEWLDR offset 0x014) to dynamically update this EBPB entry to the DL value provided at boot time or the value stored in the partition table. This enables booting off alternative drives, even when the VBR code ignores the DL value.
I think the next step might be to add a "valid looking" BPB or partition table, and see if that's enough to convince firmware to stop trashing your data.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Stamerlan
Member
Member
Posts: 25
Joined: Thu Nov 05, 2015 8:59 am
Location: Minsk, Belarus

Re: Partially written string literals

Post by Stamerlan »

Hi,

When memory is corrupted? After loading boot sector to memory or after invoking int 0x10?

Have a nice day!
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

Stamerlan wrote:Hi,

When memory is corrupted? After loading boot sector to memory or after invoking int 0x10?

Have a nice day!
It sounds like after invoking INT10H, since:
eisdt wrote:Solved

Writing straight to the VGA display address worked exquisitely! :D Although this only addresses the problem of printing out messages, instead of the surrounding problem.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Partially written string literals

Post by Brendan »

Hi,
intx13 wrote:
Stamerlan wrote:When memory is corrupted? After loading boot sector to memory or after invoking int 0x10?
It sounds like after invoking INT10H, since:
eisdt wrote:Writing straight to the VGA display address worked exquisitely! :D Although this only addresses the problem of printing out messages, instead of the surrounding problem.
If changing the code (to make it write directly to display memory instead of using "int 0x10") causes the symptoms to disappear; then you'd have to find out if the symptoms disappeared because the code was changed (e.g. the byte/s being corrupted aren't being used for anything important anymore), or if the symptoms disappeared because "int 0x10" isn't being used.

Mostly I'd want to do another "display the sector as dots on the screen" test that writes to display memory without using "int 0x10" to avoid making false assumptions.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply