Lệnh insmod trong Linux

Giới thiệu

Trong lab này, chúng ta sẽ khám phá lệnh insmod trong Linux, được sử dụng để chèn một kernel module vào kernel đang chạy. Kernel modules là các đoạn mã có thể được tải và gỡ tải vào kernel khi cần thiết, cung cấp thêm chức năng hoặc trình điều khiển. Chúng ta sẽ học cách biên dịch một kernel module đơn giản và sử dụng insmod để chèn nó vào kernel đang chạy.

Lab này bao gồm các bước sau: giới thiệu về lệnh insmod, biên dịch một kernel module và chèn một kernel module bằng insmod. Gói linux-headers-$(uname -r) là cần thiết để biên dịch kernel module và lệnh insmod được sử dụng để chèn module đã biên dịch vào kernel đang chạy.

Giới thiệu về lệnh insmod

Trong bước này, chúng ta sẽ khám phá lệnh insmod trong Linux, được sử dụng để chèn một kernel module vào kernel đang chạy. Kernel modules là các đoạn mã có thể được tải và gỡ tải vào kernel khi cần thiết, cung cấp thêm chức năng hoặc trình điều khiển.

Trước tiên, hãy kiểm tra phiên bản kernel hiện tại và các kernel modules có sẵn:

uname -r
lsmod

Ví dụ đầu ra:

5.15.0-58-generic
Module                  Size  Used by
nvme_core              102400  1
pci_stub                16384  1
vboxpci                 24576  0
vboxnetadp              45056  0
vboxnetflt              49152  0
vboxdrv               1028096  3 vboxnetadp,vboxnetflt,vboxpci

Lệnh lsmod liệt kê các kernel modules hiện đang được tải. Chúng ta có thể thấy rằng có một số modules liên quan đến VirtualBox, một phần mềm ảo hóa phổ biến.

Tiếp theo, hãy tạo một kernel module đơn giản. Tạo một file mới tên hello.c trong thư mục ~/project với nội dung sau:

#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple kernel module");

int init_module(void) {
    printk(KERN_INFO "Hello, kernel!\n");
    return 0;
}

void cleanup_module(void) {
    printk(KERN_INFO "Goodbye, kernel!\n");
}

Module này chỉ đơn giản là in ra thông báo "Hello, kernel!" khi nó được tải và thông báo "Goodbye, kernel!" khi nó được gỡ tải.

Bây giờ, hãy biên dịch kernel module:

sudo apt update
sudo apt-get install -y linux-headers-$(uname -r)
gcc -Wall -DMODULE -D__KERNEL__ -I/lib/modules/$(uname -r)/build/include -c hello.c

Gói linux-headers-$(uname -r) chứa các file header cần thiết để biên dịch kernel modules cho phiên bản kernel hiện tại. Lệnh gcc biên dịch file hello.c thành một file object hello.o.

Với kernel module đã biên dịch, bây giờ chúng ta có thể sử dụng lệnh insmod để chèn nó vào kernel đang chạy:

sudo insmod hello.o

Ví dụ đầu ra:

Lệnh insmod tải module hello.o vào kernel. Bạn sẽ thấy thông báo "Hello, kernel!" trong nhật ký hệ thống (ví dụ: dmesg).

Để xác minh rằng module đã được tải, hãy chạy:

lsmod | grep hello

Ví dụ đầu ra:

hello                  16384  0

Đầu ra cho thấy rằng module hello hiện đã được tải trong kernel.

Biên dịch một Kernel Module

Trong bước này, chúng ta sẽ học cách biên dịch một kernel module từ mã nguồn.

Trước tiên, hãy tạo một file kernel module mới tên hello2.c trong thư mục ~/project với nội dung sau:

#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Another simple kernel module");

int init_module(void) {
    printk(KERN_INFO "Hello, from the second kernel module!\n");
    return 0;
}

void cleanup_module(void) {
    printk(KERN_INFO "Goodbye, from the second kernel module!\n");
}

Module này tương tự như module chúng ta đã tạo trong bước trước, nhưng với một thông báo khác.

Bây giờ, hãy biên dịch module hello2.c:

gcc -Wall -DMODULE -D__KERNEL__ -I/lib/modules/$(uname -r)/build/include -c hello2.c

Quá trình biên dịch tương tự như trước, ngoại trừ việc chúng ta đang biên dịch file hello2.c thay vì hello.c.

Sau khi biên dịch, bạn sẽ thấy file object hello2.o trong thư mục ~/project.

Chèn một Kernel Module bằng insmod

Trong bước này, chúng ta sẽ học cách chèn kernel module đã biên dịch vào kernel đang chạy bằng lệnh insmod.

Trước tiên, hãy đảm bảo rằng module hello2.o đã được biên dịch và có sẵn trong thư mục ~/project:

ls -l ~/project/hello2.o

Ví dụ đầu ra:

-rw-r--r-- 1 labex labex 16384 Apr 11 12:34 /home/labex/project/hello2.o

Bây giờ, chúng ta có thể sử dụng lệnh insmod để chèn module hello2.o vào kernel:

sudo insmod ~/project/hello2.o

Ví dụ đầu ra:

Lệnh insmod tải module hello2.o vào kernel. Bạn sẽ thấy thông báo "Hello, from the second kernel module!" trong nhật ký hệ thống (ví dụ: dmesg).

Để xác minh rằng module đã được tải, hãy chạy:

lsmod | grep hello2

Ví dụ đầu ra:

hello2                 16384  0

Đầu ra cho thấy rằng module hello2 hiện đã được tải trong kernel.

Tóm tắt

Trong lab này, chúng ta đã khám phá lệnh insmod trong Linux, được sử dụng để chèn một kernel module vào kernel đang chạy. Đầu tiên, chúng ta đã kiểm tra phiên bản kernel hiện tại và các kernel modules có sẵn bằng các lệnh uname -rlsmod. Sau đó, chúng ta đã tạo một kernel module đơn giản in ra thông báo "Hello, kernel!" khi được tải và thông báo "Goodbye, kernel!" khi được gỡ tải. Chúng ta đã biên dịch kernel module bằng lệnh gcc và gói linux-headers-$(uname -r), chứa các file header cần thiết cho phiên bản kernel hiện tại. Cuối cùng, chúng ta đã sử dụng lệnh insmod để chèn kernel module đã biên dịch vào kernel đang chạy.

400+ câu lệnh phổ biến trong Linux