Page 1 of 2
Strange trouble while copying kernel to 0x100000
Posted: Thu Jun 30, 2016 2:07 pm
by whellcome
I made a very easy bootloader.
This bootloader loads the kernel from the second sector of a floppy or of an hard disk.
I tested it in bochs(If I remember correctly A20 is already enabled when the bootloader runs)
so I do not have to care if the A20 enabling code is perfect or not
(It is not because it assumes that a word over 0xfffff is 0 (nothing
should accessed to it before.)).
While running it's skipped(I've checked this).
So my bootloader works fine until it copies data(nasm syntax):
Code: Select all
xor ecx,ecx
mov ch,[es:0x200] ;size in sectors of 512 bytes (the first byte is not part of the kernel code is its size).
shl ecx,9 ;size now in bytes
xor dx,dx
call segment_set ;set all the segment registers
mov esi,0x7e01
mov edi,0x100000
rep movsb ;but copies to 0x0 instead of 0x100000
mov dx,0x10 ;data descriptor
call segment_set
lgdt [gdt_descriptor]
mov eax,cr0
or ah,1
mov cr0,eax
jmp 0x8:0x0
Well it jumps to 0x100000 and it executes bytes from 0x100000.
So code is executed looking like A20 it's enabled
but data are not copied like A20 it's enabled because from 0x100000 only
are executed and the desidered code is at 0x0.
Re: Strange trouble while copying kernel to 0x100000
Posted: Thu Jun 30, 2016 2:29 pm
by Combuster
rep movsb ;but copies to 0x0 instead of 0x100000
In 16 bit mode that actually uses cx, si and di instead of their 32-bit variants. The lower 16 bits of edi are of course... zero!
Re: Strange trouble while copying kernel to 0x100000
Posted: Thu Jun 30, 2016 2:40 pm
by whellcome
So how I can enable 32bit mode?
I tried to to execute it while protection was enabled but it didn't worked.
Maybe I haven't read something important on the wiki?
Re: Strange trouble while copying kernel to 0x100000
Posted: Thu Jun 30, 2016 2:44 pm
by SpyderTL
In 16-bit mode, you can set ES to 0xFFFE, and DI to 0x0020. This should start writing at address 0x10000, I believe.
Re: Strange trouble while copying kernel to 0x100000
Posted: Thu Jun 30, 2016 4:55 pm
by BrightLight
Read a DWORD from 0x100000, and read a DWORD from address 0x0000. If they are equal, A20 is not enabled.
In Bochs, QEMU, VirtualBox and most real HW, enabling A20 is easy:
Code: Select all
in al, 0x92
or al, 2
and al, 0xFE
out 0x92, al
Re: Strange trouble while copying kernel to 0x100000
Posted: Thu Jun 30, 2016 11:47 pm
by whellcome
No A20 was enabled because after the far jump cpu executed from 0x100000.
I've seen this with bochs.
The problem was to use:
instead of:
a32 is an override prefix.
But I must admit it doesn't work anyway.
I must check something...
Re: Strange trouble while copying kernel to 0x100000
Posted: Fri Jul 01, 2016 12:16 am
by iansjack
whellcome wrote:No A20 was enabled because after the far jump cpu executed from 0x100000.
How do you know that? Have you checked that the code there is different to the code at 0x0?
Re: Strange trouble while copying kernel to 0x100000
Posted: Fri Jul 01, 2016 12:19 am
by whellcome
Exactely.
Re: Strange trouble while copying kernel to 0x100000
Posted: Fri Jul 01, 2016 12:54 am
by Combuster
There's still quite a bit of curious code choices going on. For instance
Is not the line of code one would expect at that location, and your protected mode segment use seems counter-intuitive as well. So even though you might get the actual copy working, it would be unlikely that you actually get to executing the code you just moved.
Re: Strange trouble while copying kernel to 0x100000
Posted: Fri Jul 01, 2016 1:12 am
by whellcome
Ok.
But I have another problem:
after
has been executed the first time the first kernel byte is not copied at all.
(not copied at 0x0 and not at 0x100000)
Cpu also executes (after a32 rep movsb is executed) from 0xfe9e6(cs = 0xf000 ip=0xe9e6).
Re: Strange trouble while copying kernel to 0x100000
Posted: Fri Jul 01, 2016 1:16 am
by alexfru
omarrx024 wrote:Read a DWORD from 0x100000, and read a DWORD from address 0x0000. If they are equal, A20 is not enabled.
That logic is flawed. You may have the same data in both locations.
Re: Strange trouble while copying kernel to 0x100000
Posted: Fri Jul 01, 2016 2:26 am
by Brendan
Hi,
whellcome wrote:But I have another problem:
after
has been executed the first time the first kernel byte is not copied at all.
(not copied at 0x0 and not at 0x100000)
Cpu also executes (after a32 rep movsb is executed) from 0xfe9e6(cs = 0xf000 ip=0xe9e6).
In real mode; the first time it tries to execute this instruction you'll get a general protection fault because EDI is higher than the segment's limit (0x00100000 > 0x0000FFFF). To fix that, switch to protected mode and load ES with a 32-bit data descriptor (that has "limit = 0xFFFFFFFF"), then copy the kernel.
Cheers,
Brendan
Re: Strange trouble while copying kernel to 0x100000
Posted: Fri Jul 01, 2016 2:40 am
by Combuster
whellcome wrote:Cpu also executes (after a32 rep movsb is executed) from 0xfe9e6(cs = 0xf000 ip=0xe9e6).
If you have bochs, you can look at the logs and you'll see an error that you exceeded the segment limit. The address you're looking at is the location of the BIOS' General Protection Fault handler.
A computer starts up in the mode that mostly resembles 16-bit processors. Several 32-bit things don't work out of the box as a result. Over the whole course of this thread you seem to have a lack of idea how these mechanics work, so I'd suggest taking a step back from the actual code while you read up on
Protected Mode,
Unreal Mode,
Babystep, and
Rolling Your Own Bootloader. Those pages should give you enough background ideas so you can review your design and make the appropriate changes. If you still have implementation issues afterwards, they'll have less fundamental issues, making them easier to solve.
Re: Strange trouble while copying kernel to 0x100000
Posted: Fri Jul 01, 2016 7:05 am
by whellcome
Combuster wrote:There's still quite a bit of curious code choices going on. For instance
Is not the line of code one would expect at that location, and your protected mode segment use seems counter-intuitive as well. So even though you might get the actual copy working, it would be unlikely that you actually get to executing the code you just moved.
So where I should put it?
I thought it was important to enter protected mode.
Re: Strange trouble while copying kernel to 0x100000
Posted: Fri Jul 01, 2016 7:23 am
by Octocontrabass
Setting a reserved bit of CR0 will not enable protected mode.