Saya telah membaca sedikit tentang cara mengkompilasi modul kernel pada (dan untuk) Raspberry Pi, tapi saya masih belum cukup tahu mengapa itu tidak bekerja. Saya sudah bisa membangun modul, tetapi ia melaporkan Invalid module format
ketika saya mencoba insmod
hasilnya. Inilah proses yang saya ikuti. Pertama, sebagai root di bawah /root
saya menjalankan skrip shell berikut:
getKernel.sh
#! /usr/bin/bash
FIRMWARE_HASH=$(zgrep "* firmware as of" /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | head -1 | awk '{ print $5 }')
KERNEL_HASH=$(wget https://raw.githubusercontent.com/raspberrypi/firmware/$FIRMWARE_HASH/extra/git_hash -O -)
git clone https://github.com/raspberrypi/linux
cd linux
git checkout $KERNEL_HASH
wget https://raw.githubusercontent.com/raspberrypi/firmware/$FIRMWARE_HASH/extra/Module.symvers
zcat /proc/config.gz >.config
make oldconfig
make modules_prepare
ln -s /root/linux /lib/modules/$(uname -r)/build
Beberapa baris pertama berasal dari http://lostindetails.com/blog/post/Compiling-a-kernel-module-for-the-raspberry-pi-2
Selebihnya saya menulis untuk mengotomatisasi lebih banyak proses. Setelah semua itu berjalan dengan sukses, saya memiliki sumber yang harus sama persis dengan kernel yang berjalan, konfigurasi untuk mencocokkan dan symlink. Ada beberapa arahan ulang dari lokasi web github (tampaknya sekarang https://raw.githubusercontent.com/ ) tetapi tidak ada kesalahan aktual.
Kemudian saya menjadi pi
pengguna default dan dalam direktori bernama /home/pi/projects/lkm
Saya memiliki kode sumber ini untuk modul mainan yang sangat sederhana:
hello.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Do-nothing test driver");
MODULE_VERSION("0.1");
static int __init hello_init(void){
printk(KERN_INFO "Hello, world.\n");
return 0;
}
static void __exit hello_exit(void){
printk(KERN_INFO "Goodbye, world.\n");
}
module_init(hello_init);
module_exit(hello_exit);
Akhirnya, saya membangun modul dengan Makefile ini
Makefile
MODSRC=/home/pi/projects/lkm
obj-m+=hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=${MODSRC} modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=${MODSRC} clean
Akhirnya, saya mencoba memuat modul:
sudo insmod hello.ko
Namun hasilnya mengecewakan:
insmod: ERROR: tidak bisa memasukkan modul hello.ko: Format modul tidak valid
Detail yang mungkin relevan
Saya menggunakan jessie
versi terbaru dari Raspbian di Raspberry Pi2.
$ uname --kernel-release --kernel-version
4.1.13-v7+ #826 SMP PREEMPT Fri Nov 13 20:19:03 GMT 2015
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.9/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Raspbian 4.9.2-10' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 4.9.2 (Raspbian 4.9.2-10)
Sayangnya, saya tidak yakin bagaimana cara mengatasi masalah ini lebih lanjut atau memperbaikinya. Ada petunjuk?
Jawaban:
Pertama-tama, pastikan Anda menggunakan header kernel yang tepat. Saya berasumsi bahwa header kernel dan kode sumber Anda lebih diperbarui daripada kernel yang Anda jalankan.
Coba lakukan
apt-get update && apt-get upgrade
kemudian instal ulang modul. Jika masalah berlanjut, periksa tiga kali apakah header kernel Anda cocok dengan kernel Anda saat ini, kompilasi ulang lagi lalu coba instal.Catatan: Saya menggunakan Jessie.
UPDATE: Jalankan ini sebagai root.
Anda mungkin perlu me-reboot. Setelah itu, lanjutkan dengan perintah di bawah ini, masih menggunakan akun root.
Jika
rpi-source
melempar kesalahan GCC (sesuatu tentang ketidakcocokan versi), tidak apa-apa asalkan versi GCC Anda saat ini lebih tinggi . Jalankanrpi-source --skip-gcc
bukannyarpi-source
Kemudian, lanjutkan dengan contoh Hello World Anda. Buat folder dan
cd
ke dalamnya. Lalu, buat file.File:
hello.c
Makefile (case-sensitive?)
Sekarang setelah Anda memiliki file, Anda dapat melanjutkan dan menjalankan perintah membangun Hello World seperti biasa:
Anda sekarang harus memeriksa
dmesg
. Baris terakhir harus dicetakHello World :)
dengan warna merah.Jika Anda melakukannya, selamat. Anda baru saja membuat dan menginstal modul kernel.
Sekarang hapus menggunakan
rmmod hello
.dmesg
seharusnya sekarang cetak yangGoodbye World!
disorot dengan warna merah.Sumber: 1 2 3
sumber
rpi-source
bagian cukup. Anda dapat mencoba membangun milik Anda dari titik itu.Ada versi yang jauh lebih sederhana di sini, diuji dengan jessie dan stretch .
sudo apt-get install raspberrypi-kernel-headers
dan kemudian ketika file Anda ada di tempat:
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
Contoh
Buat
hello
direktori, masuk ke dalam dan buat file-file berikut:hello.c
danMakefile
.Saya sarankan bekerja sebagai user biasa Anda, bukan root , hanya
insmod
,rmmod
danmake modules_install
perintah memerlukan akses root, dan diperlukansudo
ditampilkan dalam perintah berikut.hello.c (tidak berubah, file Anda)
Makefile (diubah)
Pemakaian
make
(dalam direktori yang sama dengan Makefile)sudo insmod hello.ko
Hello World :)
di outputdmesg
sudo rmmod hello
Goodbye, world.
int output daridmesg
sudo make modules_install
akan menginstal modul di tempatnya, jadimodprobe
akan berfungsisumber
rpi-update
,rpi-update
disarankan dalam jawaban pandalion98apt
repositori Raspbian , jika saya tidak salah. Memperbarui kernel berarti menjalankanrpi-update
skrip Hexxeh . Saat ini, memperbaruiraspberrypi-kernel
atau menjalankanrpi-update
melakukan hal yang hampir sama.raspberrypi-kernel-headers
, biasanya menginstal header kernel yang tidak cocok, dari pengalaman (header cenderung menjadi versi yang lebih baru dari kernel), maka dari itu mengapa saya memilih untuk "pergi manual".dalam
getKernel.sh
file addsebelum
(sekarang dalam gambar rpi default /proc/config.gz tidak ada)
sumber