Autor Thema: Problem mit externen Variablen (vom Linker erstellt)  (Gelesen 8271 mal)

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« am: 08. August 2013, 21:27 »
Hallo,
ich bin gerade dabei cdi_init() zu programmieren und bin auf folgendes Problem gestossen: Ich habe mir in Tyndur angeschaut, wie sie das so machen. Ich habe dort einige Teile übernommen nachdem ich verstanden habe, was diese machen. Nun bekomme ich aber zwei Fehlermeldungen vom Compiler:
undefined reference to `__start_cdi_drivers'
undefined reference to `__stop_cdi_drivers'
Die entsprechende Datei ist (cdi.c, nur der wichtigste Teil):
#include "cdi.h"

extern struct cdi_driver *__start_cdi_drivers;
extern struct cdi_driver *__stop_cdi_drivers;

cdi_list_t drivers;

void cdi_init()
{
struct cdi_driver **pdrv;
struct cdi_driver *drv;

drivers = cdi_list_create();

// Alle in dieser Binary verfuegbaren Treiber aufsammeln
for(pdrv = &__start_cdi_drivers; pdrv < &__stop_cdi_drivers; pdrv++)
{
drv = *pdrv;
if(drv->init != NULL)
{
drv->init();
cdi_driver_register(drv);
}
}
}
Ich habe schon alles versucht, bekomme aber den Fehler nicht weg. Ich habe auch schon mal diese zwei Variablen im Linkerscript definiert, hat aber nichts gebracht. Ich habe das so verstanden, dass diese zwei Werte vom Linker definiert werden oder nicht?

Hier noch das Linkerscript:
OUTPUT_FORMAT(elf64-x86-64)
OUTPUT_ARCH(i386:x86-64)
/*  Bei _start soll die Ausfuehrung losgehen */
ENTRY(_start)

/*
 * Hier wird festgelegt, in welcher Reihenfolge welche Sektionen in die Binary
 * geschrieben werden sollen
 */
SECTIONS
{
    /*
     * . ist die aktuelle Position in der Datei. Wir wollen den Kernel wie gehabt
     * an 1 MB laden, also muessen wir dort die erste Sektion hinlegen
     */
    . = 0x100000;
kernel_start = .;

    /*
     * Der Multiboot-Header muss zuerst kommen (in den ersten 8 kB).
     * Die Standardsektionen einfach hintereinander weg einbinden.
     */
    .text : {
        /*(multiboot) kein Multibootheader vorhanden.*/
        *(.text)
    }
    .data ALIGN(4096) : {
        *(.data)
    }
    cdi_drivers ALIGN(4096) : {
        *(cdi_drivers)
    }
    .rodata ALIGN(4096) : {
        *(.rodata)
    }
    .bss ALIGN(4096) : {
        *(.bss)
    }
kernel_end = .;
}

Ich hoffe ihr könnt mir helfen.
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 09. August 2013, 08:48 »
Wie sieht deine Deklaration von CDI_DRIVER() aus? Legst du dort die Variablen in der Section cdi_drivers an?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #2 am: 09. August 2013, 16:21 »
Die Definition von CDI_DRIVER() habe ich einfach aus Tyndur übernommen.
#define cdi_glue(x, y) x ## y
#define cdi_declare_driver(drv, counter) \
    static const void* __attribute__((section("cdi_drivers"), used)) \
        cdi_glue(__cdi_driver_, counter) = &drv;

#define CDI_DRIVER(name, drv, deps...) cdi_declare_driver(drv, __COUNTER__)
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 09. August 2013, 17:19 »
Also tyndur hat cdi_drivers überhaupt nicht im Linkerskript stehen. Das könnte eine Voraussetzung dafür sein, dass __start/stop_* überhaupt generiert werden, siehe http://sourceware.org/binutils/docs/ld/Orphan-Sections.html (da steht zwar nicht, dass das sonst nicht passiert, aber eben, dass es bei solchen Sections passiert)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #4 am: 09. August 2013, 17:38 »
Danke vielmals für deine Hilfe.
Also gibt es zwei Möglichkeiten:
  • Dass man diese zwei Werte im Linkerscript selbst definiert.
  • Dass man im Linkerscript nichts von der Sektion cdi_drivers hinschreibt.
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

 

Einloggen