یوشا

دست نوشته ها و تجربیات شخصی

یوشا

دست نوشته ها و تجربیات شخصی

شهید دکتر مصطفی چمران: می گویند تقوا از تخصص لازمتر است، آنرا می پذیرم، اما می گویم آنکس که تخصص ندارد و کاری را می پذیرد بی تقواست!

طبقه بندی موضوعی

 

در ادامه مقاله قبلیم(12 سال پیش!) که ماژول Kernel لینوکس رو تعریف کردم، در این مقاله به نوشتن ماژول برای Kernel لینوکس می پردازم.

در این مقاله، به صورت ساده یاد می‌ گیریم که چگونه یک ماژول Hello World برای کرنل Linux بنویسیم، کامپایل و اجرا کنیم... و همه اینها بر پایه توزیع های معروف مثل Debian, RedHat و Slackware انجام میدیم.

 

ماژول های هسته لینوکس

هسته لینوکس / Linux kernel قلب سیستم‌ عامل لینوکس است و مسئول مدیریت منابع سخت‌ افزاری، ارتباط با سخت‌ افزار و اجرای برنامه‌ هاست. هسته لینوکس به صورت ماژولار طراحی شده، یعنی بسیاری از قابلیت‌ های آن به صورت فایلهای جدا و Load شدنی (Loadable Kernel Modules - LKM) پیاده‌ سازی می‌ شوند.

ماژول های هسته Linux دارای چند نوع هستند:  ماژول‌ های درایور دستگاهها (Device drivers)، ماژول‌ های فایل سیستم (Filesystem)، ماژول‌ های شبکه (Network)، ماژول‌ های امنیتی (Security) و ماژول‌ های مدیریت حافظه و پردازش (Memory & process management). این ماژول ها باعث اضافه شدن feature در هسته، افزایش کارایی، سفارشی‌ سازی آسان و نگهداری ساده‌ تر خود هسته می‌ شوند.

 

پیش‌ نیازها برای توزیع‌ های مختلف

جهت توسعه و تولید ماژول هسته لینوکس، به تعدادی ابزار و سورس نیاز هست که در زیر آنها را نصب می کنیم:

1. خانواده دبیان (Debian/Ubuntu)

sudo apt update
sudo apt install build-essential linux-headers-$(uname -r)

2. خانواده ردهت (Fedora/RHEL/CentOS)

sudo dnf install kernel-devel gcc make

3. اسلکور (Slackware) 

sudo slackpkg install gcc make kernel-headers kernel-source

 

نوشتن ماژول Hello World (برای همه توزیع‌ ها)

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

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Hello World module for Slackware and other distros");
MODULE_VERSION("1.1");

static int __init hello_init(void) {
    printk(KERN_INFO "Hello from Slackware Kernel!\n");
    return 0;
}

static void __exit hello_exit(void) {
    printk(KERN_INFO "Goodbye from Slackware Kernel!\n");
}

module_init(hello_init);
module_exit(hello_exit);

 توضیحات کدهای بالا:

  • #include <linux/module.h>: یک فایل هدر (header) است که به توسعه‌ دهندگان ماژول‌ امکان می‌ دهد تا ماژول‌ های خود را با هسته لینوکس ادغام کنند. این فایل شامل defines، structures، ماکروها و توابعی است که برای نوشتن ماژول‌ های هسته ضروری هستند.

  • MODULE_LICENSE("GPL"): مشخص می‌ کند که ماژول تحت پروانه GPL است (اجباری).

  • printk: تابع چاپ در Log کرنل (مشابه printf اما برای کرنل).

    • KERN_INFO سطح Log را تعیین می‌ کند (در /var/log/kern.log یا dmesg دیده می‌ شود).

  • __init و __exit:

    • __init تعیین می کند که تابع فقط یک بار هنگام لود اجرا شود و سپس حافظه آزاد شود.

    • __exit برای توابعی است که فقط هنگام حذف ماژول اجرا می‌ شوند.

  • module_init و module_exit: توابع initialize و finalize ماژول را register می‌ کنند.

 

کامپایل و نصب ماژول

جهت کامپایل و نصب ماژول می توان بصورت دستی هم عمل کرد و دستورات را وارد کرد، اما بهتره یک فایل builder بنام Makefile بسازید و محتویات زیر رو داخل وارد کنید.

و سپس دستور make رو در کنسول سیستم در همون مسیر بزنید تا ماژول تولید بشه.

1. برای دبیان/ردهت

obj-m := hello_world.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

all:
    make -C $(KDIR) M=$(PWD) modules

clean:
    make -C $(KDIR) M=$(PWD) clean

2. برای اسلکور

obj-m := hello_world.o
KDIR ?= /usr/src/linux-$(shell uname -r)
PWD := $(shell pwd)

all:
    make -C $(KDIR) M=$(PWD) modules

clean:
    make -C $(KDIR) M=$(PWD) clean

 توضیحات کدهای بالا:

obj-m := hello_world.o فایل ماژول نهایی: hello_world.ko.

KDIR مسیر هدر های کرنل.

PWD مسیر فعلی.

make ساخت ماژول (hello_world.ko).

make clean پاکسازی فایل‌ های موقت.

نکته برای اسلکور:
در بعضی نسخه های Slackware ممکن است نیاز باشد مسیر کرنل را به صورت دستی مشخص کنید:

export KDIR=/usr/src/linux-$(uname -r)

 

اجرا و توقف ماژول

برای اجرا یا متوقف کردن ماژول از دستورات زیر استفاده می کنیم. این دستورات در همه توزیع های لینوکس موجود هستند:

1. برای لود ماژول

sudo insmod hello_world.ko

2. جهت بررسی خروجی

dmesg | tail -n 2

خروجی نمونه

[123456789] Hello from Slackware Kernel!

3. جهت حذف ماژول

sudo /sbin/rmmod hello_world

نکات ویژه Slackware

  1. مسیر کرنل:
    در Slackware کرنل در /usr/src/linux-$(uname -r) قرار دارد.

  2. تفاوت در ابزارها:
    در Slackware از insmod/rmmod به جای modprobe استفاده می شود..

  3. مدیریت ماژول‌ ها:
    برای لیست ماژول‌ های لود شده در Slackware:

    cat /proc/modules
    

 

تفاوت syscall با function call

در حین توسعه هسته یا ماژول های هسته ممکنه با واژه های syscall زیاد سروکار داشته باشید، اما syscall دقیقا چی هست:

  • معقوله system call (یا همون syscall) با محیط kernel در ارتباطه ولی function call با محیط user در ارتباطه.
  • system call با سیستم عامل تعامل برقرار می کنه ولی function call با برنامه و کتابخانه.
  • بخاطر گستردگی و تودرتو بودن system call، معمولاً منابع بیشتری صرف call کردن اونها میشه، ولی function call هزینه های کمتری رو دربر میگیره.
  • دستورات system call توسط function call صدا زده میشه ولی function call توسط برنامه صدا زده میشه.
  • یک دستور system call تکه ای کد در kernel-space هستش ولی function call تکه ای کد در user-space هستش.

تنها شباهت اینها در مهیا کردن خدمات به caller هستش.

 

مشکلات رایج

مشکل: Kernel Panic پس از لود ماژول
دلایل: دسترسی به حافظه نامعتبر (NULL pointer dereference) یا استفاده از توابع فضای user در کرنل (مثل printf به جای printk یا kmalloc بجای malloc)

 

مشکل: ماژول روی نسخه‌ های مختلف هسته کار نمی‌ کند
دلایل: تغییرات API کرنل بین نسخه‌ ها. پس کد را با آخرین نسخه‌ های کرنل تست کنید یا از LINUX_VERSION_CODE برای بررسی نسخه کرنل استفاده کنید

 

مشکل: Memory Leak در ماژول
دلایل:  آزاد نکردن حافظه در تابع exit یا فراموش کردن آزادسازی منابع. می توانید از ابزارهایی مانند kmemleak برای تشخیص leak حافظه استفاده کنید.

 

معرفی ماژولهای اوپن‌ سورس جهت یادگیری
1. پروژه eBPF

مانیتورینگ شبکه و trace سیستم

لینک: github.com/iovisor/bcc

2. پروژه FUSE
پیاده‌ سازی سیستم فایل در User-space

لینک: github.com/libfuse/libfuse

3. پروژه Open-IOMMU
درایور IOMMU برای مدیریت دسترسی به حافظه

لینک: github.com/OpenIOMMU

4. پروژه LTTng
سیستم trace عملکرد کرنل جهت دیباگ و آنالیز سیستم

لینک: github.com/lttng

5. پروژه KVM
توضیحات: ماژول مجازی‌ سازی جهت ساخت ماشین‌ های مجازی

لینک: git.kernel.org/pub/scm/virt/kvm/kvm.git

  • ۰۴/۰۴/۰۸
  • یوشا آل ایوب

linux module

ماژول لینوکس

هسته لینوکس

نظرات  (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

کاربران بیان میتوانند بدون نیاز به تأیید، نظرات خود را ارسال کنند.
اگر قبلا در بیان ثبت نام کرده اید لطفا ابتدا وارد شوید، در غیر این صورت می توانید ثبت نام کنید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">