2015-12-22 6 views
0

Мне очень нравится функция linux kernel module_init, я хотел бы реализовать ту же функцию для своих приложений пользовательского пространства.Реализовать аналогичный module_init как ядро ​​Linux, но встретить некоторые проблемы в сценарии ld

Я пытаюсь изменить компоновщика скрипт, чтобы сделать это:

1, скопировать x86-64 стандартный Л.Д. скрипт

2, добавьте мой заказной раздел

.module.init   : 
    { 
    PROVIDE_HIDDEN (__module_init_start = .); 
    *(.module_init*) 
    PROVIDE_HIDDEN (__module_init_end = .); 
    } 

3, положить init функция указатель в moudle_init раздел

#define app_module_init(x) __initcall(x); 
#define __initcall(fn) \ 
      static initcall_t __initcall_##fn \ 
      __attribute__ ((__section__(".module_init"))) = fn 

app_module_init(unit_test_1_init); 
app_module_init(unit_test_2_init); 
app_module_init(unit_test_3_init); 
app_module_init(unit_test_4_init); 

4, скомпилируйте приложение с пользовательским роскопию линкер скрипт (на основе стандартного)

gcc -o "./module_init" -T module.lds ./module_init.o 

5, Тогда я objdump в moudle_init, я обнаружил, секция генерируется:

Disassembly of section .module_init: 

0000000000a01080 <__initcall_unit_test_1_init>: 
    a01080: ad      lods %ds:(%rsi),%eax 
    a01081: 05 40 00 00 00   add $0x40,%eax 
    ... 

0000000000a01088 <__initcall_unit_test_2_init>: 
    a01088: c2 05 40    retq $0x4005 
    a0108b: 00 00     add %al,(%rax) 
    a0108d: 00 00     add %al,(%rax) 
    ... 

0000000000a01090 <__initcall_unit_test_3_init>: 
    a01090: d7      xlat %ds:(%rbx) 
    a01091: 05 40 00 00 00   add $0x40,%eax 
    ... 

0000000000a01098 <__initcall_unit_test_4_init>: 
    a01098: ec      in  (%dx),%al 
    a01099: 05 40 00 00 00   add $0x40,%eax 

Но __module_init_start и __module_init_end переменная не значение я ожидается. В моем случае __module_init_start - 0x4005ad, а __module_init_end - 0x400000003. Это очень странно, потому что 0x4005ad - это адрес __initcall_unit_test_1_init.

Кто-нибудь может дать мне представление о том, как сделать это пространство пользователя module_init?

+0

Это «проводной» или «странный»? – Downvoter

+0

Вы просматриваете адреса __module_init_start/end или их значения? Сценарий компоновщика задает адреса. – immibis

+0

Мне никогда не приходилось использовать специальный скрипт компоновщика для этого: http://stackoverflow.com/questions/11840651/how-can-i-implement-a-dynamic-dispatch-table-in-c/11844418# 11844418 – Art

ответ

1

Сценарий компоновщика может устанавливать только адреса переменных. Используйте &__module_init_start, чтобы получить указатель на начало раздела, и &__module_init_end, чтобы получить указатель до конца.

+0

Да, вы правы, я очень благодарен! – user14944