“Merhaba Dunya!”
Adettendir bir Hello World diyelim. Bir önceki bölümdeki Makefile
dosyasını
kullanalım.
1obj-m += ${file}.o
2PWD := $(CURDIR)
3
4all:
5 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
6
7clean:
8 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Bu da kodumuz:
1#include <linux/module.h>
2#include <linux/kernel.h>
3
4int init_module(void){
5 printk(KERN_INFO "Merhaba Dunya...\n");
6 return 0;
7}
8
9void cleanup_module(void) {
10 printk(KERN_INFO "Gule gule Dunya...\n");
11}
Daha sonra make file=merhaba
dediğimizde hata alıyoruz.
ay@ubuntu2204:~/ws/sys/driver$ make file=merhaba
make -C /lib/modules/6.5.0-27-generic/build M=/home/ay/ws/sys/driver modules
make[1]: Entering directory '/usr/src/linux-headers-6.5.0-27-generic'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
You are using:
CC [M] /home/ay/ws/sys/driver/merhaba.o
/bin/sh: 1: gcc-12: not found
make[3]: *** [scripts/Makefile.build:251: /home/ay/ws/sys/driver/merhaba.o] Error 127
make[2]: *** [/usr/src/linux-headers-6.5.0-27-generic/Makefile:2039: /home/ay/ws/sys/driver] Error 2
make[1]: *** [Makefile:234: __sub-make] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-6.5.0-27-generic'
make: *** [Makefile:6: all] Error 2
Diyor ki şu an kullanılan kernelin derlendiği C derleyicisi ile senin kullandığın
farklı ve gcc-12
yi bulamadım diyor. Hemen bendekine bakıyoruz.
ay@ubuntu2204:~/ws/sys/driver$ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Bende versiyon 11 varmış, o 12 arıyor. sudo apt install gcc-12
ile kuralım.
ay@ubuntu2204:~/ws/sys/driver$ gcc-12 --version
gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ay@ubuntu2204:~/ws/sys/driver$ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Her ne kadar gcc
hala eski olanı gösterse de gcc-12
nin olması yeterli oluyor.
ay@ubuntu2204:~/ws/sys/driver$ which gcc
/usr/bin/gcc
ay@ubuntu2204:~/ws/sys/driver$ which gcc-12
/usr/bin/gcc-12
ay@ubuntu2204:~/ws/sys/driver$ ls -lah /usr/bin/gcc
lrwxrwxrwx 1 root root 6 Ağu 5 2021 /usr/bin/gcc -> gcc-11
ve
ay@ubuntu2204:~/ws/sys/driver$ make file=merhaba
make -C /lib/modules/6.5.0-27-generic/build M=/home/ay/ws/sys/driver modules
make[1]: Entering directory '/usr/src/linux-headers-6.5.0-27-generic'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
You are using: gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
CC [M] /home/ay/ws/sys/driver/merhaba.o
MODPOST /home/ay/ws/sys/driver/Module.symvers
ERROR: modpost: missing MODULE_LICENSE() in /home/ay/ws/sys/driver/merhaba.o
make[3]: *** [scripts/Makefile.modpost:144: /home/ay/ws/sys/driver/Module.symvers] Error 1
make[2]: *** [/usr/src/linux-headers-6.5.0-27-generic/Makefile:1991: modpost] Error 2
make[1]: *** [Makefile:234: __sub-make] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-6.5.0-27-generic'
make: *** [Makefile:6: all] Error 2
Yukarıda hala derleyici uyarısı veriyor ama sadece isimler farklı gibi, sonuçta
ikisi de 12.3.0
.
ERROR: modpost: missing MODULE_LICENSE()
şeklinde bir hata aldık, patladık.
Yüklenebilir kernel modüllerinde lisansın belirtilmesi güncel kernellerde zorunludur. Bu, yasal problemler gibi çeşitli çok teknik olmayan problemlerin önüne geçmek için ya da hata durumlarında kernel’i tainted olarak işaretlemek için alınmış bir tedbirdir [1] [2] [3]. Eskiden derleniyormuş ama yüklerken bu durum ortaya çıkıyormuş artık derlenmiyor.
MODULE_LICENSE
makrosunun çalışması için #include
larının altına yazmamız
gerekiyor. Şimdilik derlemeye devam etmek için GPL
lisansını seçebiliriz.
Elbette normalde modülümüze uygun bir lisans seçmemiz gerekiyor, buna ileride
değinebilirim.
1#include <linux/module.h>
2#include <linux/kernel.h>
3
4MODULE_LICENSE("GPL");
5
6int init_module(void){
7 printk(KERN_INFO "Merhaba Dunya...\n");
8 return 0;
9}
10
11void cleanup_module(void) {
12 printk(KERN_INFO "Gule gule Dunya...\n");
13}
bundan sonra
ay@ubuntu2204:~/ws/sys/driver$ make file=merhaba
make -C /lib/modules/6.5.0-27-generic/build M=/home/ay/ws/sys/driver modules
make[1]: Entering directory '/usr/src/linux-headers-6.5.0-27-generic'
warning: the compiler differs from the one used to build the kernel
The kernel was built by: x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
You are using: gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
CC [M] /home/ay/ws/sys/driver/merhaba.o
MODPOST /home/ay/ws/sys/driver/Module.symvers
CC [M] /home/ay/ws/sys/driver/merhaba.mod.o
LD [M] /home/ay/ws/sys/driver/merhaba.ko
BTF [M] /home/ay/ws/sys/driver/merhaba.ko
Skipping BTF generation for /home/ay/ws/sys/driver/merhaba.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/linux-headers-6.5.0-27-generic'
Bu sefer başarılı olduk. Bir sürü de dosya çıkıyor.
ay@ubuntu2204:~/ws/sys/driver$ ll
total 352
drwxrwxr-x 2 ay ay 4096 May 5 15:47 ./
drwxrwxr-x 3 ay ay 4096 May 4 18:40 ../
-rw-rw-r-- 1 ay ay 174 May 4 18:46 Makefile
-rw-rw-r-- 1 ay ay 232 May 4 19:09 merhaba.c
-rw-rw-r-- 1 ay ay 111424 May 5 15:47 merhaba.ko
-rw-rw-r-- 1 ay ay 300 May 5 15:47 .merhaba.ko.cmd
-rw-rw-r-- 1 ay ay 33 May 5 15:47 merhaba.mod
-rw-rw-r-- 1 ay ay 968 May 5 15:47 merhaba.mod.c
-rw-rw-r-- 1 ay ay 168 May 5 15:47 .merhaba.mod.cmd
-rw-rw-r-- 1 ay ay 96320 May 5 15:47 merhaba.mod.o
-rw-rw-r-- 1 ay ay 38560 May 5 15:47 .merhaba.mod.o.cmd
-rw-rw-r-- 1 ay ay 16536 May 5 15:47 merhaba.o
-rw-rw-r-- 1 ay ay 37410 May 5 15:47 .merhaba.o.cmd
-rw-rw-r-- 1 ay ay 33 May 5 15:47 modules.order
-rw-rw-r-- 1 ay ay 136 May 5 15:47 .modules.order.cmd
-rw-rw-r-- 1 ay ay 0 May 5 15:47 Module.symvers
-rw-rw-r-- 1 ay ay 185 May 5 15:47 .Module.symvers.cmd
Bizim yükleyeceğimiz dosya kernel object dosyası yani .ko
oluyor.
Kernel’e Modülün Yüklenmesi ve Çıkartılması
Bunun için insmod
aracını kullanacağız. Bunun için root yetkisi gerekiyor.
ay@ubuntu2204:~/ws/sys/driver$ sudo insmod merhaba.ko
[sudo] password for ay:
Bu işlem ile modülümüz kernel’e yüklendi. Yani modül kernelin bir parçası haline geldi.
Kaldırmak için de rmmod
programını kullanacağız.
ay@ubuntu2204:~/ws/sys/driver$ sudo rmmod merhaba.ko
gibi
Peki bu mesajlar nereye gitti? Bunları da dmesg
üzerinden görebiliriz:
...
[ 1305.004460] merhaba: loading out-of-tree module taints kernel.
[ 1305.004502] merhaba: module verification failed: signature and/or required key missing - tainting kernel
[ 1305.148552] Merhaba Dunya...
[ 1453.721631] Gule gule Dunya...
Bir modül yüklendiği zaman init_module()
çağrılıyor kernel tarafından. Bu
modülün constructor’ı gibi, main()
gibi özel bir fonksiyonmuş gibi
düşünebiliriz. Başarı durumunda 0, hata durumunda negatif değer dönmelidir. Hata
dönerse kernel bu modülü yüklemekten vazgeçer. Herhangi bir parametre almaz.
cleanup_module()
de modül kernelden çıkartılırken çağrılıyor, destructor gibi.
Bir parametre almaz ve bir geri dönüş değeri yoktur, void
.
Burada bu fonksiyonların ismini değiştirme şansımız var ama onu bir macro ile söylememiz gerekiyor kodda. Bir şey yapmak istemiyorsak bu isimleri kullanmalıyız.
printk()
kernel tarafından sağlanan ve standart C’de olmayan bir fonksiyondur.
Benzer şekilde KERN_INFO
da kernel tarafından tanımlanan bir makrodur. Bunları
göreceğiz.
Not
C kodunda include ettiğimiz linux/module.h
ve linux/kernel.h
,
/lib/modules/$(uname -r)/build/include
dizini içerisinde yer almaktadır. Yani
bildiğimiz libc ve POSIX kütüphanelerinin başlık dosyalarının bulunduğu
/usr/include
içerisinde değildir.
Kaynaklar
127-13847
💭 Yorumlar
Yorum altyapısı giscus tarafından (evet tarafından!) sağlanmaktadır. Yorum yazabilmek için GitHub hesabınız üzerinden giriş yapmanız gerekmektedir. Yorumlar, Github Discussions üzerinde saklanmaktadır.
cf2437e7-7642-4e66-8455-aff7981b4b0b