Author Topic: relocation truncated to fit  (Read 18992 times)

nobody

  • Guest
relocation truncated to fit
« on: September 09, 2006, 09:45:11 PM »
Hi,

I assembled two 16-bit code files with the dos-32-binary of NASM in elf format. Linking with ld fails and yields the message "relocation truncated to fit R_386_16".

Is there a switch to avoid this failure?

Thanks,

Steffen

nobody

  • Guest
Re: relocation truncated to fit
« Reply #1 on: September 10, 2006, 12:05:27 AM »
Hi Steffen,

Might be a switch to ld... Might be a better question for an ld forum (if any).

I'm not certain, from your question, whether you know what you're doing, or not. If you know what you're doing, I don't know the answer to your question. If you're not aware of it... ELF is inherently a 32-bit format. There are GNU extensions to the elf format which *do* allow 16- and 8-bit(!) relocations. Nasm has - fairly recently - been upgraded to accept these. There is a switch - "-w+gnu-elf-extensions" to warn if you use these (should be on by default, IMHO, but apparently not). AFAIK, Nasm gets this right, but I doubt if it's been very extensively tested. I have *no* idea how/when/why to use these properly.

This *won't* allow you to run 16-bit code in Linux, if that's what you're trying to do! You might be able to take "16-bit code" - that is, code that uses 16-bit registers and instructions, but *not* 16-bit interrupts or a segmented addressing model!!! - and ask Nasm to assemble it as 32-bit code (which is the default for "-f elf"), and get working results... but you'd probably be better off to rewrite it as 32-bit code.

You say you're using the 32-bit dos executable of Nasm... what ld? Are you using MinGW/Cygwin ld, or transferring the .o file to a Linux (or other) machine?

If you know what you're doing, educate me, Steffen. If not, explain more about what you're trying to do - show us, or explain, the 16-bit code, and what sort of situation you expect the result to run in. Maybe we can help you figure out something that *will* work.

Best,
Frank

nobody

  • Guest
Re: relocation truncated to fit
« Reply #2 on: September 10, 2006, 08:19:43 AM »
Dear Frank,

Thank you for your immediate reply.

I am trying to write (i) a 512 byte bootloader and (ii) a small os, under Windows 2000.

The bootloader is 16-bit NASM code. The os shall be 16-bit gcc code. (I will compile the os with gcc and assemble it with the gnu as, directive ".code16gcc").

Now, to link the bootloader and the os I need an object file format that's understood by both, NASM and gnu as, and by my favorite linker ld (version 2.15.91 from MinGW). The only format seems to be elf.

That's my goal. For now, I have written the os not in c but in assembler, too. I have assembled the NASM bootloader and the NASM os into two elf objects with the switch -w+gnu-elf-extensions on. (For the bootloader and the os I used the NASM directive BITS 16.) But if I try to link with ld I get a failure.

Can you help me further?

Thanks,

Steffen

nobody

  • Guest
Re: relocation truncated to fit
« Reply #3 on: September 10, 2006, 10:01:28 AM »
I don't know if it counts as "help" or not... I can try to dissuade you... :)

Gcc seems like an odd choice of tool to write a 16-bit OS, but if you can get it to work, more power to ya! The 512 byte bootsector has to be flat binary, AFAIK, and really doesn't want to be "linked" with anything. It needs to load whatever runs next (the kernel, or a "second stage" loader is common). If this "next" thing is anything *but* flat binary, you'll need to provide the loader for it. No big deal, but tough to squeeze into 512 bytes - thus the "second stage".

What you might want to do is concatenate the bootsector and "next" file into a single file, so you can write it to disk (floppy, presumably?) in one go. "copy /b boot.bin+kernel.bin image.bin" will do that - no need for a linker. Another way to do this would be to, *after* your boot signature, "incbin 'kernel.bin'"... or 'kernel.exe' in whatever format you provide a loader for.

If you have in mind something more than that, I can't help you. The way I would do it (I am not writing an OS - not, Not, NOT - but, jeez, somebody's got to!), if I were doing it, would be to use a modification of Deb Wiles' bootsector. She reads FAT12 and loads LOADER.BIN and KERNEL.BIN. I modified it to load just LOADER.BIN (if we're going to load the kernel now, what's LOADER.BIN for???). I also modified it to load LOADER.BIN as if it were a .com file - at 100h into its segment. That way, I can test LOADER.BIN as a "dosless .com file" under dos, simply copy it to drive a:, and reboot to see if it *really* worked. I haven't gotten as far as actually loading a kernel - I lack the "high level overview" of what I'd want this OS to be. A more common approach is to use an emulator - Bochs, or similar - but I want to see it run on "real hardware". So my experience (limited) doing it "that way" may not be much help to you...

I assume we're talking about booting from a floppy. They tell me that computers don't even *have* floppies, these days. The modern way to boot and test an OS is from CDRW or a USB "pen". My machine has never booted from CD (although the bios offers to), currently I can't even *write* a CD, and I haven't got USB, so this stuff leaves me completely in the dust! "Creak, groan!"

Best,
Frank