Linking/initialization trouble
-
- Posts: 22
- Joined: Sat Mar 06, 2010 2:17 pm
Linking/initialization trouble
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?
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?
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Linking/initialization trouble
Posting your linker script and makefile would be very helpful
-
- Posts: 22
- Joined: Sat Mar 06, 2010 2:17 pm
Re: Linking/initialization trouble
Sorry, the linker script is:
and the makefile(batch):
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.
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 = .;
}
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
- KotuxGuy
- Member
- Posts: 96
- Joined: Wed Nov 25, 2009 1:28 pm
- Location: Somewhere within 10ft of my favorite chubby penguin!
Re: Linking/initialization trouble
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 )
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 )
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Linking/initialization trouble
One thing that catches my eye is
I think probably meant 0x00100000, or 1MB, not 64kb; in fact I'm surprised Grub even loaded it.
Nothing else jumps immediately at me
Code: Select all
phys = 0x00010000;
Nothing else jumps immediately at me
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Linking/initialization trouble
Because his intermediate objects are ELF files? Because it matches his i686-elf-gcc compiler? Because its the correct version of LD to use?KotuxGuy wrote:Why are you using i686-elf-ld if you're compiling to a flat binary?
-
- Posts: 22
- Joined: Sat Mar 06, 2010 2:17 pm
Re: Linking/initialization trouble
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).KotuxGuy wrote:Why are you using i686-elf-ld if you're compiling to a flat binary?
Now why do you assume I'm using GRUB? My bootloader(2-stage) actually loads the kernel to 10000h [ES=1000h, BX=0].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
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
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, ...)
- 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, ...)
-
- Posts: 22
- Joined: Sat Mar 06, 2010 2:17 pm
Re: Linking/initialization trouble
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?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, ...)
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.
-
- Posts: 22
- Joined: Sat Mar 06, 2010 2:17 pm
Re: Linking/initialization trouble
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?
-
- 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
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?).
-
- Posts: 22
- Joined: Sat Mar 06, 2010 2:17 pm
Re: Linking/initialization trouble
EDIT: Answered my own question about ELF
-
- Posts: 22
- Joined: Sat Mar 06, 2010 2:17 pm
Re: Linking/initialization trouble
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:
and an objdump if it helps:
works-
fails-
Thanks
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 = .;
}
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
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