Merge several libs into a single one
Page 1 of 1

Author:  iliak [ Tue Nov 26, 2019 12:00 pm ]
Post subject:  Merge several libs into a single one

My project is to generate a binary file for reading by a motorola 680x0. The idea is to make a ROM inspired by the model of Amiga, ie the kernel is composed of multiple libraries. For this, first a few context elements:

- GNU m68k-elf-*
- CMake 3.x
- the projet structure :
   ├── bootstrap
   │ └── bootstrap.s
   ├── devices
   │ ├── input.device
   │ └── serial.device
   └── libraries
     ├─ dos.library
     ├─ exec.library
     └─ graphics.library

src/bootstrap/bootstrap.s contains the assembler code to handle the startup of the 680x0 and the directories devices/ and libraries/ contain the sources of the different "modules". For more details: https://gitlab.mimicprod.net/os/miga.

I use CMake to make static libraries, which gives me a libXXXXXX.a for each module and bootstrap, all in ELF format. Now, I want to put all these .a in one file (ELF or binary). For that, I have this file for the linker:

    ram (rwx): ORIGIN = 0x0, LENGTH = 15M
    rom (rx): ORIGIN = 0xF00000, LENGTH = 1M

PROVIDE (_stack = ORIGIN(ram) + LENGTH(ram));

ENTRY (_reset_handler);

    .text : {
        . = ALIGN(4);
    } >rom

The problem is that the produced file contains only the code source of bootstrap.s and no trace of the other dependencies.

A small idea of ​​how to merge all the code into a single file (ELF or binary) while managing the relocations ?

Is generating static libraries the correct process, would shared libraries be more appropriate ?

Author:  Solar [ Wed Nov 27, 2019 3:59 am ]
Post subject:  Re: Merge several libs into a single one

The tool to handle static linker archives (.a) is ar. You don't use the linker (ld) for this at all, and you don't need a linker script. You need the linker only for the final step, creating the final binary.

But I would like to take you a step backward on your general concept, because I happen to know a thing or two about AmigaOS. You're setting out to link the devices and libraries into the kernel binary, and I can't help but think that you might have gotten things backwards a bit.

The thing about the AmigaOS kernel -- Exec.Library -- was that it was a microkernel. It did not "consist of multiple libraries" at all! Instead, it provided layers of messaging primitives, one implemented on top of each other in a pseudo-OO way (as the kernel was written in C, not C++):

  • A List was a specialization of a Node was a specialization of a MinNode.
  • A Semaphore was a specialization of a Msgport was a specialization of a Node...
  • An IORequest was a specialization of a Message was a specialization of a Node...
  • A Device was a specialization of a Library was a specialization of a Node...
  • A Process was a specialization of a Task was a specialization of a Node...

You get the idea.

These messaging primitives were then used by the various components of the operating system -- DOS.Library et al. -- to implement their services, reducing duplication of functionality. This is one of the things that made AmigaOS so lean: You didn't have to implement stuff like lists over and over and over, because the kernel provided them.

Libraries, Devices, and Resources were loaded dynamically as and when needed. This made administrating AmigaOS a breeze: You added new hardware, dropped the NewHardware.devices to SYS:Devs/, and a config to SYS:Devs/DOSDrivers (which would tell the OS which *.device to load and use), and there you go. If you don't want to activate a device at boot, there's SYS:Storage/DOSDrivers to "park" your activation config.

If you want to capture some of what made AmigaOS so special, I suggest you check out this document archived at the Wayback machine, which describes Amiga Exec in some detail. You're missing out if you don't!

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group