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

Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

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