[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 »

I might have found a clue: reading http://wiki.osdev.org/Boot_Sequence

Code: Select all

(However, some BIOS' load to 0x7c0:0x0000 (segment 0x07c0, offset 0), which resolves to the same physical address, but can be surprising. A good practice is to enforce CS:IP at the very start of your boot sector.)
Indeed, Linux (used to) use that address for its bootsector (source). I actually put the text section at 0x7C00 with ld.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

eisdt wrote:I might have found a clue: reading http://wiki.osdev.org/Boot_Sequence

Code: Select all

(However, some BIOS' load to 0x7c0:0x0000 (segment 0x07c0, offset 0), which resolves to the same physical address, but can be surprising. A good practice is to enforce CS:IP at the very start of your boot sector.)
Indeed, Linux (used to) use that address for its bootsector (source). I actually put the text section at 0x7C00 with ld.
No, you've done it right. Your bootloader performs a long jump to 0000:asmain right away, forcing CS and adjusting IP. Additionally, that would screw up all your memory references if it were wrong.

The problem has something to do with the location of the call in your bootloader. For example, if you wrap the first call to PrintRegister in a loop, it will happily print 0xDEAD over and over. If you delete a few instructions up above you can squeeze in another call to PrintRegister as well. But if the call is located too far into memory, it fails. I'm guessing something is overwriting part of your bootloader code in memory. At first I thought it was the stack, but I moved it around and still the same problem.
Stamerlan
Member
Member
Posts: 25
Joined: Thu Nov 05, 2015 8:59 am
Location: Minsk, Belarus

Re: Partially written string literals

Post by Stamerlan »

I have no idea but may be try to disable interrupts?

P.S. And try to reset values of unused registers before int 0x10 - maybe some vendor-specific function is called like that http://www.delorie.com/djgpp/doc/rbinter/id/12/1.html
Last edited by Stamerlan on Wed Nov 11, 2015 3:51 pm, edited 1 time in total.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

I think this illustrates the problem better: http://pastebin.com/eyxqyxeF

In QEMU, all four calls to PrintRegister take place. On the problematic laptops, only the first three seem to happen.
Stamerlan
Member
Member
Posts: 25
Joined: Thu Nov 05, 2015 8:59 am
Location: Minsk, Belarus

Re: Partially written string literals

Post by Stamerlan »

Change line 42 from

Code: Select all

       mov $0x3, %bh # BH = page number = 0 ; BL = 3 = Cyan (ignored)
to

Code: Select all

       movw $0x7, %bx
eisdt
Member
Member
Posts: 31
Joined: Sat Nov 07, 2015 9:58 am
Location: Italy

Re: Partially written string literals

Post by eisdt »

intx13 wrote:I think this illustrates the problem better: http://pastebin.com/eyxqyxeF

In QEMU, all four calls to PrintRegister take place. On the problematic laptops, only the first three seem to happen.
I've experienced the same issue.
intx13 wrote: I'm guessing something is overwriting part of your bootloader code in memory. At first I thought it was the stack, but I moved it around and still the same problem.
Or, perhaps, the code is overflowing the 512 bytes? However the adjacent area should be free for use...
Stamerlan wrote:Change line 42 from
No difference. Colors are ignored in text mode.
Stamerlan
Member
Member
Posts: 25
Joined: Thu Nov 05, 2015 8:59 am
Location: Minsk, Belarus

Re: Partially written string literals

Post by Stamerlan »

but %bh - video page (should be 0 not 3)
Last edited by Stamerlan on Wed Nov 11, 2015 4:20 pm, edited 2 times in total.
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:but %bh - video page (should be 0 not 3)
Yeah, you're right. My bad. Another user spotted thathere typo.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

Here's the simplest I could reduce the problem to: http://pastebin.com/eS5bFdiv

Adjust the number of nops to effect the problem. No nops and it works fine. 4 nops and it prints out two exclamation points and hangs.
15 nops and it doesn't print anything. There's another number that will make it print repeatedly for maybe 10 seconds, then start printing a different character and then hang, but I forget how many.

This code doesn't use your print function, doesn't do anything but call int 0x13 repeatedly, so it would seem that BIOS is touching memory it shouldn't.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

eisdt wrote:
Stamerlan wrote: P.S. Which BIOS version do u have?
American Megatrends, revision 4.6.
FYI the system I'm reproducing the problem on is running American Megatrends UEFI 2.15 (in CSM)
Stamerlan
Member
Member
Posts: 25
Joined: Thu Nov 05, 2015 8:59 am
Location: Minsk, Belarus

Re: Partially written string literals

Post by Stamerlan »

Guys look here: https://bbs.archlinux.org/viewtopic.php?id=189483

Some bioses uses low 64k of memory as a temporary storage.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Partially written string literals

Post by intx13 »

Corrupted low memory at ffff880000007e60 (7e60 phys) = 380000a2f0
Memory corruption detected in low memory
http://askubuntu.com/questions/183922/s ... -around-it
The whole computer is brand new, only like two weeks old. I am having different times computer freezes, and have the error that came from the log viewer:

AMI BIOS detected: BIOS may corrupt low RAM, working around it.
Well, there you go I guess. What kind of junky BIOS uses 7C00-7E00 for scratch space though?!

eisdt, your options moving forward are:
  • Relocate your code after boot to somewhere safe
  • Don't use those offending interrupts until you're executing somewhere else
  • Don't use that PC ;)
Stamerlan
Member
Member
Posts: 25
Joined: Thu Nov 05, 2015 8:59 am
Location: Minsk, Belarus

Re: Partially written string literals

Post by Stamerlan »

Linux do some checks about it: http://lxr.free-electrons.com/source/ar ... el/check.c

Great work, intx13!

Happy hacking! ;)
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 »

Wow, now I have to fix all my boot loaders. I would have never thought a BIOS would use the boot code area :shock:

I kept looking at the code here trying to see the issue - I'm extremely surprised by this answer.

Impressive detective work guys =D>, now we just need to get this on the WiKi somewhere.
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.
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,
BASICFreak wrote:Wow, now I have to fix all my boot loaders. I would have never thought a BIOS would use the boot code area :shock:
I wouldn't bother.

If you look at the comments in Linux you see this:

Code: Select all

/*
 * Some BIOSes seem to corrupt the low 64k of memory during events
 * like suspend/resume and unplugging an HDMI cable.  Reserve all
 * remaining free memory in that area and fill it with a distinct
 * pattern.
 */
For a normal boot loader, you can guarantee the OS isn't doing suspend or resume, and the chance of the user plugging in or removing a HDMI cable while booting is almost zero. I doubt any of the boot loaders for Linux guard against this either.

A kernel might want to guard against this; but a kernel isn't a boot loader; and I suspect that you could create a copy of the area before suspend and check it after resume; and there's no reason to avoid the RAM itself during normal operation.


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