Page 1 of 2
Alignment problem ?
Posted: Thu Aug 14, 2014 6:11 am
by staringlizard
Hi OSdev,
I started to make a bootloader where I use dap and lba to load my x86-64 kernel.
I bumped into a problem which I believe is about alignment or placement.
I made 4 tests.
When I place the dap at these locations: 0x7d80, 0x7db0, 0x7dc0
gdt pointer at these locations: 0x7d7c, 0x7dac, 0x7dbc
gdt structure at these locations: 0x7d60, 0x7d90, 0x7da0
Everything works.
But when I place the above at these locations:
dap: 0x7dd0
gdt pointer: 0x7dcc
gdt structure: 0x7db0
(So according to 'objdump -d -mi8086 <file>' these three address location are the only difference between working and non-working apart from some some unused code that made the addresses change)
It still works on my laptop, bochs and qemu but crash on one of my desktop computers at this line:
asm volatile("ljmp $0x08, %0" :: "i"(SYSTEM_KERNEL_MEMORY_ADDR));
I have attached the objdump where the problem exist here ->
Is there some magic here that I'm not aware of?
Regards,
StaringL
Re: Alignment problem ?
Posted: Thu Aug 14, 2014 2:50 pm
by jnc100
I think you need to do a bit of investigation with your debugger looking at the data that has been loaded to each address to see what is wrong.
I do note however that you seem to only allocate 4 bytes for the GDT pointer, where it should be 6 bytes (32-bit mode) or 10 bytes (64-bit mode). Perhaps the upper bits are being overwritten by the DAP?
Regards,
John.
Re: Alignment problem ?
Posted: Fri Aug 15, 2014 8:44 am
by staringlizard
Thanks for the answer John ! I have considered it for quite some time.
I do wonder, how you can see how many bytes I allocated for gdt pointer in the attached log?
Could you elaborate on this?
My gdt pointer looks like this:
Code: Select all
typedef struct
{
u16_t limit;
u32_t base;
} __attribute__((packed)) gdt_ptr_t;
&gdtp_p = 0x7dcc
gdtp_p = 0x700
gdtp_p->limit = 0x0017
gdtp_p->base = 0x00007db0
I guess this should be ok, after all this is not x86-64 code. I also tried to add a dummy u32 after the base and set it to 0x0 just to be sure but it did me no good.
The section that I am talking about looks like this:
Code: Select all
7c9d: 66 a1 cc 7d mov 0x7dcc,%eax
7ca1: 67 c7 00 17 00 movw $0x17,(%eax)
7ca6: 67 66 c7 40 02 b0 7d movl $0x7db0,0x2(%eax)
7cad: 00 00
7caf: 67 0f 01 10 lgdtw (%eax)
I have debugged this for several days now but I am not successful. But the bug is in there somewhere...
/Regards
StaringL
Re: Alignment problem ?
Posted: Fri Aug 15, 2014 8:56 am
by jnc100
What are &gdtp_p.limit and &gdtp_p.base and how do these compare with the DAP structure's address?
Regards,
John.
Re: Alignment problem ?
Posted: Fri Aug 15, 2014 12:20 pm
by staringlizard
I remade the code a little bit where I now have the gdtp variable in the mbr instead of outside.
(gdb) print/x dap
$1 = {size = 0x10, dummy = 0x0, no_of_sectors = 0x34, offset = 0x0, segment = 0x800, lbal = 0x2, lbah = 0x0}
(gdb) print/x &dap
$2 = 0x7de0
(gdb) print/x gdt
$3 = {{limit_low = 0x0, base_low = 0x0, base_middle = 0x0, access = 0x0, granularity = 0x0, base_high = 0x0}, {limit_low = 0x0,
base_low = 0x0, base_middle = 0x0, access = 0x98, granularity = 0x20, base_high = 0x0}, {limit_low = 0x0, base_low = 0x0,
base_middle = 0x0, access = 0x90, granularity = 0x0, base_high = 0x0}}
(gdb) print/x &gdt
$4 = 0x7db0
(gdb) print/x gdtp
$5 = {limit = 0x17, base = 0x7db0, dummy = 0x0}
(gdb) print/x &gdtp
$6 = 0x7dc8
logs :
Small note: As I mentioned before the function memory16_discover is not executed. It only acts as padding to expose the problem.
Re: Alignment problem ?
Posted: Sun Aug 17, 2014 10:50 am
by staringlizard
Hi OSdev,
I have found the problem. There seem to be some limitation in the bios for the computer in question (running with mb ASUS P8Z68-V PRO/GEN3 Z68 S-1155 ATX).
It is not possible to store the gdt structure (length in my case is 3*8 byte) at location 0x7db0 or higher. To store it at address 0x7da8 is ok. It does not matter where the actual gdt pointer is stored, nor does it matter where the dap structure is located.
Just wanted to share this. I had no idea that these sort of limitation existed. Perhaps this is Wiki material btw ?
Regards,
StaringL
Re: Alignment problem ?
Posted: Sun Aug 17, 2014 11:39 am
by Combuster
This is a good indication that something else is also using that region. The GDT can technically be placed anywhere in memory, and many people have done so in the past.
Some things that interest me though:
Code: Select all
00007cb7 <sboot16_main>:
7cb7: 66 55 push %ebp
That's an uninitialized use of SS and SP. It also appears that you're using the .code16gcc hack. Changing the stack afterwards makes sure that
Code: Select all
7ceb: 66 c9 leavel
7ced: e9 36 ff jmp 7c26 <sboot16_switch_to_64bit>
accesses something different and trashes the stack
Code: Select all
7d0d: cd 10 int $0x10
7d0f: f4 hlt
hlt with if=1 is nothing but a short delay until the next IRQ fires - which can be anytime. The VGA bios doesn't need any delays so this appears to be a bad idea.
Re: Alignment problem ?
Posted: Sun Aug 17, 2014 1:09 pm
by jnc100
I'm still concerned that in your original post you state that
staringlizard wrote:dap: 0x7dd0
gdt pointer: 0x7dcc
gdt structure: 0x7db0
and given that 0x7dd0 - 0x7dcc = 0x4 then the gdt pointer only reserves 4 bytes for itself (instead of at least 6). As you later state you define this as
staringlizard wrote:Code: Select all
typedef struct
{
u16_t limit;
u32_t base;
} __attribute__((packed)) gdt_ptr_t;
it makes me dubious that your u16_t and u32_t types are the length you think they are. This could lead to all manner of problems, particularly if the code is combined with the use of .code16gcc.
Regards,
John.
Re: Alignment problem ?
Posted: Sun Aug 17, 2014 4:14 pm
by staringlizard
I want to thank you for taking interest in my problem
@John,
The lgdt instruction takes a pointer to the gdtp structure. Pointers are double word in real mode (.code16gcc) so it should be good, right?
Sorry if I got you confused by writing "gdt pointer: 0x7dcc" in my original post. It should have been gdtp pointer.
@Combuster,
You are right, using hlt is not very bright. I will change this to loop instead. That is what I intended.
Forgive me, I am learning x86 instruction set as we speak. The following instruction seems to be a bit of a problem for me in my current situation, as you pointed out.
7ceb: 66 c9 leavel
I will try some more with your comments in mind and get back with some test results.
Regards,
StaringL
Re: Alignment problem ?
Posted: Sun Aug 17, 2014 5:11 pm
by staringlizard
I have attached a new version here:
But I get the same problem. E.g. if have gdt structure on 0x7db0 or higher (
edit: I only try addresses that are within the limits of the mbr atm) it will crash on this particular computer.
/Regards,
StaringL
Re: Alignment problem ?
Posted: Sun Aug 17, 2014 6:24 pm
by FallenAvatar
What does the memory map look like on this computer that is giving you issues?
- Monk
Re: Alignment problem ?
Posted: Sun Aug 17, 2014 11:24 pm
by jnc100
staringlizard wrote:@John,
The lgdt instruction takes a pointer to the gdtp structure. Pointers are double word in real mode (.code16gcc) so it should be good, right?
Sorry if I got you confused by writing "gdt pointer: 0x7dcc" in my original post. It should have been gdtp pointer.
Generally you'd do something like (NASM syntax):
Code: Select all
lgdt [gdtinfo]
gdtinfo:
dw gdtend - gdt - 1
dd gdt
gdt:
descriptors
gdtend:
Which would assemble to 0f 01 16 disp16, as indeed it does in your latest disassembly (offset 0x1x8), but the actual pointer itself as defined in memory should still be 6 bytes long. Also, the GDT seems wrong in your current disassembly (it starts at offset 0x1b0 if the pointer is to be believed) in that all the segment limits are set to 0.
Regards,
John.
Re: Alignment problem ?
Posted: Mon Aug 18, 2014 2:15 am
by staringlizard
jnc100 wrote:staringlizard wrote:
gdtend:[/code]Which would assemble to 0f 01 16 disp16, as indeed it does in your latest disassembly (offset 0x1x8), but the actual pointer itself as defined in memory should still be 6 bytes long. Also, the GDT seems wrong in your current disassembly (it starts at offset 0x1b0 if the pointer is to be believed) in that all the segment limits are set to 0.
The gdt starts at offset 0x1b0 (e.g. 0x7db0 in memory). As you know it will start with a null gdt entry:
00 00 00 00 00 00 00 00
Then a code entry:
00 00 00 00 00 98 20 00
Then the data entry:
00 00 00 00 00 90 00 00
The gdtp you can see is loaded here:
lgdtw 0x7dc8
and if you look in the raw dump you can see that this pointer represents this memory (offset 0x1c8):
17 00 b0 7d 00 00 00 00 00 00
Where 17 00 is the size in Little-Endian (16 bit) and b0 7d 00 00 00 00 00 00 (64 bit) is the pointer to the gdt in Little-Endian.
This looks OK to me.
Regards,
StaringL
Re: Alignment problem ?
Posted: Mon Aug 18, 2014 2:36 am
by staringlizard
tjmonk15 wrote:What does the memory map look like on this computer that is giving you issues?
- Monk
Hi Monk,
Here is the memory layout as reported from BIOS.
/Regards,
StaringL
Re: Alignment problem ?
Posted: Mon Aug 18, 2014 4:23 am
by Icee
staringlizard wrote:Then a code entry:
00 00 00 00 00 98 20 00
Then the data entry:
00 00 00 00 00 90 00 00
These two descriptors define segments with 0 limit. Also, I don't see you setting the D bit on code segment: is this intentional, i.e. are you going to execute 16-bit protected code afterwards?