• [^] # Re: Fort intéressant...

    Posté par . En réponse à la dépêche L'évolution de Fastboot. Évalué à 6.

    Tout à fait.
    Le __init est un raccourci pour dire que le code de la fonction appartient à la section .init.text, permettant ainsi de libérer cette mémoire après l'appel de ces fonctions qui ne seront plus utilisées.

    Là où se joue l'ordre d'appel c'est à la définition du device_initcall(fonction).

    Voici un extrait de include/linux/init.h

    #define __define_initcall(level,fn,id) \
    static initcall_t __initcall_##fn##id __used \
    __attribute__((__section__(".initcall" level ".init"))) = fn

    /*
    * Early initcalls run before initializing SMP.
    *
    * Only for built-in code, not modules.
    */
    #define early_initcall(fn) __define_initcall("early",fn,early)

    /*
    * A "pure" initcall has no dependencies on anything else, and purely
    * initializes variables that couldn't be statically initialized.
    *
    * This only exists for built-in code, not for modules.
    */
    #define pure_initcall(fn) __define_initcall("0",fn,0)

    #define core_initcall(fn) __define_initcall("1",fn,1)
    #define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
    #define postcore_initcall(fn) __define_initcall("2",fn,2)
    #define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
    #define arch_initcall(fn) __define_initcall("3",fn,3)
    #define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
    #define subsys_initcall(fn) __define_initcall("4",fn,4)
    #define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
    #define fs_initcall(fn) __define_initcall("5",fn,5)
    #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
    #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
    #define device_initcall(fn) __define_initcall("6",fn,6)
    #define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
    #define late_initcall(fn) __define_initcall("7",fn,7)
    #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)


    Le level définit l'ordre d'appel. Plus il est petit, plus l'appel se fait au début.
    On commence par les early_initcall (avant que le multiprocesseur soit activé).
    Ensuite viennent les fonctions du coeur du noyau, puis les éléments relatifs à l'architecture, puis les sous-systèmes, puis le système de fichier, etc....

    Ce qui donnera une section .initcall0.init pour les pure_initcall, .initcall1.init pour le coeur du noyau etc....

    Et voilà, les pointeurs de fonctions seront regroupés par sections et rangés dans le bon ordre :-)