KernelNewbies
  • Comments
  • Immutable Page
  • Menu
    • Navigation
    • RecentChanges
    • FindPage
    • Local Site Map
    • Help
    • HelpContents
    • HelpOnMoinWikiSyntax
    • Display
    • Attachments
    • Info
    • Raw Text
    • Print View
    • Edit
    • Load
    • Save
  • Login

Kernel Hacking

  • Frontpage

  • Kernel Hacking

  • Kernel Documentation

  • Kernel Glossary

  • FAQ

  • Found a bug?

  • Kernel Changelog

  • Upstream Merge Guide

Projects

  • KernelJanitors

  • KernelMentors

  • KernelProjects

Community

  • Why a community?

  • Regional Kernelnewbies

  • Personal Pages

  • Upcoming Events

References

  • Mailing Lists

  • Related Sites

  • Programming Links

Wiki

  • Recent Changes

  • Site Editors

  • Side Bar

  • Tips for Editors

  • Hosted by WikiWall

Navigation

  • RecentChanges
  • FindPage
  • HelpContents
Revision 2 as of 2017-12-30 01:29:57
KernelNewbies:
  • InitcallMechanism
  • KernelToCode

What we have discovered is not just an understanding of how the Linux kernel works, but also a solution for creating a compile-time list of function pointers which call be called in the order they are initialized. Taking the code from the previous section and making it more stand-alone and general purpose we end up with the following: (notice how no linker script is required)

/*
 * Copyright (C) 2006  Trevor Woerner
 */

#include <stdio.h>

typedef void (*funcptr_t)(void);
extern funcptr_t __start_newsect, __stop_newsect;

#define data_attr         __attribute__ ((section ("newsect")))
#define create_entry(fn)  funcptr_t _##fn data_attr = fn

void my_init1 (void) { printf ("my_init1() #1\n"); }
void my_init2 (void) { printf ("my_init2() #2\n"); }

create_entry (my_init1);
create_entry (my_init2);

int
main (void)
{
        funcptr_t *call_p;

        call_p = &__start_newsect;
        do {
                printf ("call_p: %p\n", call_p);
                (*call_p)();
                ++call_p;
        } while (call_p < &__stop_newsect);

        return 0;
}

Which generates:

[trevor@trevor code]$ make mycalls   
cc     mycalls.c   -o mycalls
[trevor@trevor code]$ ./mycalls 
call_p: 0x804960c
my_init1() #1
call_p: 0x8049610
my_init2() #2

and

0804830c g     F .text  00000000              _start
0804830c l    d  .text  00000000              .text
08048330 l     F .text  00000000              call_gmon_start
08048354 l     F .text  00000000              __do_global_dtors_aux
08048388 l     F .text  00000000              frame_dummy
080483b0 g     F .text  00000018              my_init1
080483c8 g     F .text  00000018              my_init2
080483e0 g     F .text  00000053              main
08048434 g     F .text  0000004f              __libc_csu_init
08048484 g     F .text  00000005              __libc_csu_fini
0804848c l     F .text  00000000              __do_global_ctors_aux
...
0804960c g       *ABS*  00000000              __start_newsect
0804960c g     O newsect        00000004              _my_init1
0804960c l    d  newsect        00000000              newsect
08049610 g     O newsect        00000004              _my_init2
08049614 g       *ABS*  00000000              __bss_start
08049614 g       *ABS*  00000000              __stop_newsect

Notice also how the my_initN() functions were put in the general .text segment since I don't really care where they end up (unlike the kernel guys).

  • MoinMoin Powered
  • Python Powered
  • GPL licensed
  • Valid HTML 4.01