The meaning relocatable(Gu ld -Ur).
The meaning relocatable(Gu ld -Ur).
When I link with the -Ur flag, it makes my kernel relocatable. But what does relocatable mean in this use? Does it mean my kernel is a PIE and can be loaded anywhere, but unmovable, or does it mean it can be loaded anywhere then remapped into (for example) 0xC0000000?
Re: The meaning relocatable(Gu ld -Ur).
In this sense it means that the kernel is not fully linked. It will (most likely) not run correctly. To complete the link and make it work, you have to run ld again without the -Ur or -r flag. It would theoretically be possible to have a very smart loader that could complete the link, but Grub cannot do that.When I link with the -Ur flag, it makes my kernel relocatable. But what does relocatable mean in this use?
If a trainstation is where trains stop, what is a workstation ?
Re: The meaning relocatable(Gu ld -Ur).
Odd... It's always worked before. Albeit to work is only to print a to 0xb8000.
How is it that kernels can be loaded at x address, then mapped to a different virtual address. Would that not confuse the kernel of where it's data (among just about everything else) is?
Edit:
My final call to ld: ld -melf_i386 -nostdlib --oformat elf32-i386 -T link.ld -Ur --warn-unresolved-symbols $+ -o $@
My ld script:
How is it that kernels can be loaded at x address, then mapped to a different virtual address. Would that not confuse the kernel of where it's data (among just about everything else) is?
Edit:
My final call to ld: ld -melf_i386 -nostdlib --oformat elf32-i386 -T link.ld -Ur --warn-unresolved-symbols $+ -o $@
My ld script:
Code: Select all
ENTRY(trampoline)
SECTIONS {
.text 0x100000 : {
code = .;_code = .;
boot/boot.o(.text)
*(.text)
. = ALIGN(_pagesize);
code_end = .;_code_end = .;
}
.data ALIGN(_pagesize) : {
data = .;_data = .;
*(.data)
*(.rodata)
. = ALIGN(_pagesize);
data_end = .;_data_end = .;
}
.bss ALIGN(_pagesize) : {
bss = .;_bss = .;
*(.bss)
. = ALIGN(_pagesize);
bss_end = .;_bss_end = .;
}
}
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: The meaning relocatable(Gu ld -Ur).
The kernel is linked to its final destination address, and the early boot code is made explicitly aware of the fact that its address information is "wrong". Alternatively, you can engage in some big linker tricks, which also work.
Re: The meaning relocatable(Gu ld -Ur).
You must remove the -Ur. It may work, or appear to work but it will eventually fail.This causes the code to be loaded by Grub at 0x100000. However, after you set up paging, the code can be re-mapped to 0xc0000000 and run there. There are a few tricks needed. You need to make sure that the start-up code is position independent because it will start at 0x100000 and then switch to 0xc0000000, and you'll have to apply an offset to access data until you set the paging bit.
One way is like this ...How is it that kernels can be loaded at x address, then mapped to a different virtual addres
Code: Select all
.text 0xc0000000 :
AT ( 0x100000 ) ALIGN (0x1000)
{ *(.text) }
etc.
If a trainstation is where trains stop, what is a workstation ?
Re: The meaning relocatable(Gu ld -Ur).
Code: Select all
ENTRY(trampoline)
SECTIONS {
.init 0x1000000 : AT(0x1000000) {
init = .;_init = .;
boot/boot.o(.text)
boot/boot.o(.data)
init_end = .;_init_end = .;
}
.text 0xc0000000 : {
code = .;_code = .;
*(EXCLUDE_FILE (boot/boot.o).text)
. = ALIGN(pagesize);
code_end = .;_code_end = .;
}
.data ALIGN(pagesize) : {
data = .;_data = .;
*(EXCLUDE_FILE (boot/boot.o).data .rodata)
. = ALIGN(pagesize);
data_end = .;_data_end = .;
}
.bss ALIGN(pagesize) : {
bss = .;_bss = .;
*(EXCLUDE_FILE (boot/boot.o).bss)
. = ALIGN(pagesize);
bss_end = .;_bss_end = .;
}
}
Re: The meaning relocatable(Gu ld -Ur).
Something like this .... (sorry unchecked because I am away from my dev machine) Note as I said before, that the code in boot.S that executes and sets up the mappings before the paging bit is set must be position independent because it will need to execute at 0x100000 even though LD thought it would execute at 0xc0000000. Also if you access any global variables before the remapping is done and the paging bit is set, you will have to subtract 0xbff00000 from the address. That's because LD will fixup the addresses to be in the 0xc0000000 range. I have some sample code somewhere that does this. I can try to find it if no-one can point you to some.
BTW, I think you have a typo you saidbut I think you meant
Code: Select all
ENTRY(trampoline)
SECTIONS {
.init 0xc0000000 : AT(0x100000) {
init = .;_init = .;
boot/boot.o(.text)
boot/boot.o(.data)
init_end = .;_init_end = .;
}
.text ALIGN(pagesize) : {
code = .;_code = .;
*(EXCLUDE_FILE (boot/boot.o).text)
. = ALIGN(pagesize);
code_end = .;_code_end = .;
}
.data ALIGN(pagesize) : {
data = .;_data = .;
*(EXCLUDE_FILE (boot/boot.o).data .rodata)
. = ALIGN(pagesize);
data_end = .;_data_end = .;
}
.bss ALIGN(pagesize) : {
bss = .;_bss = .;
*(EXCLUDE_FILE (boot/boot.o).bss)
. = ALIGN(pagesize);
bss_end = .;_bss_end = .;
}
}
BTW, I think you have a typo you said
Code: Select all
.init 0x1000000 : AT(0x1000000) {
Code: Select all
.init 0x100000 : AT(0x100000) {
If a trainstation is where trains stop, what is a workstation ?
Re: The meaning relocatable(Gu ld -Ur).
No, the point was to have .init have vma=lma(0x100000), then for the others to have a contiguous lma with .init, but with the real vma. All the code and data in .init is for setting up paging.
After the kernel is setup it can just unmap and mark the phys memory used by .init free.
My problem is that grub loads .init at 0x10000 and the tries to load .text at 0xc0000000. I want .text loaded at the next page aligned addr after .init, but with a vma of 0xc0000000.
After the kernel is setup it can just unmap and mark the phys memory used by .init free.
My problem is that grub loads .init at 0x10000 and the tries to load .text at 0xc0000000. I want .text loaded at the next page aligned addr after .init, but with a vma of 0xc0000000.
Re: The meaning relocatable(Gu ld -Ur).
Well try .. No guarantees though.
P.S. Don't forget to FIX YOUR TYPO. ( 1M = 0x100000 not 0x1000000 )
Code: Select all
ENTRY(trampoline)
SECTIONS {
.init 0x100000 : AT(0x100000) {
init = .;_init = .;
boot/boot.o(.text)
boot/boot.o(.data)
init_end = .;_init_end = .;
}
.text 0xc0000000 : AT(0x104000) {
code = .;_code = .;
*(EXCLUDE_FILE (boot/boot.o).text)
. = ALIGN(pagesize);
code_end = .;_code_end = .;
}
.data ALIGN(pagesize) : {
data = .;_data = .;
*(EXCLUDE_FILE (boot/boot.o).data .rodata)
. = ALIGN(pagesize);
data_end = .;_data_end = .;
}
.bss ALIGN(pagesize) : {
bss = .;_bss = .;
*(EXCLUDE_FILE (boot/boot.o).bss)
. = ALIGN(pagesize);
bss_end = .;_bss_end = .;
}
}
P.S. Don't forget to FIX YOUR TYPO. ( 1M = 0x100000 not 0x1000000 )
If a trainstation is where trains stop, what is a workstation ?
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: The meaning relocatable(Gu ld -Ur).
I'll quote the relevant bit of my ARM ldscript, which is built the same way:
Code: Select all
. += 0xFFFF0000
.text : AT(ADDR(.text) - 0xFFFF0000) {
*(.ivt)
*(.text*)
*(.rodata*)
}
Re: The meaning relocatable(Gu ld -Ur).
I'm loading at 16mb on purpose, isn't there important stuff in the area between 1mb and 16mb?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: The meaning relocatable(Gu ld -Ur).
memory that's actually present?
Re: The meaning relocatable(Gu ld -Ur).
In you 2nd post you saidIn your 3rd post you saidIn your 4th post you saidAt least 2 of those 3 different addresses must be typos.
Code: Select all
SECTIONS {
.text 0x100000 : {
code = .;_code = .;
Code: Select all
SECTIONS {
.init 0x1000000 : AT(0x1000000) {
init = .;_init = .;
Code: Select all
grub loads .init at 0x10000
If a trainstation is where trains stop, what is a workstation ?
Re: The meaning relocatable(Gu ld -Ur).
That's gerryf400 for pointing that out. I'll make it 1mb.
But something just occurred to me. Why am I adding all this extra complexity to my kernel, when it'd be simple to just run it in the low x mbs? Is there any practical reason to choose the higher half over the lower half? It leaves the same amount for apps to use later on, either way.
Is higher half just a tradition, or is there a rationale to it? The only meaningful reason(IMHO) in the wiki is for 64bit oses, mine is 32bit.
But something just occurred to me. Why am I adding all this extra complexity to my kernel, when it'd be simple to just run it in the low x mbs? Is there any practical reason to choose the higher half over the lower half? It leaves the same amount for apps to use later on, either way.
Is higher half just a tradition, or is there a rationale to it? The only meaningful reason(IMHO) in the wiki is for 64bit oses, mine is 32bit.
Re: The meaning relocatable(Gu ld -Ur).
I think the main advantage of the higher half kernel is that that you can change the memory map of your O/S and you have more chance of keeping the applications that have been written for your O/S binary compatible.
Let's say you decide on a memory map where user-space goes from 0 to 0xbfff ffff and the kernel from 0xc000 0000 to 0xffff ffff. And let's say the apps built for your O/S have an entry point at 0x401000. If you one day re-design your kernel so that it need more memory you could change the kernel to begin at 0xb000 0000 and your apps wouldn't need to be rebuilt. It's not so easy to guarantee that with a lower-half kernel.
Let's say you decide on a memory map where user-space goes from 0 to 0xbfff ffff and the kernel from 0xc000 0000 to 0xffff ffff. And let's say the apps built for your O/S have an entry point at 0x401000. If you one day re-design your kernel so that it need more memory you could change the kernel to begin at 0xb000 0000 and your apps wouldn't need to be rebuilt. It's not so easy to guarantee that with a lower-half kernel.
If a trainstation is where trains stop, what is a workstation ?