Page 4 of 7
Re: Partially written string literals
Posted: Wed Nov 11, 2015 3:27 pm
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.
Re: Partially written string literals
Posted: Wed Nov 11, 2015 3:43 pm
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.
Re: Partially written string literals
Posted: Wed Nov 11, 2015 3:49 pm
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
Re: Partially written string literals
Posted: Wed Nov 11, 2015 3:50 pm
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.
Re: Partially written string literals
Posted: Wed Nov 11, 2015 3:57 pm
by Stamerlan
Change line 42 from
Code: Select all
mov $0x3, %bh # BH = page number = 0 ; BL = 3 = Cyan (ignored)
to
Re: Partially written string literals
Posted: Wed Nov 11, 2015 4:06 pm
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.
Re: Partially written string literals
Posted: Wed Nov 11, 2015 4:11 pm
by Stamerlan
but %bh - video page (should be 0 not 3)
Re: Partially written string literals
Posted: Wed Nov 11, 2015 4:15 pm
by eisdt
Stamerlan wrote:but %bh - video page (should be 0 not 3)
Yeah, you're right. My bad. Another user spotted that
here typo.
Re: Partially written string literals
Posted: Wed Nov 11, 2015 4:20 pm
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.
Re: Partially written string literals
Posted: Wed Nov 11, 2015 4:23 pm
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)
Re: Partially written string literals
Posted: Wed Nov 11, 2015 4:34 pm
by Stamerlan
Guys look here:
https://bbs.archlinux.org/viewtopic.php?id=189483
Some bioses uses low 64k of memory as a temporary storage.
Re: Partially written string literals
Posted: Wed Nov 11, 2015 4:40 pm
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
Re: Partially written string literals
Posted: Wed Nov 11, 2015 4:43 pm
by Stamerlan
Linux do some checks about it:
http://lxr.free-electrons.com/source/ar ... el/check.c
Great work, intx13!
Happy hacking!
Re: Partially written string literals
Posted: Wed Nov 11, 2015 8:34 pm
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
I kept looking at the code here trying to see the issue - I'm extremely surprised by this answer.
Impressive detective work guys
, now we just need to get this on the WiKi somewhere.
Re: Partially written string literals
Posted: Thu Nov 12, 2015 3:19 am
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
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