লোডযোগ্যযোগ্য কার্নেল মডিউলটি কার্নেলটি পুনরায় সংবিধান না করে সংকলন করুন


20

আমি রাস্পবেরি পাইতে কার্নেল মডিউলটি কীভাবে সংকলন করতে পারি সে সম্পর্কে আমি বেশ কিছুটা পড়েছি, তবে কেন এটি কাজ করছে না তা নির্ধারণ করার জন্য আমি এখনও যথেষ্ট সক্ষম নই। আমি মডিউলটি তৈরি করতে সক্ষম হয়েছি, তবে Invalid module formatযখন আমি insmodফলাফলটি চেষ্টা করি তখন এটি রিপোর্ট করে। এই প্রক্রিয়াটি আমি অনুসরণ করেছি। প্রথমে রুট হিসাবে /rootআমি নিম্নলিখিত শেল স্ক্রিপ্টটি সম্পাদন করেছি:

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 

প্রথম কয়েকটি লাইনগুলি http://lostindetails.com/blog/post/Compiling-a-kernel-module-for-the-raspberry-pi-2 থেকে এসেছে

বাকি আমি আরও বেশি প্রক্রিয়া স্বয়ংক্রিয় করতে লিখেছিলাম। এর সবগুলি সফলভাবে রান হয়ে গেলে, আমার কাছে উত্সটি রয়েছে যা চলমান কার্নেল, ম্যাচ করার জন্য কনফিগারেশন এবং একটি সিমিলিংকের সাথে হুবহু মিলে যায়। গিথুব ওয়েব অবস্থান থেকে কিছু পুনঃনির্দেশ ছিল (সম্ভবত এটি এখন https://raw.githubusercontent.com/ ) তবে প্রকৃত ত্রুটি নেই।

তারপরে আমি ডিফল্ট piব্যবহারকারী হয়ে উঠি এবং নামের একটি ডিরেক্টরিতে /home/pi/projects/lkmআমার কাছে খুব সাধারণ খেলনা মডিউলটির জন্য এই উত্স কোডটি থাকে:

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

অবশেষে, আমি এই মেকফিল দিয়ে মডিউলটি তৈরি করি

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

পরিশেষে, আমি মডিউলটি লোড করার চেষ্টা করি:

sudo insmod hello.ko

ফলাফলটি হতাশাব্যঞ্জক:

insmod: ERROR: মডিউল sertোকানো গেল না হ্যালো। কো: अवैध মডিউল ফর্ম্যাট

সম্ভবত প্রাসঙ্গিক বিশদ

আমি বর্তমানে jessieরাস্পবিয়ান পাই 2 তে রাস্পবিয়ানের সর্বশেষতম সংস্করণটি ব্যবহার করছি ।

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

দুর্ভাগ্যক্রমে, আমি কীভাবে এটি আরও সমস্যার সমাধান করব বা ঠিক করব তা নিশ্চিত নই। কোন সংকেত সনাক্ত করুন?


আমি আমার সমস্ত তদন্ত এবং অভিজ্ঞতাগুলি একটি স্ক্রিপ্টে সংকলন করেছি, github.com/x29a/kernel/blob/master/rpi/prepare.sh এবং সম্পর্কিত ব্লগপোস্ট ব্লগ পোস্ট। Chris007.de/…
x29a

উত্তর:


23

প্রথমত, নিশ্চিত হয়ে নিন যে আপনি সঠিক কার্নেল শিরোনাম ব্যবহার করেছেন। আমি ধরে নিচ্ছি যে আপনার কার্নেল শিরোনাম এবং উত্স কোড আপনি যে কার্নেলটি চালাচ্ছেন তার চেয়ে বেশি আপডেট হয়েছে।

apt-get update && apt-get upgradeমডিউলটি আবার ইনস্টল করার চেষ্টা করুন । যদি সমস্যাটি থেকে যায় তবে ট্রিপলটি পরীক্ষা করে দেখুন যে আপনার কার্নেল শিরোনামগুলি আপনার বর্তমান কার্নেলের সাথে মেলে, পুনরায় কম্পাইল করুন তারপরে ইনস্টল করার চেষ্টা করুন।


দ্রষ্টব্য: আমি জেসি ব্যবহার করছি।

আপডেট: এগুলি রুট হিসাবে চালান।

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

# Update the kernel!
rpi-update

আপনাকে পুনরায় বুট করতে হবে। এর পরে, নীচের কমান্ডগুলি দিয়ে এগিয়ে চলুন, তারপরেও রুট অ্যাকাউন্টটি ব্যবহার করে।

# 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-sourceকোনও জিসিসি ত্রুটি (কোনও সংস্করণ মেলে না এমন কিছু সম্পর্কে) ছুড়ে ফেলে তবে আপনার বর্তমান জিসিসি সংস্করণ যত বেশি হবে ততক্ষণ ঠিক আছে । rpi-source --skip-gccপরিবর্তে চালানrpi-source

তারপরে, আপনার হ্যালো ওয়ার্ল্ড উদাহরণ দিয়ে এগিয়ে যান। ফোল্ডারটি তৈরি করুন এবং cdএটিতে। তারপরে, ফাইলগুলি তৈরি করুন।

mkdir hello
cd hello

নথি পত্র:

, hello.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 (কেস সংবেদনশীল?)

obj-m := hello.o

এখন আপনার কাছে ফাইল রয়েছে, আপনি এগিয়ে যেতে পারেন এবং হ্যালো ওয়ার্ল্ড বিল্ড কমান্ডগুলি চালিয়ে যেতে পারেন:

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

আপনার এখন চেক করা উচিত dmesg। শেষ লাইনটি Hello World :)লাল রঙে হাইলাইট করা মুদ্রণ করা উচিত ।

আপনি যদি, অভিনন্দন। আপনি সবেমাত্র একটি কার্নেল মডিউল তৈরি এবং ইনস্টল করেছেন।

এখন এটি ব্যবহার করে অপসারণ rmmod hellodmesgএখন Goodbye World!লাল রঙে হাইলাইট করা মুদ্রণ করা উচিত ।

সূত্র: 1 2 3


আপনি যখন "আপনার কার্নেল শিরোনামগুলি আপনার বর্তমান কার্নেলের সাথে মেলে কিনা তা পরীক্ষা করে দেখুন" বলতে গেলে আপনার ঠিক কী বোঝানো উচিত যে আমার এটি করা উচিত?
এডওয়ার্ড

অ্যাডওয়ার্ড আপডেট হয়েছে
পিএনডিএ

@ অ্যাডওয়ার্ড নোট করুন এটি হ্যালো বিশ্বের উদাহরণ। আমি আপনার মডিউলটি তৈরি করেছি, কিন্তু আমি বুঝতে পারি যে এটি একই। পার্থক্য হ'ল আপনার কোডটিতে লাল হাইলাইট নেই।
পিএনডিএ

@ অ্যাডওয়ার্ড আপনার ক্ষেত্রে, আমি মনে করি যে rpi-sourceঅংশটি পর্যাপ্ত না হওয়া পর্যন্ত নির্দেশাবলী অনুসরণ করা উচিত । আপনি যে বিন্দু থেকে আপনার তৈরি চেষ্টা করতে পারেন।
পিএনডিএ

5

এখানে অনেক সহজ সংস্করণ রয়েছে, জেসি এবং প্রসারিত পরীক্ষিত ।

sudo apt-get install raspberrypi-kernel-headers

এবং তারপরে যখন আপনার ফাইলগুলি স্থানে থাকে:

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

উদাহরণ

helloডিরেক্টরি তৈরি করুন , ভিতরে যান এবং নিম্নলিখিত ফাইলগুলি তৈরি করুন: hello.cএবং Makefile

আমি সুপারিশ করছি আপনার স্বাভাবিক ব্যবহারকারী হিসেবে কাজ না রুট , শুধুমাত্র insmod, rmmodএবং make modules_installকমান্ড রুট অনুমতির প্রয়োজন, এবং প্রয়োজনীয় sudoনিম্নলিখিত কমান্ড প্রদর্শন করা হয়।


হ্যালো। সি। (অপরিবর্তিত, আপনার ফাইল)

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

মেকফাইল (পরিবর্তিত)

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)   

ব্যবহার

  • বিল্ড: make(মেকফিলের মতো একই ডিরেক্টরিতে)
  • পরীক্ষা
    • সাথে মডিউল Inোকান sudo insmod hello.ko
    • এই Hello World :)আউটপুট মধ্যেdmesg
    • সঙ্গে মডিউল সরান sudo rmmod hello
    • এই Goodbye, world.int- এ আউটপুটdmesg
  • ইনস্টল করুন, যখন আপনার মডিউলটি কাজ sudo make modules_installকরবে, মডিউলটি যেখানে এটি ইনস্টল modprobeকরবে তাই কাজ করবে।

1
'রাস্পবেরিপি-কার্নেল' প্যাকেজটির মাধ্যমে ইনস্টল করা কার্নেলগুলির জন্য খুব ভাল কাজ করে। 'প্যান্ডেলিয়ন ৯৮' দ্বারা জারি করা বিবরণটির বিপরীতে 'আরপিআই আপডেট' এর মাধ্যমে ইনস্টল করা কার্নেলগুলি বোঝায়। উভয় পদ্ধতি পারস্পরিক একচেটিয়া অধিকার?
স্পার্কি

1
আমি মনে করি এটা যেহেতু ওপি (এডওয়ার্ড) একটি বৈধ উত্তর কথা বলত সম্পর্কে rpi-update, rpi-updateএ pandalion98 এর উত্তর প্রস্তাব ছিল
PIM

@ স্পার্কি পোস্ট করার সময় apt, যদি আমার ভুল না হয় তবে কার্নেলটি এখনও রাস্পবিয়ার সংগ্রহস্থলের সাথে সংহত হয়নি। কার্নেল আপডেট করার অর্থ হেক্সেক্সের rpi-updateস্ক্রিপ্ট চালানো। এই দিনগুলিতে আপডেট করা raspberrypi-kernelবা চালানো rpi-updateবেশ একই জিনিস করে।
পিএনডিএ

হিসাবে হিসাবে raspberrypi-kernel-headers, এটি সাধারণত অভিজ্ঞতা থেকে (শিরোনামগুলি কার্নেলের চেয়ে নতুন সংস্করণ হিসাবে দেখা যায়) মেলেনি কার্নেল শিরোনামগুলি ইনস্টল করে, তাই কেন আমি "ম্যানুয়াল যান" বেছে নিই।
পিএনডিএ

'রাস্পবেরিপি-কার্নেল' এবং 'আরপিআই-আপডেট' এর মধ্যে কিছুটা পার্থক্য রয়েছে বলে মনে হয়: একটির ফলাফল এই মুহুর্তে '4.9.56+' তে অন্যটি '4.9.66+' তে আসে। সুতরাং আমি মনে করি আমাদের এখনও উভয় বিল্ড পদ্ধতি পৃথকভাবে পরিচালনা করতে হবে
স্পার্কি

2

মধ্যে getKernel.shফাইল যোগ

sudo modprobe configs

আগে

zcat /proc/config.gz >.config

(এখন ডিফল্ট আরপিআই চিত্র / প্রোপ / কনফিগ.gz বিদ্যমান নেই)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.