Linking/initialization trouble

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
GenHornet18
Posts: 22
Joined: Sat Mar 06, 2010 2:17 pm

Linking/initialization trouble

Post by GenHornet18 »

Good Day,

So I'm developing a basic kernel following JamesM tutorials (which are a damn good job btw James) and I'm having trouble getting my global variables to initialize with an original value. Specifically the Attribute variable in my screen source file. As I boot my kernel in bochs I get a black screen because the kernel was loaded correctly and the output message was outputted but the Attribute variable isn't set so it outputs black letters (indistinguishable from the background).

After long enough debugging I tracked the problem to what I believe is the linker. I say this because when I link 7 object files together and I get the error and yet when I link only the first 3 object files (required for outputting text) the Attribute value is initialized to what it originally was set as after declaration (i.e unsigned short Attrib = 0x07;). So I'm left wondering why when I link more object files together does this variable fail to become initialized?
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Linking/initialization trouble

Post by Owen »

Posting your linker script and makefile would be very helpful
GenHornet18
Posts: 22
Joined: Sat Mar 06, 2010 2:17 pm

Re: Linking/initialization trouble

Post by GenHornet18 »

Sorry, the linker script is:

Code: Select all

 OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00010000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}
and the makefile(batch):

Code: Select all

echo Creating kernel, please wait...
rem ELF files, create a kernel

nasm -f elf start.asm -o start.o
i686-elf-gcc -Wall -ffreestanding -finline-functions -nostdinc -I./include -c Main.c -o Main.o
i686-elf-gcc -Wall -ffreestanding -finline-functions -nostdinc -I./include -c OutSet.c -o OutSet.o
i686-elf-gcc -Wall -ffreestanding -finline-functions -nostdinc -I./include -c DataSet.c -o DataSet.o
i686-elf-gcc -Wall -ffreestanding -finline-functions -nostdinc -I./include -c DescTables.c -o DescTables.o
i686-elf-gcc -Wall -ffreestanding -finline-functions -nostdinc -I./include -c ISR.c -o ISR.o
i686-elf-gcc -Wall -ffreestanding -finline-functions -nostdinc -I./include -c Timer.c -o Timer.o
i686-elf-gcc -Wall -ffreestanding -finline-functions -nostdinc -I./include -c Paging.c -o Paging.o


i686-elf-ld -T link.ld -o kernel.bin start.o Main.o DataSet.o OutSet.o DescTables.o ISR.o Timer.o Paging.o  
echo Finished!
rm *.o
pause
Using this makefile results in an error, while if I don't link the last 4 object files (and remove all references from them) the initialization works. The fault doesn't seem to be in the C files, as they do work as intended.
User avatar
KotuxGuy
Member
Member
Posts: 96
Joined: Wed Nov 25, 2009 1:28 pm
Location: Somewhere within 10ft of my favorite chubby penguin!

Re: Linking/initialization trouble

Post by KotuxGuy »

Why are you using i686-elf-ld if you're compiling to a flat binary?
Give a man Linux, you feed the nearest optician ( Been staring at the PC too long again? ).
Give a man OS X, you feed the nearest NVidia outlet ( I need more GPU power!! )
Give a man Windows, you feed the entire Tylenol company ( Self explanatory :D )
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Linking/initialization trouble

Post by Owen »

One thing that catches my eye is

Code: Select all

phys = 0x00010000;
I think probably meant 0x00100000, or 1MB, not 64kb; in fact I'm surprised Grub even loaded it.

Nothing else jumps immediately at me
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Linking/initialization trouble

Post by Owen »

KotuxGuy wrote:Why are you using i686-elf-ld if you're compiling to a flat binary?
Because his intermediate objects are ELF files? Because it matches his i686-elf-gcc compiler? Because its the correct version of LD to use?
GenHornet18
Posts: 22
Joined: Sat Mar 06, 2010 2:17 pm

Re: Linking/initialization trouble

Post by GenHornet18 »

KotuxGuy wrote:Why are you using i686-elf-ld if you're compiling to a flat binary?
Everything is ELF so it just seems to match up (if I don't the original LD will complain about not being able to modify a PE object).
Owen wrote:I think probably meant 0x00100000, or 1MB, not 64kb; in fact I'm surprised Grub even loaded it.

Nothing else jumps immediately at me
Now why do you assume I'm using GRUB? My bootloader(2-stage) actually loads the kernel to 10000h [ES=1000h, BX=0].

I don't think there is anything wrong with the bootloader as it does load the kernel to the correct location and transfers control to it. I find it odd though that when there are more object files linked my variables don't initialize correctly. Is there anything wrong with the linker script?
js
Member
Member
Posts: 38
Joined: Thu Feb 26, 2009 1:45 am

Re: Linking/initialization trouble

Post by js »

Possible causes I see (but I may very well be mistaken) :

- where's your .rodata segment ???
- since you're loading your kernel at a very low adress, and errors seem to occur past a certain file size, have you checked nothing's tampering with your data ? (BIOS video, BIOS functions, ...)
GenHornet18
Posts: 22
Joined: Sat Mar 06, 2010 2:17 pm

Re: Linking/initialization trouble

Post by GenHornet18 »

js wrote: where's your .rodata segment ???
- since you're loading your kernel at a very low adress, and errors seem to occur past a certain file size, have you checked nothing's tampering with your data ? (BIOS video, BIOS functions, ...)
Is it necessary to have a segment in the linker script for only *(.rodata) ? I assumed I could combine it with my the *(.text) section?

Based on a hex dump the strings are present in the kernel, and this is all done in protected mode so I don't actually use any BIOS interrupts. The kernel when fully compiled/linked is only 8KB so if the start address is 10000h(phys) then it shouldn't be interfering with any other reserved memory. I will look into relocating to above 1MB, and see if this makes a difference. I still find it odd though, because it will work if I assign a value to 'Attrib' after it's declaration, it just refuses to initialize.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Linking/initialization trouble

Post by pcmattman »

GenHornet18
Posts: 22
Joined: Sat Mar 06, 2010 2:17 pm

Re: Linking/initialization trouble

Post by GenHornet18 »

Well I do have a *(.rodata) section and I have confirmed via hex editor that the strings are present in the file. I've also confirmed that the original value that's to be assigned to the variable 'Attrib' is present in the .data section. So if all the data is there then why does it not get assigned? Could my address somehow be offset?
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Linking/initialization trouble

Post by pcmattman »

If you're not using GRUB, you most likely have an error in your code to handle any required relocations in the ELF file. You may also be loading part of your kernel rather than the entire thing (not enough sectors loaded?).
GenHornet18
Posts: 22
Joined: Sat Mar 06, 2010 2:17 pm

Re: Linking/initialization trouble

Post by GenHornet18 »

EDIT: Answered my own question about ELF
GenHornet18
Posts: 22
Joined: Sat Mar 06, 2010 2:17 pm

Re: Linking/initialization trouble

Post by GenHornet18 »

Alright I've isolated the problem but I'm unsure of how to fix it. It seems when the .text section of my linker script is beyond 1 page (4096) the variables don't get initialized (from the .data section). However when the .text section is smaller then 1 page everything seems to be initialized and works properly. So I'm assume this is an aligning issue? Any ideas on how to correct this?

Linker script I'm using:

Code: Select all

OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS
{
  .text 0x10100 :
  {
    code = .; 
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }

  .data : 
  {
     data = .; 
     *(.data)
     . = ALIGN(4096);
  }

  .bss : 
  {
    bss = .; 
    *(.bss)
    . = ALIGN(4096);
  }

  end = .;
} 
and an objdump if it helps:
works-

Code: Select all

kernel.bin:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000f00  00010100  00010100  00000100  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00001000  00011000  00011000  00001000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          0000000c  00012000  00012000  00002000  2**2
                  ALLOC
  3 .comment      00000036  00000000  00000000  00002000  2**0
                  CONTENTS, READONLY

fails-

Code: Select all

kernel.bin:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00001f00  00010100  00010100  00000100  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00001000  00012000  00012000  00002000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000c60  00013000  00013000  00003000  2**5
                  ALLOC
  3 .comment      0000005a  00000000  00000000  00003000  2**0
                  CONTENTS, READONLY
Thanks
Post Reply