Yüklenebilir bir çekirdek modülünü çekirdeği yeniden derlemeden derleme


20

Raspberry Pi'de bir çekirdek modülünü nasıl derleyeceğimi (ve bunun için) biraz okudum, ama neden işe yaramadığını hala tam olarak anlayamadım. Modülü oluşturabildim, ancak sonucu Invalid module formatdenediğimde rapor veriyor insmod. İşte benim takip ettiğim süreç. İlk olarak, altında root olarak /rootaşağıdaki kabuk betiğini yürüttüm:

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 

İlk birkaç satır http://lostindetails.com/blog/post/Compiling-a-kernel-module-for-the-raspberry-pi-2 ' dendir.

Geri kalanlar süreci daha da otomatikleştirmek için yazdım. Tüm bunlar başarılı bir şekilde çalıştığında, çalışan çekirdeğe, eşleşecek yapılandırmaya ve bir işaret bağlantısına tam olarak uyması gereken kaynağa sahibim. Github web konumundan bazı yönlendirmeler yapıldı (görünüşe göre şimdi https://raw.githubusercontent.com/ ) ama gerçek hata yok.

Sonra varsayılan pikullanıcı oluyorum ve /home/pi/projects/lkmçok basit bir oyuncak modül için bu kaynak kodum var adlı bir dizinde :

Merhaba 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);

Sonunda modülü bu Makefile ile yapıyorum.

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

Sonunda modülü yüklemeye çalışıyorum:

sudo insmod hello.ko

Ancak sonuç hayal kırıklığı yaratıyor:

insmod: HATA: modül eklenemedi hello.ko: Geçersiz modül formatı

Muhtemelen ilgili detaylar

jessieRaspbian'ın şu anda en yeni sürümünü Raspberry Pi2'de kullanıyorum .

$ 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) 

Ne yazık ki, bunun nasıl daha fazla giderileceğinden veya düzeltileceğinden emin değilim. Herhangi bir ipucu var mı?


Anlıyorum, bir komut dosyası içine bütün bulguları ve deneyimleri derlenmiş github.com/x29a/kernel/blob/master/rpi/prepare.sh ve ilgili blog gönderisi blog.chris007.de/...
x29a

Yanıtlar:


23

Her şeyden önce, uygun çekirdek başlıkları kullandığınızdan emin olun. Çekirdek başlıklarınızın ve kaynak kodunuzun, çalıştırdığınız çekirdekten daha güncel olduğunu varsayıyorum.

Yapmayı deneyin ve apt-get update && apt-get upgradeardından modülü tekrar yükleyin. Sorun devam ederse, çekirdek başlıklarınızın geçerli çekirdeğinizle eşleştiğini üç kez kontrol edin, yeniden derleyin ve yüklemeyi deneyin.


Not: Jessie kullanıyorum.

GÜNCELLEME: Bunları root olarak çalıştırın.

# The usual update routine
apt-get update -y
apt-get upgrade -y

# Update the kernel!
rpi-update

Yeniden başlatmanız gerekebilir. Ondan sonra, hala root hesabını kullanarak aşağıdaki komutlara devam edin.

# Get rpi-source
sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source

# Make it executable
sudo chmod +x /usr/bin/rpi-source

# Tell the update mechanism that this is the latest version of the script
/usr/bin/rpi-source -q --tag-update

# Get the kernel files thingies.
rpi-source

rpi-sourceBir GCC hatası verirse (sürüm uyuşmazlığı hakkında bir şey), geçerli GCC sürümünüz daha yüksek olduğu sürece sorun olmaz . Run rpi-source --skip-gccyerinerpi-source

Ardından, Hello World örneğinizle devam edin. Klasörü ve cdiçine oluşturun . Sonra dosyaları oluşturun.

mkdir hello
cd hello

Dosyalar:

Merhaba C

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

int hello_init(void)
{
    pr_alert("Hello World :)\n");
    return 0;
}
void hello_exit(void)
{
    pr_alert("Goodbye World!\n");
}
module_init(hello_init);
module_exit(hello_exit);

Makefile (büyük / küçük harfe duyarlı?)

obj-m := hello.o

Artık dosyalarınız elinizde, devam edip normal Hello World derleme komutlarını çalıştırabilirsiniz:

make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
insmod hello.ko

Şimdi kontrol etmelisin dmesg. Son satır Hello World :)kırmızıyla vurgulanmış olarak yazdırılmalıdır .

Yaparsan tebrikler. Az önce bir çekirdek modülü kurdunuz ve taktınız.

Şimdi kullanarak kaldırın rmmod hello. dmesgşimdi Goodbye World!kırmızı renkle vurgulanmış olarak basılmalıdır.

Kaynaklar: 1 2 3


"Çekirdek başlıklarınızın mevcut çekirdeğinize uyup uymadığını kontrol edin" derken bunu nasıl yapmam gerekir?
Edward

@Edward güncellendi.
PNDA

@Edward Bunun merhaba dünya örneği olduğuna dikkat edin. Modülünü yaptım, ama aynı olduğunu anladım. Tek fark, kodunuzun kırmızı vurgu içermemesidir.
PNDA

@Edward Sizin durumunuzda, rpi-sourceparça yeterli oluncaya kadar talimatları izlemeyi düşünüyorum . Sizinkini bu noktadan kurmayı deneyebilirsin.
PNDA

5

Burada çok daha basit bir sürümü var, jessie ve stretch üzerinde test edildi .

sudo apt-get install raspberrypi-kernel-headers

ve sonra dosyalarınız yerinde olduğunda:

make -C /lib/modules/$(uname -r)/build M=$(pwd) modules

Örnek

helloDizini oluşturun, içeri girin ve aşağıdaki dosyaları oluşturun: hello.cand Makefile.

Ben tavsiye normal bir kullanıcı olarak çalışan değil kök , sadece insmod, rmmodve make modules_installkomutlar root yetkileri gerektiren ve gerekli sudoaşağıdaki komutları gösterilmektedir.


hello.c (değişmedi, dosyanız)

#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);

Makefile (değiştirildi)

obj-m+=hello.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(pwd) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(pwd) clean

modules_install: all
    $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
    $(DEPMOD)   

kullanım

  • Derleme: make(Makefile ile aynı dizinde)
  • Ölçek
    • Modülü ile takın sudo insmod hello.ko
    • Bul Hello World :)çıkışındadmesg
    • Modülü ile çıkartın sudo rmmod hello
    • Goodbye, world.İnt çıktısını bulundmesg
  • Modülünüz çalışırken, sudo make modules_installait olduğu modülü kuracak, modprobeçalışacaktır.

1
'ahududu-çekirdek' paketi ile kurulan çekirdekler için çok iyi çalışıyor. Bunun aksine, 'pandalion98' tarafından verilen açıklama, 'rpi-update' ile yüklenen çekirdekleri ifade eder. Her iki yöntem de karşılıklı olarak münhasırdır.
sparkie

1
Bu konuda OP (Edward) bu yana geçerli bir cevap hiç konuşmadık olduğunu düşünüyorum rpi-update, rpi-updatepandalion98 cevabı önerildi
pim

@sparkie Gönderim sırasında apt, eğer hatalı değilsem, çekirdek Raspbian'ın deposuna hala entegre değildi. Çekirdeğin güncellenmesi, Hexxeh'in rpi-updatesenaryosunu çalıştırmak anlamına geliyordu . Bu günlerde, güncelleme raspberrypi-kernelveya çalışan rpi-updatehemen hemen aynı şeyi.
PNDA

Gelince raspberrypi-kernel-headers, genellikle birinin "el go" seçti dolayısıyla neden, (başlıklar çekirdekten daha yeni bir sürümü olma eğilimi) deneyimlerinden, eşleşmeyen çekirdek başlıkları yükler.
PNDA

'raspberrypi-çekirdek' ve 'rpi-update' arasında bir fark var gibi görünüyor: bunlardan biri şu anda '4.9.56+' ile '4.9.66+' ile sonuçlanıyor. Biz hala ayrı hem yapı prosedürünü ele zorunda Bence Yani
Sparkie

2

içinde getKernel.shdosya ekleme

sudo modprobe configs

önce

zcat /proc/config.gz >.config

(şimdi varsayılan rpi görüntüsünde /proc/config.gz mevcut değil)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.