kernel-header v. os-header

  • Hallo Zusammen,
    vorgestern habe ich im Brustton der Überzeugung Chopperhead erklärt, dass man natürlich gegen die "richtigen" Header (in dem konkreten Fall die Header aus media_build_experimental) bauen muss. Je länger ich darüber nachdenke, um so unsicherer werde ich mir, was denn die "richtigen" Header sind.


    Ich kann mich erinnern, das es vor gaaaanz langer Zeit mal so war, dass man nach einem Kernel-Update ein make header_install gemacht hat, und dann die libc neu gebaut hat. Das target im Kernel-Source gibt es auch noch, und die Doku ebenso (linux-src/Documentation/make/headers_install.txt). Nur macht das heute keiner(?) mehr. Die Distributionen (hier gentoo) bringen ein Paket linux-headers mit, gegen das dann glibc (oder ulibc oder was auch immer der jeweilige Distributor für angebracht hält) gebaut wird (gentoo) oder - bei Binär-Distributionen) gebaut wurde (passend zum header-Paket).


    Wie auch immer, es gibt also nicht mehr nur die kernel-Header, sondern ein generischeres Header-Paket (dass vermutlich auch irgendwie aus den mit make header_install exportierten Linux-Quellen gemacht wurde), das von glibc an aufwärts den gesamten Userspace glücklich macht. Die Kernel-Doku sagt, dass diese Headers rückwärts- aber nicht vorwärtskompatibel sind, also mit alten Headern gebaute Progis mit einem neueren Kern (also neueren Kernel-Headern) noch laufen. Das erklärt auch, warum bisweilen die Version von (unter Gentoo) latest stable kernel und latest stable linux-headers auseinanderlaufen können. Klar, dass man mit älteren Headern neue Features nicht benutzen kann - klar aber auch, dass Programme bzw. die libc nicht nach jedem Kernel-Update neu gebaut werden müssen. Na, ja, oder vieleicht unter bestimmten umständen doch???


    Ebenso klar ist mir, dass das alles nur für den Userspace gilt. Hier hat eben eine gewisse Entkopplung vom Kern stattgefunden, so dass jeder über den Weg libc und stdc (gcc) kernel-Features nutzen kann und solch lustige Dinge wie dynamisches nachladen von Programmcode hinbekommt. Für Treiber sieht das anders aus. Vereinfacht ausgedrückt findet hier das "dynamische Nachladen von Programmcode" ja direkt in Interaktion mit de Kern statt (modprobe/insmod), und deshalb muss der Treiber ja auch die Kernel-Sourcen (bzw. Header) kennen (z.B. nvidia-Treiber).


    Jetzt kommt ufo daher, und sagt sich, warum soll ich die Armen mit den alten Kernen eigentlich von meiner Treiberentwicklung ausschließen? (OT: Danke dafür!) Und macht einen "Backport". Die Treiber sind aber eben nicht im Userspace, und außerdem sagt die Kernel Doku ganz klar, dass die Header rückwärts-, aber nicht vorwärts kompatibel sind. Was bleibt also anders übrig, als für die gegen neue Header entwickelten Treiber auch MIT diesen neuen Headern zu bauen. Da diese aber Rückwärtskompatibel sind, sollten ja alle Programme die gegen die älteren Header gebaut sind noch laufen - solange sie keine neuen Features, die erst mit den neuen Headern implementiert wurden nutzen.


    Alles was jetzt kommt ist deshalb besonders objectiv, weil es nicht von Fachwissen getrübt wird...


    Der VDR benötigt gewisse Features des Kerns (hier eben der dvb-Treiber) und fragt deshalb die APIVERSION ab, und spielt eben nicht mehr weiter mit, wenn diese Unterschritten wird. Halbwegs aktueller Kern und linux-headers und alles ist gut. Wenn man dahinter liegt, nimmt man jetzt ufos Treiber, baut gegen die von den Treibern mitgebrachten Header, und es ist ebenfalls alles gut.


    Hat man aber eine Kernel-Header-Kombination, die neu genug für vdr ist, will aber trotzdem ufos Treiber benutzen, welche Header sind dann die "Richtigen"? Ufos Header sind ja - nach Kernel-Doku-Definition - rückwärtskompatibel (also laufen Programme, die gegen ältere Header gebaut sind auch noch), und der vdr ist mit der APIVERSION der OS-Header zufrieden (also nutzt er ja keine Features, die seit dieser APIVERSION dazu gekommen sind - oder doch?), kann man das dann einfach so lassen?


    Und was passiert wenn man jetzt Header mischt? Aus Sicht des VDR-Binaries: es ist gegen glibc mit alten Headern gelinkt, es benutzt aber selbst -I$(DVBDIR), und weil wir im Makeprozess nicht genügend wachsam waren, werden Plugins geladen, die über includes auf vdr-header-Dateien dvb-Treiber-Header includieren, die wiederum gegen den alten Headerstand laufen, weil das -I$(DVBDIR) nicht ins allerletzte unter/unter-Verzeichnis durch gereicht wurde. Und was ist mit der Auflösung der Dependencies? Mir ist erst nachdem ich die "# error: wrong DVBDIR"-Zeile in die (älteren) os-Header eingebaut habe afgefallen, dass ALLE(!) MAKEEDEP-Aufrufe ALLER(!) Plugins IMMER(!) gegen die alten Header laufen(*).


    Ich hoffe irgendein Kernel-/C-/Make-Guru kann mir das erklären, weil ich die Zusammenhänge verstehen will.


    Ganz pragmatisch bewegen mich diese Fragen:


    - Ab welcher linux-Header-Version kann man -I$(DVBDIR) bei der Verwendung von media_build_experimental einfach weglassen? Kann man das überhaupt?
    - Wenn man vdr gegen die neuen Header bauen muss (weil letzte Frage mit "nein" beantwortet, bzw. API-Version der installiert os-header nicht ausreichend), wie bekommt man -I$(DVBDIR) überall hin durchgereicht?(*)
    Oder kurz: Was sind denn nun die "richtigen Header"? ;)


    Gruß, Ingo


    (*) Ich habe bei mir ganz brutal in Make.config CXX += -I$(DVBDIR) gesetzt - dann klappts auch mit den MAKEDEP...

  • Die header auf dem System müssen hundertprozentig zur verwendeten glibc passen, d.h. es müssen die header auf dem system sein, die zum compilieren der glibc damals verwendet wurden.
    Wenn das nicht so ist, compiliert u.U. neuer source code, bringt aber beim Linken Fehler oder beim Ausführen Fehler.


    Im Falle der dvb header ist das irrelevant, da die glibc keine symbole aus den dvb headern verwendet.

  • VDR muß gegen die DVB-Header kompiliert werden, deren zugehörige Treiber im System laufen.
    Das ist nicht verhandelbar [tm].


    D.h. "/usr/include/linux/dvb", falls man die Treiber des Kernels verwendet, ansonsten die Header des Treiberpakets (media_build, media_build_experimental etc.).


    CU
    Oliver

  • Ja schön. Aber an dem DVB-Headerzeug ändert sich nichts.


    Ist doch einer der Grundsätze von Linus Torvalds.


    Das ist falsch.


    APIs dürfen selbstverständlich erweitert werden!
    Es muß jedoch gewährleistet werden, daß alte Applikationen _unverändert_ weiter laufen.
    Kein Problem, falls der Maintainer mindestens Brain 1.0 hat.


    CU
    Oliver

  • VDR muß gegen die DVB-Header kompiliert werden, deren zugehörige Treiber im System laufen.
    Das ist nicht verhandelbar [tm].



    Das ist nur dann nötig, wenn


    a) die header des verwendeten Treibers nicht mehr abwärtskompatibel sind (und das sollten Treiber-Entwickler um jeden Preis vermeiden)
    oder
    b) neuere features in der Anwendung benötigt werden, die in den kernel headern noch nicht enthalten sind.



    Grundsätzlich hast du nat. recht.

  • VDR muß gegen die DVB-Header kompiliert werden, deren zugehörige Treiber im System laufen.
    Das ist nicht verhandelbar [tm].


    Das ist aber rein praktisch nicht durchführbar. Jedenfalls nicht bei Distributionen die Binärpakete ausliefern.


    Beispiel Debian/Ubuntu, das liefert das fertige VDR Paket und der User installiert sich irgendeinen Kernel (mit dem dann auch der DVB Treiber kommt). Oder er installiert das media-build-dkms Paket.


    Wie machen das andere Programme die irgendwelche DVB Header nutzen?


    cu

  • Wenn man VDR gegen einen älteren Stand des DVB-API übersetzt, kann man neue Funktionen nicht nutzen.
    Mit einer solchen Einschränkung muß man dann halt leben.


    Da das neue API hoffentlich rückwärtskompatibel ist, funktioniert es trotzdem.


    Dennoch muß es möglich sein, VDR gegen andere Header zu kompilieren.
    (Das ist alles, was mich in diesem Zusammenhang interessiert.)


    CU
    Oliver

  • Moin!


    Ist das ganze nicht "nur" ein Problem von Distributionen, die einen "zu alten" Kernel einsetzen?


    Beispiel: yaVDR mit Ubuntu 12.04 setzt 3.2 ein, da ist die DVB-Version neu genug für den vdr, weshalb es egal sein sollte, ob er gegen linux-headers oder media_build(_experimental) gebaut wird, weil die neueren Header von media_build keine neuen Features beinhalten, die der vdr braucht.


    Der vdr muss also nur auf solchen Systemen gegen die Header des installierten Treibers übersetzt werden, wenn die Kernel-Header diese Features noch nicht unterstützen.


    Beispiel: das momentane Debian stable (6.0 squeeze) setzt Kernel 2.6.32 ein, dessen DVB-API-Version zu alt ist. Deshalb baut der vdr auf diesem System nicht mehr. Darum gibt es die Treiberpakete. Und wenn man den vdr nutzen will, muss man ihn gegen die Treiber-Header bauen, denn gegen die Kernel-Header kann er ja nicht bauen.


    Mein Fazit:
    Im Normalfall sind die Treiber-Header vollkommen egal. Es gibt nun manchmal eben neue Features in einer Anwendung, die eine gewisse Mindestversion der benutzten Komponenten voraussetzt. Und wenn die eben nicht gegeben sind, kann das Programm nicht funktionieren. Wenn man es in einer solchen Umgebung zum Laufen bringen möchte, muss man alle entsprechenden Stellen (und sei es nur das Makefile mit DVBDIR) anfassen.
    Wenn der vdr also ein Feature mitbringt, gegen beliebige DVB-Header zu kompilieren, dann ist das nett und schön. Macht das Leben der Leute einfacher, die "zu alte" Mindestvoraussetzungen benutzen. Rein aus vdr-Sicht ist es aber (meiner Meinung nach) kein notwendiges Feature. Es ist nur dann sinnvoll, dieses zu haben, wenn der vdr die Chance haben soll, am "Puls der DVB-Entwickler" zu bleiben...


    Es gibt ja z.B. auch noch den s2api-wrapper-Patch. Der funktioniert quasi anders herum: es wird alles nachgerüstet, was den alten DVB-Headern fehlt.


    Lars.

  • OK. Ich kann mit der nicht verhandelbaren Aussage leben.


    Kommen wir damit also zu Teil zwei meiner Frage: Wie bekommen wir die INCLUDES durchgereicht in die Plugins - insbesondere in MAKEDEP? Da gibts doch bestimmt schon was - denn sonst Wären ja in der Vergangenheit ALLE Dependencies bei der Verwendung von kernelfremden Treibern falsch erzeugt worden... UFO: ich benutze Deine Treiber erst seit 1.7.34. Hast Du für die von Dir benutzten Plugins jeweils fas MAKEDEP angepasst? Oder wie machst Du das?


    Und nochmal die Frage: Welche Treiberfunktionen benutzt der vdr, die in der abgefragten APIVERSION nicht enthalten sind, aber in media_build_experimental neu eingefügt wurden?


    Gruß, Ingo

  • Beispiel: das momentane Debian stable (6.0 squeeze) setzt Kernel 2.6.32 ein, dessen DVB-API-Version zu alt ist. Deshalb baut der vdr auf diesem System nicht mehr.


    Jup, verwirrend das alles sein ;)



    Und 3.2.18-1~bpo60+1 liefert in /usr/include/linux/dvb/version.h
    ---
    #define DVB_API_VERSION 5
    #define DVB_API_VERSION_MINOR 4
    ---


    Was für ein Kernel da drauf ist ist also auch hier egal, der aktuelle VDR baut auf squeeze immer wenn man die Backports drin hat.



    Wobei klar, die Makefiles sollten die Möglichkeit geben andere DVB Header nach Wunsch korrekt einzubinden.


    cu


  • Kommen wir damit also zu Teil zwei meiner Frage: Wie bekommen wir die INCLUDES durchgereicht in die Plugins - insbesondere in MAKEDEP? Da gibts doch bestimmt schon was - denn sonst Wären ja in der Vergangenheit ALLE Dependencies bei der Verwendung von kernelfremden Treibern falsch erzeugt worden... UFO: ich benutze Deine Treiber erst seit 1.7.34. Hast Du für die von Dir benutzten Plugins jeweils fas MAKEDEP angepasst? Oder wie machst Du das?


    Ist mir auch erst im Zuge der Makefile-Diskussion aufgefallen, daß
    (a) VDR nicht gegen media_build_experimental gebaut wurde
    (b) VDR die Dependencies immer gegen /usr/include/linux/DVB baut
    (c) dvbhddevice nicht gegen media_build_experimental gebaut wurde (was kurioserweise gut geht, da es im Plugin fragwürdige #ifndef-Anweisungen gibt)
    (d) Alle Plugins die Dependencies gegen /usr/include/linux/DVB bauen.


    Vorschlag[*]:
    - Das DVB-Verzeichnis optional den CFLAGS/CXXFLAGS hinzufügen.
    - Bei MAKEDEP auch CXXFLAGS verwenden.


    Zitat


    Und nochmal die Frage: Welche Treiberfunktionen benutzt der vdr, die in der abgefragten APIVERSION nicht enthalten sind, aber in media_build_experimental neu eingefügt wurden?


    Derzeit nur eine API-Erweiterung für dvbhddevice.


    CU
    Oliver


    [*] Ihr könnt es natürlich auch wieder beliebig kompliziert machen. :)

  • Dann haben diejenigen, die Debian Stable einsetzen eben Pech.


    Nur weil eine Distribution es nicht auf die Reihe bringt aktuell zu bleiben... Selbst Slackware, was ich bisher immer als die konservativste Distri unter den Konservativen gesehen habe, hat einen 3.2er Kernel.


    Ich selbst werde da wohl dank Archlinux die wenigsten Probleme haben (3.6er Stable, 3.7er im Testing)

  • Dann haben diejenigen, die Debian Stable einsetzen eben Pech.


    Wie ich weiter oben schon detaliert schrieb ;) hat Debian Stable nicht die geringsten Probleme mit dieser Sache.


    Aber das ist ja gar nicht das Thema, entweder die VDR Makefiles erlauben das bauen gegen alternative DVB Header (dann aber richtig) oder eben nicht.


    Ich selbst werde da wohl dank Archlinux die wenigsten Probleme haben (3.6er Stable, 3.7er im Testing)


    Naja, wie wir festgestellt haben spielt die Kernelversion ja nun überhaupt keine Rolle. Das ist ja gerade der Witz an der Sache, per Default wird gegen die Header des libc Dev Packetes gebaut. Und die hängen vermutlich auf keiner Distribution vom gerade zufällig installierten Kernel ab.


    cu

  • Was meinst denn du, was los wäre, wenn ich das aus den Makefiles rausschmeiße... Ich habe ja jetzt schon den schlimmsten Krieg heraufbeschworen.


    Ich empfinde das nicht als Krieg. Ist doch zur Zeit sehr produktiv - wenn ich da an die esrten beiden Tgae nach 1.7.34 denke...


    OK, wir wollen also sauber gegen andere DVB Header bauen. Daraus folgt, das im Falle eines gesetzten DVBDIR in Make.config folgendes gewährleistet werden muss:


    1. gcc und g++ müssen mit zusätzlich

    Code
    -D__user= -D__u8=uint8_t -I/usr/local/src/media_build_experimental/linux/include/uapi

    aufgerufen werden.
    2. MAKEDEP (also "g++ -MM -MG) muss zusätzlich mit

    Code
    -I/usr/local/src/media_build_experimental/linux/include/uapi

    aufgerufen werden.


    1. altes Makefile:
    Da die alten Makefiles Make.config includen kann man CFLAGS (bzw. CXXFLAGS) um "-D__user= -D__u8=uint8_t" ergänzen und INCLUDES um -I$(DVBDIR). Im eigentlichen makedep wird INCLUDES ja referenziert - in den g++ Aufrufen ja eh.
    2. neues Makefile
    Hier habe wir ein Plroblem, zwar haben wir nach den Anpassungen in Make.config für DVBDIR "-D__user= -D__u8=uint8_t -I/usr/local/src/media_build_experimental/linux/include/uapi" in der vdr.pc in cflags und cxxflags, aber die neuen Plugin-Makefiles benutzen in ihrem "@$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@" keine Variable, die aus vdr.pc belegt wird.


    Selbst dem Vorschlag von UFO folgend, läuft das MAKEDEP in /usr/include/linux/dvb... Ich habe in den letzten Tagen (zum Leidwesen von Chopperhead - ich will wirklich keinen Krieg, ganz im Gegenteil) versucht, irgendwie in Make.config und Makefile zu umgehen - das war Brotlos.


    Die neuen Plugin-Makefiles müssen angefasst werden. Da kann man entweder CXXFLAGS an MAKEDEPEND anhängen, oder - und das ist sauberer; anfassen muss man sie ja eh nochmal - in die neuen PLUGIN-Makefiles muss ein

    Code
    (shell pkg-config --cflags-only-I vdr)

    (oder ein entsprechendes MAKRO, das drei verschiedene vdr.pc Verotungen abklappert) an MAKEDEPEN angehängt werden. Mann könnte es auch in INCLUDES scheiben, aber dann stehts bei den normale g++ Aufrufen zwei mal da (ist ja schon in CFLAGS.


    Gruß, Ingo

  • Offtopic:

    zum Leidwesen von Chopperhead - ich will wirklich keinen Krieg


    Nur mal zur Info: er nennt sich Copperhead... :) Da ich das jetzt schon mehrmals in deinen Beiträgen gelesen habe, dachte ich, ich erwähn's mal...


    Lars.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!