elf file format

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.
Post Reply
Brill

elf file format

Post by Brill »

Hi, i've been trying to create a simple exec file for grub to load to get some idea that at least something can run when grub loads. then build on from it.
So, there's two questions here.
First, i've been told in the past (on this board in fact) that grub does the switch to pmode. If what is the state of the machine when it jumps to the os. Grub manuals, as far as i can tell, don't say anything about pmode or what the machine is like at os loading.
Secondly, i get the error message in ld:
kernel.o: In function `_start':
kernel.o(.text+0x8): relocation truncated to fit: R_386_16 .text
What does this mean? Currently my kernel, if you could call it that, looks like this:

[BITS 32]
[GLOBAL _start]
[SECTION .text]
dw 0x1BADB002
dw 0x000000000
dw 0x1BADB002
_start:
mov si, msg
call displaystring

mov ah, 0
int 016h

db 0EAh
dw 0000h
dw 0FFFFh

displaystring:
lodsb
or al,al
jz short finish
mov ah,0x0E
mov bx,0x0007
int 0x10
jmp displaystring
finish:
retn

msg db 'Press Any Key ...', 13, 10, 0

Basically, this code runs start and displays some text, waits for keyboard activity and then reboots. (i got it from something else).

Is the correct layout for an elf file to work which is why i get the above ld linker error, also, is the multiboot header right? I think it is, as far as some multiboot spec that i found goes, bit 16 doesn't need to be set in the flags cos im using the elf file format but when i load a similar version of the above code (a bit cut down to just display some messaging and no reboot or keyboard business grub says the file format is not supported.

^ a bit long but hopefully someone will be kind enough to allow me to even start some kind of kernel. Thanks :)

Regards Brill.
carbonBased

RE:elf file format

Post by carbonBased »

That relocation thing doesn't make sense to me... it looks like it's happening when trying to display the string (text + 8 bytes), but that looks fine to me.

Not only that, the error message leads me to believe that you're making a 16-bit relocation... but you aren't (!?)

Sorry, dude, but I can't help you out there...

As for the multiboot header, though... that's not 100% correct... OHH!  And there's you're problem with the linker (probably!)... you're using dw to define a word... but those are double words (32-bits!).  Use dd instead!

Anyway, the multiboot header is this:
dd magic
dd flags
dd checksum

where, as you have it, magic = 0x1BADB002
and flags is... whatever ;)
however, checksum = 0 - (magic + flags)

You'll have to change your checksum for grub to load your kernel properly.

Also, you might want to consider setting bit 2 (10b) so you can get some info from GRUB about currently installed memory and other stuff.

Jeff

PS: you're right about bit 16, as well.
Brill

RE:elf file format

Post by Brill »

Hi, thanks for your help. I would never have known the mheader was wrong without it ;).

I've found that what seems to be making the linker go wrong is the code:
mov si, msg.

Without that it links correctly. Although, in theory, without that the message will never get displayed so obviously its needed.
After further playing around i've realised that si needs extending to esi for the 32bit extended version of it. Have you any idea why? The extra extensions aren't needed unless the size is larger than 16bits but since it works in real mode (i tried this code as a bootloader to see something working, thats before i descovered grub and its ability to switch to pmode saving me a lot of hassle which nearly made me give up osdevelopment) then there should be no problem. :/


Regards Brill
carbonBased

RE:elf file format

Post by carbonBased »

Ahh, yes, that makes sense!

I figured it was that instruction (it's exactly .text + 8 bytes) but couldn't find anything wrong with it... but, I was in boot sector mode :)

Yes, you must use esi because the move instruction (when in protected mode) always assumes a 32-bit address (unless you use the memory size prefix (0x66?))  Doesn't matter if the address is only one byte away, it'll still load a 32-bit pointer.

No worries, though, dude, both mov instructions only take 1 clock cycle (assuming 486+) so there's no waste.

Jeff

PS: Yeah, man, I know what you mean 'bout grub... I wasn't a huge fan of boot loader coding either :)
Brill

RE:elf file format

Post by Brill »

Excellent! The elf file assembles/links correctly, but now i have a further 2 problems!

Problem 1. When i use vmware to boot of the floppy grub gives the error message about not being enough memory. But there's 128MB of it and the kernel is only 200b?!

Problem 2. When i do boot the kernel outside an emulator on a proper machine (256Mb) i get the kernel tripple faulting and the machine resets :S.
Mega :(.

Oh well, i'll keep on messin' with it. Thanks for your help CarbonBased. V.helpful.

Regards Brill
carbonBased

RE:elf file format

Post by carbonBased »

Strange,

I've used grub under vmware at it works perfectly, and that's with a 5k kernel, and a 96MB Memory vmware system.  Is your kernel's entry address properly formed?

Grub will only load kernels above the 1MB mark (0x00100000), so you'll either need to specify that in a linker script, or pass "-Ttext 0x00100000" to ld.

Other than that, I don't have any ideas...

Jeff
Schol-R-LEA

This code won't work anyway

Post by Schol-R-LEA »

You cannot call BIOS interrupts from p-mode without dropping into v86 mode first. You'll have to write you string to the video memory directly.
Schol-R-LEA

To continue where I left off...

Post by Schol-R-LEA »

I'm not sure what is causing the linking problem, offhand, so I can't give much help there. However, I can say that the multiboot header is incorrect; you can't define a word space (dw) and then fit a double word (dd) into it. In this case, the second half of the first doubleword is being overwritten by the first half of the second doubleword, and the second half of the second doubleword is overwritten by the first half of the third doubleword.

It would also make things clear if you defined it as a struct, with the individual fields named, as so:

MBH_MAGIC    EQU 0x1BADB002
MBH_FLAGS    EQU 0x00000000


struc   MultibootHeader
   magic         dd MBH_MAGIC
   flags         dd MBH_FLAGS
   checksum      dd -(MBH_MAGIC + MBH_FLAGS)

   ; optional fields
%if (MBH_FLAGS ^ 0x00008000)        ; bit 16 - non-ELF files
   head_addr     dd MultibootHeader
   load_addr     dd MultibootHeader
   load_end_addr dd _edata
   bss_end_addr  dd _end
   entry_addr    dd _start          
%endif

%ifdef (MBH_FLAGS ^ 0x00000002)     ; bit 2- video mode data
   mode_type     dd 0x000000000
   width         dd 0x000000000
   height        dd 0x000000000
   depth         dd 0x000000000
%endif

   endstruct

Which should clarify things a bit (I hope). Note the checksum is the *negative* of the sum of magic and flags (that is, if you were to add magic and flags, and the add that sum to checksum, the result would be zero). I wrote this out explicitly, even though it was not necessary to, in case you need to modify the flags later. The purpose of the separate EQUs for the constants was to make this, and the subsequent %if statements, easier to manage.

This information is taken from the Multiboot Specification v0.7, http://www.mcc.ac.uk/grub/multiboot_toc.html , which also has the details of the processor state at OS loading time, and a boot code sample (though the assembly code uses AT&T format).

As for the final jump, I'm not sure where that's jumping to, but I doubt it does what you mean it to. The idiom used is, in any cae, unneccessary in p-mode code, as there's no difference between NEAR and FAR jumps - all non-SHORT jumps use 32-bit addressing in p-mode, IIRC.

I hope this helps; corrections are always welcome.
Brill

RE:elf file format

Post by Brill »

ok, thanx mate. :)


Regards Brill
Brill

RE:To continue where I left off...

Post by Brill »

Thanks for all your help :). Appreciate it.

Regards Brill.
DeReiter

RE:elf file format

Post by DeReiter »

GRUB puts sys into 32-bits - you cant do int $0x10 becuse it doesnt exist in the IDT table :(


First of all, read the MULTIBOOT specs - I'll paste it here 4 you:

http://www.mcc.ac.uk/grub/multiboot_toc.html


====================
When the boot loader invokes the 32-bit operating system, the machine must have the following state:


CS must be a 32-bit read/execute code segment with an offset of 0 and a limit of 0xFFFFFFFF.

DS, ES, FS, GS, and SS must be a 32-bit read/write data segment with an offset of 0 and a limit of 0xFFFFFFFF.

The address 20 line must be usable for standard linear 32-bit addressing of memory (in standard PC hardware, it is wired to 0 at bootup, forcing addresses in the 1-2 MB range to be mapped to the 0-1 MB range, 3-4 is mapped to 2-3, etc.).

Paging must be turned off.

The processor interrupt flag must be turned off.

EAX must contain the magic value 0x2BADB002; the presence of this value indicates to the operating system that it was loaded by a Multiboot-compliant boot loader (e.g. as opposed to another type of boot loader that the operating system can also be loaded from).

EBX must contain the 32-bit physical address of the Multiboot information structure provided by the boot loader (see section 3.3 Boot information format).
All other processor registers and flag bits are undefined. This includes, in particular:


ESP: the 32-bit operating system must create its own stack as soon as it needs one.

GDTR: Even though the segment registers are set up as described above, the GDTR may be invalid, so the operating system must not load any segment registers (even just reloading the same values!) until it sets up its own GDT.

IDTR: The operating system must leave interrupts disabled until it sets up its own IDT.

=========================


GRUB puts the system into PMODE.... for an example kernel (I used it to build off my own :) )  - http://www.mcc.ac.uk/grub/multiboot_4.html#SEC23
DeReiter

Why make your own multiboot-compilant header?

Post by DeReiter »

JUST USE THE MULTIBOOT.H
Post Reply