Apakah faedah memperkenalkan mekanisme modul dalam linux?

青灯夜游
Lepaskan: 2023-04-06 15:28:34
asal
1328 orang telah melayarinya

Faedah memperkenalkan mekanisme modul dalam Linux: 1. Apabila aplikasi keluar, ia boleh mengabaikan pelepasan sumber atau kerja pembersihan lain, tetapi fungsi keluar modul mesti membuat asal dengan berhati-hati semua yang dilakukan oleh permulaan fungsi; 2 , Mekanisme ini membantu memendekkan kitaran pembangunan modul, iaitu, pendaftaran dan penyahpasangan adalah sangat fleksibel dan mudah.

Apakah faedah memperkenalkan mekanisme modul dalam linux?

Persekitaran pengendalian tutorial ini: sistem linux7.3, komputer Dell G3.

Apakah faedah memperkenalkan mekanisme modul dalam Linux?

Mula-mula, modul pradaftar sendiri untuk menyampaikan permintaan masa hadapan, dan kemudian fungsi permulaannya tamat serta-merta. Dalam erti kata lain, tugas fungsi permulaan modul adalah untuk menyediakan lebih awal untuk panggilan fungsi masa hadapan.

Faedah:

  • 1) Apabila aplikasi keluar, ia boleh mengabaikan pelepasan sumber atau kerja pembersihan lain, tetapi fungsi keluar modul mesti membatalkan dengan teliti pemulaan Semua yang dilakukan oleh fungsi.

  • 2) Mekanisme ini membantu memendekkan kitaran pembangunan modul. Iaitu: pendaftaran dan nyahpasang adalah sangat fleksibel dan mudah.

Analisis ringkas tentang mekanisme modul Linux

Linux membenarkan pengguna campur tangan dalam kernel dengan memasukkan modul. Mekanisme modul Linux tidak begitu jelas untuk masa yang lama, jadi artikel ini menganalisis secara ringkas mekanisme pemuatan modul kernel.

Helo Dunia modul!

Kami menguji dengan mencipta modul mudah. Yang pertama ialah fail sumber main.c dan Makefile.

florian@florian-pc:~/module$ cat main.c

#include<linux/module.h>
#include<linux/init.h>
 
static int __init init(void)
{
    printk("Hi module!\n");
    return 0;
}
 
static void __exit exit(void)
{
    printk("Bye module!\n");
}
 
module_init(init);
module_exit(exit);
Salin selepas log masuk

di mana init ialah fungsi kemasukan modul, yang dipanggil apabila modul dimuatkan, dan keluar ialah modul keluar fungsi, yang dilaksanakan dalam modul Pemunggahan dipanggil dan dilaksanakan.

florian@florian-pc:~/module$ cat Makefile

obj-m += main.o
#generate the path
CURRENT_PATH:=$(shell pwd)
#the current kernel version number
LINUX_KERNEL:=$(shell uname -r)
#the absolute path
LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)
#complie object
all:
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
#clean
clean:
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
Salin selepas log masuk

Antaranya, obj-m menentukan nama fail sasaran, dan nama fail perlu adalah sama dengan nama fail sumber (Kecuali sambungan) untuk memudahkan terbitan automatik dengan membuat.

Kemudian gunakan arahan make untuk menyusun modul dan dapatkan fail modul main.ko.

florian@florian-pc:~/module$ make

make -C /usr/src/linux-headers-2.6.35-22-generic M=/home/florian/module modules
make[1]: 正在进入目录 `/usr/src/linux-headers-2.6.35-22-generic&#39;
  Building modules, stage 2.
  MODPOST 1 modules
make[1]:正在离开目录 `/usr/src/linux-headers-2.6.35-22-generic&#39;
Salin selepas log masuk

Gunakan perintah insmod dan rmmod untuk memuatkan dan memunggah modul, dan gunakan dmesg untuk mencetak log kernel.

florian@florian-pc:~/module$ sudo insmod main.ko;dmesg | tail -1
[31077.810049] Hi module!
Salin selepas log masuk
florian@florian-pc:~/module$ sudo rmmod main.ko;dmesg | tail -1
[31078.960442] Bye module!
Salin selepas log masuk

Melalui maklumat log kernel, ia boleh dilihat bahawa kedua-dua fungsi masuk dan keluar modul telah Betul pelaksanaan panggilan.

Fail modul

Gunakan arahan readelf untuk menyemak maklumat fail modul main.ko.

florian@florian-pc:~/module$ readelf -h main.ko

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2&#39;s complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          1120 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         19
  Section header string table index: 16
Salin selepas log masuk

Kami mendapati bahawa jenis fail main.ko ialah fail sasaran yang boleh dipindahkan, yang berbeza daripada sasaran umum format fail. Kami tahu bahawa fail sasaran tidak boleh dilaksanakan secara langsung Ia perlu melalui proses peruntukan ruang alamat, resolusi simbol dan penempatan semula pemaut dan ditukar kepada fail boleh laku sebelum ia boleh dilaksanakan.

Jadi, selepas kernel memuatkan main.ko, adakah ia memautkannya?

Struktur data modul

Pertama, mari kita lihat struktur data kernel modul.

linux3.5.2/kernel/module.h:220

struct module
{
    ……
    /* Startup function. */
    int (*init)(void);
    ……
    /* Destruction function. */
    void (*exit)(void);
    ……
};
Salin selepas log masuk

Penunjuk fungsi init dan exit struktur data modul merekodkan fungsi masuk dan keluar modul yang kami takrifkan .

Pemuatan modul

Pemuatan modul diselesaikan dengan panggilan sistem kernel init_module.

linux3.5.2/kernel/module.c:3009

/* This is where the real work happens */
SYSCALL_DEFINE3(init_module, void __user *, umod,
       unsigned long, len, const char __user *, uargs)
{
    struct module *mod;
    int ret = 0;
    ……
    /* Do all the hard work */
    mod = load_module(umod, len, uargs);//模块加载
    ……
    /* Start the module */
    if (mod->init != NULL)
       ret = do_one_initcall(mod->init);//模块init函数调用
    ……
    return 0;
}
Salin selepas log masuk

Panggilan sistem init_module dilaksanakan oleh SYSCALL_DEFINE3(init_module...), yang mempunyai dua fungsi utama panggilan. load_module digunakan untuk memuatkan modul, dan do_one_initcall digunakan untuk memanggil semula fungsi init modul.

Pelaksanaan fungsi load_module ialah. Terdapat empat panggilan fungsi utama dalam fungsi load_module. copy_and_check menyalin modul dari ruang pengguna ke ruang kernel, layout_and_allocate memperuntukkan ruang alamat untuk modul, simplify_symbols melaksanakan resolusi simbol untuk modul dan apply_relocations melakukan penempatan semula untuk modul.

Ia boleh dilihat bahawa apabila modul dimuatkan, kernel melakukan proses pemautan untuk fail modul main.ko!

linux3.5.2/kernel/module.c:2864Bagi pelaksanaan fungsi do_one_initcall, ia agak mudah.

/* Allocate and load the module: note that size of section 0 is always
   zero, and we rely on this for optional sections. */
static struct module *load_module(void __user *umod,
                unsigned long len,
                const char __user *uargs)
{
    struct load_info info = { NULL, };
    struct module *mod;
    long err;
    ……
    /* Copy in the blobs from userspace, check they are vaguely sane. */
    err = copy_and_check(&info, umod, len, uargs);//拷贝到内核
    if (err)
       return ERR_PTR(err);
    /* Figure out module layout, and allocate all the memory. */
    mod = layout_and_allocate(&info);//地址空间分配
    if (IS_ERR(mod)) {
       err = PTR_ERR(mod);
       goto free_copy;
    }
    ……
    /* Fix up syms, so that st_value is a pointer to location. */
    err = simplify_symbols(mod, &info);//符号解析
    if (err < 0)
       goto free_modinfo;
    err = apply_relocations(mod, &info);//重定位
    if (err < 0)
       goto free_modinfo;
    ……
}
Salin selepas log masuk

Iaitu, fungsi kemasukan modul ini dipanggil.

linux3.5.2/kernel/init.c:673Penyahpasangan modul

int __init_or_module do_one_initcall(initcall_t fn)
{
    int count = preempt_count();
    int ret;
    if (initcall_debug)
       ret = do_one_initcall_debug(fn);
    else
       ret = fn();//调用init module
    ……
    return ret;
}
Salin selepas log masuk
Penyahpasangan modul diselesaikan dengan panggilan sistem kernel delete_module.

Lengkapkan fungsi fungsi eksport modul melalui pintu keluar panggil balik, dan akhirnya panggil free_module untuk menyahpasang modul.

Kesimpulan

Nampaknya modul kernel tidak misteri. Atur cara pengguna tradisional perlu disusun ke dalam atur cara boleh laku sebelum ia boleh dilaksanakan, manakala atur cara modul hanya perlu disusun ke dalam fail objek sebelum ia boleh dimuatkan ke dalam kernel Inti melaksanakan pautan ke modul dan menukarnya kepada kod boleh laku . Pada masa yang sama, semasa proses pemuatan dan pemunggahan kernel, fungsi kemasukan modul yang ditentukan pengguna dan fungsi keluar modul akan dipanggil semula melalui fungsi untuk melaksanakan fungsi yang sepadan.

Cadangan berkaitan: "Tutorial Video Linux"

Atas ialah kandungan terperinci Apakah faedah memperkenalkan mekanisme modul dalam linux?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan