“ ไม่มีรุ่นสัญลักษณ์สำหรับ module_layout” เมื่อพยายามโหลด usbhid.ko


27

ฉันกำลังพยายามสร้างโมดูลของตัวเองusbhid.koแต่หลังจากรวบรวมแล้วฉันไม่สามารถโหลดโมดูลได้ กล่าวว่าdmesg no symbol version for module_layoutฉันสงสัยว่าปัญหาคืออะไร ฉันได้ใช้เคอร์เนลแหล่งที่มาจากอูบุนตูแล้วและฉันก็ต้องแน่ใจว่าเวอร์ชันเคอร์เนลเหมือนกัน

คำตอบ:


22

สิ่งที่เป็นปัญหาโดยเฉพาะอย่างยิ่งเมื่อคุณสร้างโมดูลของคุณแผนผังแหล่งที่มาของเคอร์เนลอาจหายไปจากไฟล์ Modules.symvers ระบบ kbuild เตือนคุณเกี่ยวกับสิ่งนี้เมื่อคุณสร้างโมดูล หาก Modules.symvers หายไปคุณจะเห็น:

คำเตือน: สัญลักษณ์เวอร์ชันดัมพ์ /usr/src/linux-2.6.34-12/Modules.symvers หายไป; โมดูลจะไม่มีการพึ่งพาและการดัดแปลง

หากเคอร์เนลของคุณCONFIG_MODVERSIONSเปิดใช้งานอยู่ในระหว่างขั้นตอน modpost ของการสร้างไดรเวอร์ของคุณมันจะเรียกใช้สคริปต์ / mod / modpostด้วยตัวเลือก -m หากคุณกล้าหาญและดูที่สคริปต์ / mod / modpost.c source คุณจะเห็นว่าตัวเลือก -m เพิ่มสัญลักษณ์ _module_layout_ จาก vmlinux อย่างไรก็ตามหากคุณไม่มี Modules.symvers จากเคอร์เนลของคุณ คุณจะไม่ได้รับค่า CRC สำหรับสัญลักษณ์นี้และคุณจะพบข้อความแสดงข้อผิดพลาดนี้

ดังนั้นมีสองวิธีรอบนี้

1) เรียกใช้งานบิลด์เคอร์เนลของคุณเพื่อสร้าง Modules.symvers จากนั้นสร้างโมดูลใหม่ [http://www.mjmwired.net/kernel/Documentation/kbuild/modules.txt][1]

51  === 2. How to Build External Modules
52  
53  To build external modules, you must have a prebuilt kernel available
54  that contains the configuration and header files used in the build.
55  Also, the kernel must have been built with modules enabled. If you are
56  using a distribution kernel, there will be a package for the kernel you
57  are running provided by your distribution.
58  
59  An alternative is to use the "make" target "modules_prepare." This will
60  make sure the kernel contains the information required. The target
61  exists solely as a simple way to prepare a kernel source tree for
62  building external modules.
63  
64  NOTE: "modules_prepare" will not build Module.symvers even if
65  CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
66  executed to make module versioning work.

2) ตัวเลือกอื่นคือบอก modprobe ที่โง่เพียงแค่ละเว้น crap นั้นและเพียงแค่โหลดโมดูลของคุณอย่างไรก็ตาม:

modprobe -f <module>

ฉันมักจะชอบตัวเลือกที่ 2 :)


1
+1 สำหรับ "บอกโง่ modprobe เพียงละเว้นอึนั้นและเพียงแค่โหลดโมดูลของคุณต่อไป" ความคิดเห็น
Hayri Uğur Koltuk

ฉันลอง 2 และพบว่าโมดูลจะไม่โหลดอัตโนมัติในเวลาบูต มีวิธีการ -f ในเวลาบูตหรือไม่?
จัสตินจาง

17

ติดตั้งทั้งแพ็คเกจlinux-headersและที่linux-sourceสอดคล้องกับเคอร์เนลของคุณ ตัวอย่างเช่นสำหรับเคอร์เนลที่3.2.0-27-generic-paeคุณต้องการ:

  1. linux-headers-3.2.0-27-generic-pae และ
  2. linux-source-3.2.0-27-generic-pae.

ในกรณีที่รุ่นสำหรับแพ็คเกจด้านบนไม่ตรงกับรุ่นเคอร์เนลที่ใช้งานอยู่คุณต้องแทนที่$(uname -r)ด้วยสตริงเวอร์ชันจากแพ็กเกจเคอร์เนลที่ติดตั้งจากด้านบน สำหรับตัวอย่างข้างต้นแพคเกจรุ่นคือ
3.2.0-27-generic-paeเมื่อคุณเรียกใช้uname -rและผลลัพธ์เป็นสิ่งที่แตกต่างกันแล้ว3.2.0-27-generic-paeคุณจะต้องแทนที่แต่ละ$(uname -r)ด้านล่างเพื่อให้ตรงกับสตริงรุ่นจากแพคเกจที่ติดตั้ง

  1. cd /usr/src/linux-source-$Version และแตกไฟล์เก็บถาวร. tar.bz2 ในตำแหน่งและ cd ลงในไดเรกทอรีที่แยกออกมา - ฉันเดาว่าคุณทำสิ่งนี้แล้ว
  2. cp /boot/config-$(uname -r) .config ลงในไดเรกทอรีแหล่งเคอร์เนล
  3. cp /usr/src/linux-headers-$(uname -r)/Module.symvers . ลงในไดเรกทอรีแหล่งเคอร์เนล

หลังจากคุณทำเช่นนั้นในไดเรกทอรีแหล่งเคอร์เนลให้ทำดังนี้

  1. make prepare
  2. make scripts
  3. make M=drivers/usb/serial- เปลี่ยนเส้นทางหลังจากM=เพื่อให้เหมาะกับความต้องการของคุณ

น่าเสียดายที่ฉันไม่ทราบวิธีการสร้างโมดูลเฉพาะขณะที่Module.symversไม่ถูกแตะต้อง make drivers/usb/serial/option.koตัวอย่างเช่นการทำเช่นนั้นจะทำการฆ่าModule.symversไฟล์และคุณจะพบปัญหาเดิมของคุณ การใช้M=พารามิเตอร์ไม่ได้ฆ่า แต่คุณต้องสร้างโมดูลทั้งหมดในเส้นทางที่ระบุ - และฉันยังไม่พบวิธีแก้ไข


นี้ดูเหมือนว่าวิธีที่ดีที่สุดที่จะทำสิ่งในกรณีที่คุณกำลังรวบรวมโมดูลในรุ่นต้นไม้เดียวกัน ...
Treviño

2

คุณต้องใช้การตั้งค่า kernel make prepareเหมือนอย่างแม่นยำก่อนที่จะเรียก นอกจากนี้หากคุณกำลังสร้างมันออกมาจากต้นไม้คุณจะต้องสร้างมันขึ้นมาจากส่วนหัวของเคอร์เนลที่เหมือนกันซึ่งตรงกับเคอร์เนลที่ใช้งานอยู่ในปัจจุบันของคุณ


"make mrproper", "cp / boot / config - $ (uname -r) .config", "make oldconfig", "make เตรียม", "สร้างสคริปต์" ฉันใช้คำแนะนำเหล่านี้เพื่อเตรียมการรวบรวม ฉันต้องการทราบว่าฉันได้คัดลอกไฟล์การกำหนดค่าที่ถูกต้องหรือไม่ ดูเหมือนว่าจะมีเพียงหนึ่งการกำหนดค่าที่ตรงกับรุ่นเคอร์เนลของฉันใน / boot / ขออภัยเกี่ยวกับการจัดรูปแบบเป็นกล่องแสดงความคิดเห็นไม่มีรูปแบบ ....
24710 SpecC

ใช่ว่าถูกต้อง คุณเรียกใช้งาน build อยู่ที่ไหนและหากไม่ได้มาจากไดเรกทอรีระดับบนสุดคุณจะส่งค่า SUBDIRS ใด
Daniel T Chen

ขอบคุณสำหรับการตอบกลับ. เมื่อฉันพยายามสร้าง usbhid.ko ฉันใช้คำสั่งนี้ "make modules SUBDIRS = drivers / hid / usbhid"
SpecC

เมื่อฉันรันคำสั่ง "ทำให้ modules SUBDIRS = drivers / hid / usbhid" ฉันได้รับคำเตือนต่อไปนี้ "คำเตือน: Symbol version dump /usr/src/linux-source-2.6.31/Module.symvers จะหายไปโมดูลจะมี ไม่มีการพึ่งพาและการ
ดัดแปลง

@SpecC ในขณะที่คุณตรวจสอบปัญหาของคุณให้อัปเดตคำถามเดิมด้วยขั้นตอนที่คุณทำ จากนั้นแดนจะอัปเดตคำตอบของคุณและคุณจะอัปเดตต่อไปจนกว่าคุณจะคิดออกมาแทนความคิดเห็นที่ฝังอยู่ให้ดูคำแนะนำเพิ่มเติมสำหรับคำแนะนำ: meta.askubuntu.com/questions/257/how-does-ask -ubuntu-work
Jorge Castro
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.