OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 2:37 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Linking with an odd setup via a linker script assistance
PostPosted: Tue Nov 09, 2021 1:12 pm 
Offline

Joined: Tue Nov 09, 2021 11:40 am
Posts: 18
I've been working on a bootloader for an OS development project. Currently I'm trying to manage the linking of the bootloader.

My boot sector code loads the first parts of the bootloader at 0x10000. It's designed to work in 64K chunks because of this.

I haven't been using a linker script because I've only been at the boot sector phase until now. Now that I'm entering this however, that changes things.

The primary issue comes with how the linker is handling linking the symbols. Boot sector code needs to be linked relative to 0x7c00 (as cs,ds=0 at that time) but entry segment code needs to be linked relative to 0x0 (as cs,ds=1).

For reference I'm assembling with GNU as, and linking with GNU binutils.

What linker script do I need to make this possible?


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Tue Nov 09, 2021 6:07 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
amyipdev wrote:
My boot sector code loads the first parts of the bootloader at 0x10000. It's designed to work in 64K chunks because of this.

How big are you expecting your bootloader to be? I've written a lot of bootloader code and I haven't run out of space under 0x10000 yet.

amyipdev wrote:
(as cs,ds=1)

You mean 0x1000 and not 1, right? Setting a real-mode segment register to 1 changes the segment base to 0x10, not 0x10000.

amyipdev wrote:
What linker script do I need to make this possible?

You need to specify the VMA and LMA separately, possibly with overlapping VMA. There's another example at the bottom of this page that might also help.

But before you get into all of that, why do you want to link it all into a single binary? Do you really need a linker to resolve symbols across the two parts of your bootloader?


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Wed Nov 10, 2021 10:19 am 
Offline

Joined: Tue Nov 09, 2021 11:40 am
Posts: 18
Octocontrabass wrote:
amyipdev wrote:
My boot sector code loads the first parts of the bootloader at 0x10000. It's designed to work in 64K chunks because of this.

How big are you expecting your bootloader to be? I've written a lot of bootloader code and I haven't run out of space under 0x10000 yet.


Decently large - I'm loading my bootloader at 0x10000 to ensure I don't run into other tables below 0x7c00. It also allows a much simpler and easier addressing scheme. It's fully possible that my bootloader may be as large as (but definitely not larger than) 384KB, as I want to make it fairly fancy (supporting multi-boot kernels, having some basic filesystem drivers, plus potentially fancy boot-up graphics). I'm also beginning addressing at 0x10000 to make the bootloader's structure much easier to conceptualize. I could shift it downwards to 0x7e00 but where's the fun in that?

Octocontrabass wrote:
amyipdev wrote:
(as cs,ds=1)

You mean 0x1000 and not 1, right? Setting a real-mode segment register to 1 changes the segment base to 0x10, not 0x10000.


Yes, my apologies - I meant 0x1000.

Octocontrabass wrote:
amyipdev wrote:
What linker script do I need to make this possible?

You need to specify the VMA and LMA separately, possibly with overlapping VMA. There's another example at the bottom of this page that might also help.

But before you get into all of that, why do you want to link it all into a single binary? Do you really need a linker to resolve symbols across the two parts of your bootloader?


It would be preferable to do it all into one, yes. I'd like to be able to safely call functions across segments. In addition, for whatever reason, stuff seems to go haywire when I just shove separate binaries together for boot...

And thank you for that - I'll try to have a look at that. Do you think you could assist a bit more, however? I can't seem to get anything working in terms of a linker script, even just for the initial setup (1 file, loaded at 0x7c00).


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Wed Nov 10, 2021 11:39 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
amyipdev wrote:
In addition, for whatever reason, stuff seems to go haywire when I just shove separate binaries together for boot...

It works just fine when I do it. Are you doing something funny like using a binary with unresolved symbols or booting from USB?

amyipdev wrote:
I can't seem to get anything working in terms of a linker script, even just for the initial setup (1 file, loaded at 0x7c00).

Here's a typical flat binary linker script. Yours should look similar, although you'll probably have only one section since it doesn't make sense to have more than one section in a 512-byte binary.


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Wed Nov 10, 2021 11:47 am 
Offline
Member
Member

Joined: Tue Feb 18, 2020 3:29 pm
Posts: 1071
In the linker script you linked to, shouldn't "*(.rodata)" be *(.rodata*)"? I remember until spending like 30 minutes hunting down a string bug until I realized GCC put strings in subsections, and I needed to include those as well.

_________________
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Wed Nov 10, 2021 12:15 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
You're right, that example is missing wildcards to catch subsections. I think GCC can generate subsections for all of them, not just .rodata.


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Wed Nov 10, 2021 1:41 pm 
Offline

Joined: Tue Nov 09, 2021 11:40 am
Posts: 18
Octocontrabass wrote:
amyipdev wrote:
In addition, for whatever reason, stuff seems to go haywire when I just shove separate binaries together for boot...

It works just fine when I do it. Are you doing something funny like using a binary with unresolved symbols or booting from USB?


Nope - maybe it was something wrong with how I shoved them together, but for some reason it just started infinitely incrementing `%ip`.

Octocontrabass wrote:
amyipdev wrote:
I can't seem to get anything working in terms of a linker script, even just for the initial setup (1 file, loaded at 0x7c00).

Here's a typical flat binary linker script. Yours should look similar, although you'll probably have only one section since it doesn't make sense to have more than one section in a 512-byte binary.


Thank you for this.

Do I actually have to split my code into sections to use this? Will a general .text be sufficient? Previously when using sections my code would refuse to link, so I've been leaving sections out of the equation ever since.


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Wed Nov 10, 2021 2:18 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
amyipdev wrote:
for some reason it just started infinitely incrementing `%ip`.

That usually means you've jumped somewhere that doesn't contain any code. Intel had enough foresight to ensure 0xFFFF (open bus) would be an invalid instruction when they designed the 8086, but uninitialized RAM often contains 0x0000, which is a valid instruction.

amyipdev wrote:
Do I actually have to split my code into sections to use this? Will a general .text be sufficient?

You don't have to split your boot sector code into multiple sections, but you might get warnings from the linker if you use a standard section name like .text in unusual ways.

When you start using more than one segment, you'll need to somehow separate the code that goes into each segment. You can separate them by file name if you want to use the same section name everywhere.


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Wed Nov 10, 2021 3:39 pm 
Offline

Joined: Tue Nov 09, 2021 11:40 am
Posts: 18
Octocontrabass wrote:
amyipdev wrote:
for some reason it just started infinitely incrementing `%ip`.

That usually means you've jumped somewhere that doesn't contain any code. Intel had enough foresight to ensure 0xFFFF (open bus) would be an invalid instruction when they designed the 8086, but uninitialized RAM often contains 0x0000, which is a valid instruction.


That's what I thought had been going on - I know the boot sector code loaded, as it didn't stop boot (so the sector word was there), but maybe it got somehow messed up?

Octocontrabass wrote:
amyipdev wrote:
Do I actually have to split my code into sections to use this? Will a general .text be sufficient?

You don't have to split your boot sector code into multiple sections, but you might get warnings from the linker if you use a standard section name like .text in unusual ways.

When you start using more than one segment, you'll need to somehow separate the code that goes into each segment. You can separate them by file name if you want to use the same section name everywhere.


I wasn't worrying about splitting segment code.

Thank you so much for your assistance! I'll let you know how things go.


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Wed Nov 10, 2021 3:54 pm 
Offline

Joined: Tue Nov 09, 2021 11:40 am
Posts: 18
Didn't seem to work. I attached my assembly (apologize for the horrible conventions, I'll clean it up soon(TM)) and my linker script. I got the following linker error:

Code:
amy@fedora:~/Development/aucs $ ld -L linker.ld -o global global.o entry.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
global.o: in function `ini':
(.text+0x2): relocation truncated to fit: R_X86_64_16 against `.text'
global.o: in function `rddsk_routine':
(.text+0x60): relocation truncated to fit: R_X86_64_16 against `.text'
(.text+0x6c): relocation truncated to fit: R_X86_64_16 against `.text'
global.o: in function `no_lba_ex':
(.text+0x7a): relocation truncated to fit: R_X86_64_16 against `.text'
(.text+0x7d): relocation truncated to fit: R_X86_64_16 against symbol `prs' defined in .text section in global.o
global.o: in function `det_apm_abs':
(.text+0xda): relocation truncated to fit: R_X86_64_16 against `.text'
(.text+0xdd): relocation truncated to fit: R_X86_64_16 against symbol `prs' defined in .text section in global.o
global.o: in function `det_apm_err':
(.text+0xe3): relocation truncated to fit: R_X86_64_16 against `.text'
(.text+0xe6): relocation truncated to fit: R_X86_64_16 against symbol `prs' defined in .text section in global.o
entry.o: in function `get_bios_mmap':
(.text+0x22): relocation truncated to fit: R_X86_64_16 against `.text'
(.text+0x28): additional relocation overflows omitted from the output


Attachments:
global.s [2.65 KiB]
Downloaded 20 times
entry.s [686 Bytes]
Downloaded 21 times
linker.ld [155 Bytes]
Downloaded 18 times
Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Wed Nov 10, 2021 9:36 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
Code:
amy@fedora:~/Development/aucs $ ld -L linker.ld -o global global.o entry.o

That's supposed to be "-T linker.ld".

Are you intending to pack the sections together when the code and data doesn't occupy a full 64kiB, or do you want them padded so it's easier to load? If it's the former, the OVERLAY command is the right choice, but if it's the latter, you probably want something more like this:

Code:
ENTRY(ini)
OUTPUT_FORMAT("binary")

SECTIONS
{
   .text0 0x7c00 : AT(0x10000-0x200) {
      global.o(.text)
   }
   .text1 0x0 : AT(0x10000) {
      entry.o(.text)
   }
   .text2 0x0 : AT(0x20000) {
      example.o(.text)
   }
}


If you do use the OVERLAY command, you'll have to exclude the boot sector since it starts at a different VMA.


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Thu Nov 11, 2021 3:23 pm 
Offline

Joined: Tue Nov 09, 2021 11:40 am
Posts: 18
Octocontrabass wrote:
Code:
amy@fedora:~/Development/aucs $ ld -L linker.ld -o global global.o entry.o

That's supposed to be "-T linker.ld".


Ah, thank you, my bad - I'll try that out when I'm back at my development system.

Octocontrabass wrote:
Are you intending to pack the sections together when the code and data doesn't occupy a full 64kiB, or do you want them padded so it's easier to load? If it's the former, the OVERLAY command is the right choice, but if it's the latter, you probably want something more like this:

Code:
ENTRY(ini)
OUTPUT_FORMAT("binary")

SECTIONS
{
   .text0 0x7c00 : AT(0x10000-0x200) {
      global.o(.text)
   }
   .text1 0x0 : AT(0x10000) {
      entry.o(.text)
   }
   .text2 0x0 : AT(0x20000) {
      example.o(.text)
   }
}


If you do use the OVERLAY command, you'll have to exclude the boot sector since it starts at a different VMA.


Yes, I did mean the latter - thank you so much for your assistance!


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Fri Nov 12, 2021 8:02 pm 
Offline

Joined: Tue Nov 09, 2021 11:40 am
Posts: 18
Hello - it is still not linking properly. Loading the packet loads $0x7e59, while the packet should load as $0x59. Code jumps occur correctly but data jumps do not.

Code:
221:   be 59 7e                mov    $0x7e59,%si
224:   89 46 e6                mov    %ax,-0x1a(%bp)
227:   9a 84 7c 00 00          lcall  $0x0,$0x7c84
22c:   8b 46 e6                mov    -0x1a(%bp),%ax
22f:   eb fe                   jmp    0x22f


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Fri Nov 12, 2021 8:17 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
That's odd, it works perfectly fine for me. Here's the corresponding bytes from the binary I built:

Code:
BE 59 00
89 46 E6
9A 84 7C 00 00
8B 46 E6
EB FE


Do you see any warnings when you build everything? Did you make any changes to the example LD script aside from removing references to the nonexistent example.o?


Top
 Profile  
 
 Post subject: Re: Linking with an odd setup via a linker script assistance
PostPosted: Fri Nov 12, 2021 8:24 pm 
Offline

Joined: Tue Nov 09, 2021 11:40 am
Posts: 18
Octocontrabass wrote:
That's odd, it works perfectly fine for me. Here's the corresponding bytes from the binary I built:

Code:
BE 59 00
89 46 E6
9A 84 7C 00 00
8B 46 E6
EB FE


Do you see any warnings when you build everything? Did you make any changes to the example LD script aside from removing references to the nonexistent example.o?


Absolutely zero warnings. The LD script was verbatim except for removing the example.o section.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 79 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group