Page 1 of 1

Linking/initialization trouble

Posted: Sat Mar 27, 2010 4:13 pm
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?

Re: Linking/initialization trouble

Posted: Sat Mar 27, 2010 4:38 pm
by Owen
Posting your linker script and makefile would be very helpful

Re: Linking/initialization trouble

Posted: Sat Mar 27, 2010 4:44 pm
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.

Re: Linking/initialization trouble

Posted: Sat Mar 27, 2010 6:23 pm
by KotuxGuy
Why are you using i686-elf-ld if you're compiling to a flat binary?

Re: Linking/initialization trouble

Posted: Sat Mar 27, 2010 6:27 pm
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

Re: Linking/initialization trouble

Posted: Sat Mar 27, 2010 6:28 pm
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?

Re: Linking/initialization trouble

Posted: Sat Mar 27, 2010 7:17 pm
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?

Re: Linking/initialization trouble

Posted: Sun Mar 28, 2010 9:08 am
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, ...)

Re: Linking/initialization trouble

Posted: Sun Mar 28, 2010 11:09 am
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.

Re: Linking/initialization trouble

Posted: Sun Mar 28, 2010 2:44 pm
by pcmattman

Re: Linking/initialization trouble

Posted: Sun Mar 28, 2010 4:07 pm
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?

Re: Linking/initialization trouble

Posted: Sun Mar 28, 2010 7:18 pm
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?).

Re: Linking/initialization trouble

Posted: Thu Apr 01, 2010 1:58 pm
by GenHornet18
EDIT: Answered my own question about ELF

Re: Linking/initialization trouble

Posted: Sat Apr 03, 2010 12:38 pm
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