前幾天在幫 NAS 灌上 Virtualbox 時編譯 kernel module(DKMS) 時出錯,後來手動編譯,卻在 insmod 時 出現錯誤,dmesg 也出現下面這樣的錯誤訊息:
$ insmod vboxdrv/vboxdrv.ko insmod: error inserting 'vboxdrv/vboxdrv.ko': -1 Invalid parameters $ dmesg | tail [84167.691738] vboxdrv: disagrees about version of symbol sched_setscheduler [84167.698665] vboxdrv: Unknown symbol sched_setscheduler (err -22) [84167.704799] vboxdrv: disagrees about version of symbol wake_up_process [84167.711336] vboxdrv: Unknown symbol wake_up_process (err -22) [84167.717174] vboxdrv: disagrees about version of symbol __free_pages [84167.723506] vboxdrv: Unknown symbol __free_pages (err -22)
會出現這樣的錯誤,大概是因為我沒有原本 NAS 的 kernel source code and config,所以只能用 uname -r 找到一個差不多的版本,再參考其 header 編譯造成。但是該如何解這樣的問題呢?
首先確定每個 unknown symbol 的位址,以 sched_setscheduler 為例:
$ grep 'T sched_setscheduler$' /proc/kallsyms ffffffff8105c250 T sched_setscheduler
接著準備 symbol address map,如下:
$ tee addrs.dat <%lt;EOF SECTIONS { sched_setscheduler = 0xffffffff8105c250; wake_up_process = 0xffffffff8105a400; __free_pages = 0xffffffff81111de0; } EOF
這個格式應該很容易懂,大概就是 <unknown symbol> = <address> 這樣的格式。最後重新 link ko 用以下指令:
$ ld -r -o vboxdrv/vboxdrv-1.ko vboxdrv/vboxdrv.ko -R addrs.dat
打完收工。
1 comment:
用linux编程
递归目录遍历
Post a Comment