Page 1 of 1

Strange code shift when booting with Grub

Posted: Fri Feb 14, 2014 4:00 am
by Oroszlan
Hello everyone

This is the first time I post on this forum, pardon me if this is a noob question :D

Iv'e got a very tiny OS that boots with Grub in 64 bits mode, with higher-half paging enabled, inspired by this : http://wiki.osdev.org/64-bit_Higher_Hal ... ith_GRUB_2
You can see most of my code here : https://github.com/LeoTestard/Quasar/tr ... 7c052d4f86
The main difference is that my kernel is written in Rust instead of C. I think the interesting parts for this problem are the loader (arch/x86_64/boot/loader.s), and the linker script (linker.ld).

When booting with Grub, I notice something strange, the location where my Rust code (the .text section) is loaded in memory is 8 octets higher from where it should be :

Code: Select all

(qemu) x/32hb 0xFFFFFFFF8010C000
ffffffff8010c000: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
ffffffff8010c008: 0x64 0x48 0x3b 0x24 0x25 0x70 0x00 0x00
ffffffff8010c010: 0x00 0x77 0x1a 0x49 0xba 0x08 0x00 0x00
ffffffff8010c018: 0x00 0x00 0x00 0x00 0x00 0x49 0xbb 0x00
Whereas in the binary :

Code: Select all

ffffffff8010c000 <main>:
ffffffff8010c000:	64 48 3b 24 25 70 00 	cmp    %fs:0x70,%rsp
The .boot section, however, is loaded at the right position... I don't think the problem concerns my virtual memory mappings, since the shift is present even when I ask Qemu to show memory at the physical adress using xp. I have no idea of what happens here. Is Grub loading my program at the wrong location ?

I didn't notice this problem initially because the 8 octets that were located before the code of main where zeroes, so main was run just fine. But now, I have another function located just before it, and jumping to main jumps in fact... to the return of that function, and this prevents my OS to boot. :/

Thanks for your help

Re: Strange code shift when booting with Grub

Posted: Fri Feb 14, 2014 5:25 am
by jnc100
What do the program headers in the kernel binary look like? You can inspect these with objdump or readelf.

Regards,
John.

Re: Strange code shift when booting with Grub

Posted: Fri Feb 14, 2014 5:30 am
by Oroszlan
Hello

Here are the headers of the main binary, printed by objdump --all-headers

Code: Select all

quasar.img:     format de fichier elf64-x86-64
quasar.img
architecture: i386:x86-64, fanions 0x00000012:
EXEC_P, HAS_SYMS
adresse de départ 0x000000000010003c

En-tête de programme:
    LOAD off    0x00000000000000e8 vaddr 0x0000000000100000 paddr 0x0000000000100000 align 2**3
         filesz 0x000000000000c000 memsz 0x000000000000c000 flags r--
    LOAD off    0x000000000000c0f0 vaddr 0xffffffff8010c000 paddr 0x000000000010c000 align 2**4
         filesz 0x00000000000000e0 memsz 0x0000000000001009 flags rwx
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rwx

Sections:
Idx Nom           Taille    VMA               LMA               Fich off  Algn
  0 .boot         0000c000  0000000000100000  0000000000100000  000000e8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .text         000000a2  ffffffff8010c000  000000000010c000  0000c0f0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .data.rel.local 00000030  ffffffff8010c0b0  000000000010c0b0  0000c1a0  2**4
                  CONTENTS, ALLOC, LOAD, DATA
  3 .bss          00000009  ffffffff8010d000  000000000010d000  0000c1d0  2**3
                  ALLOC
SYMBOL TABLE:
0000000000100000 l    d  .boot	0000000000000000 .boot
ffffffff8010c000 l    d  .text	0000000000000000 .text
ffffffff8010c0b0 l    d  .data.rel.local	0000000000000000 .data.rel.local
ffffffff8010d000 l    d  .bss	0000000000000000 .bss
0000000000000000 l    df *ABS*	0000000000000000 loader.s
0000000000100000 l       .boot	0000000000000000 _hdr_start
000000000010003c l       .boot	0000000000000000 _hdr_end
000000000010004c l       .boot	0000000000000000 entry_point.gdt_ready
0000000000100073 l       .boot	0000000000000000 entry_point.gdt2_ready
00000000001000a5 l       .boot	0000000000000000 setup_long_mode
000000000010011c l       .boot	0000000000000000 tmp_gdt
000000000010014c l       .boot	0000000000000000 gdtr1
0000000000100152 l       .boot	0000000000000000 gdtr2
000000000010015c l       .boot	0000000000000000 gdtr3
0000000000000000 l    df *ABS*	0000000000000000 entry.rc
ffffffff8010d000 l     O .bss	0000000000000001 _crate_map_child_vectors
ffffffff8010d008 l     O .bss	0000000000000001 _rust_mod_map
0000000000000000 l    df *ABS*	0000000000000000
000000000010003c g       .boot	0000000000000000 _load_start
ffffffff8010c0b0 g     O .data.rel.local	0000000000000030 _ZN21_rust_crate_map_entry65_6be44700bf48f47130173b5614f178245343aa890d78bd6f4c96db58f9969b694v0.0E
000000000010c0e0 g       *ABS*	0000000000000000 _load_end
000000000010c000 g       .boot	0000000000000000 stack
000000000010d009 g       *ABS*	0000000000000000 _bss_end
ffffffff80000000 g       *ABS*	0000000000000000 VIRT_BASE
ffffffff8010c000 g     F .text	00000000000000a2 main
0000000000103000 g       .boot	0000000000000000 pagedir
0000000000102000 g       .boot	0000000000000000 pdpt
0000000000101000 g       .boot	0000000000000000 pml4
00000000001000a4 g       .boot	0000000000000000 __morestack
000000000010003c g       .boot	0000000000000000 entry_point
I really fail to see what's going wrong here... All the adresses look ok to me

Re: Strange code shift when booting with Grub

Posted: Fri Feb 14, 2014 7:53 am
by sortie
Hi Oroszlan, I'm not carefully following this thread, but I noticed your output is not in English. You'll want to switch the current locale when generating diagnostic output you submit here. You can do that per-shell in the future by typing:

Code: Select all

export LC_ALL=C          # Or perhaps LC_ALL=en_US.UTF-8 is better?
That should work assuming a standard Unix shell and a sufficiently Unix-like environment. All commands you use following that in the shell will then use English. This helps people that don't speak your language help you.