在運作《Linux裝置驅動程式》第三版書中的示例代碼時出現了很多編譯錯誤 ,主要原因是我的系統核心版本為 2.6.39,而示例代碼運作的核心版本為 2.6.10。以下是我遇到的問題以及解決方案:
- make時出現錯誤:
CFLAGS was changed ....Fix it to use EXTRA_FLAGS
解決方法:将Makefile中的LDD3示例代碼Scull編譯問題
改為CFLAGS += $(DEBFLAGS) CFLAGS += -I$(LDDINC)
EXTRA_CFLAGS += $(DEBFLAGS) EXTRA_CFLAGS += -I$(LDDINC)
-
error: linux/config.h: No such file or directory
原因:config.h這個頭檔案在2.6.19的核心版本以後就沒有了
解決方法:将該行代碼注釋掉
- 如圖錯誤: 解決方法:引用頭檔案
LDD3示例代碼Scull編譯問題 #include<linux/sched.h>
-
原因:task_struct結構體定義有所改動,将error: 'struct task_struct' has no member named 'uid'
和uid
等挪到了euid
中,參見cred
和include/linux/sched.h
include/linux/cred.h
兩個頭檔案
解決方案 :将報錯的代碼做如下修改(參考網址):
修改為current->uid
current->cred->uid
修改為current->euid
current->cred->euid
-
原因:SPIN_LOCK_UNLOCKED’未聲明(不在函數内)
SPIN_LOCK_UNLOCKED
自2.6.19被棄用,将在2.6.39中删除。
解決方法:将
改為static spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED;
。别的用到static DEFINE_SPINLOCK(scull_u_lock);
的地方也作相應修改。參考網址SPIN_LOCK_UNLOCKED
-
原因:2.6.36核心之後,unknown field 'ioctl' specified in initializer
結構體去掉了原來的file_operations
,添加了兩個新的成員:ioctl
解決方法: 将代碼中long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
結構體中的file_operations
改為.ioctl
即可。參考網址.compat_ioctl
-
原因:error: implicit declaration of function ‘init_MUTEX’)
在 Linux2.6.37 之後的核心中已經被廢除了, 新版本使用init_MUTEX
函數:sema_init
。static inline void sema_init(struct semaphore *sem, int val);
等同于init_MUTEX(&sem)
sema_init(&sem, 1)
。
解決方法:将代碼中用到
的地方都替換為init_MUTEX
。也可使用參考網址的另一種方法。sema_init
-
原因:從2.6.20的核心開始,error: macro "INIT_WORK" passed 3 arguments, but takes just 2
INIT_WORK
宏做了改變,原來是三個參數,後來改成了兩個參數。
解決方法:将代碼按如下方式改變(參考網址):
static void ppsc_tq_int (void *data) --> static void ppsc_tq_int (struct work_struct *data) INIT_WORK (&pha->wq, ppsc_tq_int, pha); --> INIT_WORK (&pha->wq, ppsc_tq_int);
-
原因:2.6.24以後删除了error: ‘SA_INTERRUPT’ undeclared (first use in this function)
,使用SA_INTERRUPT
代替。IRQF_DISABLED
由SA_SHIRQ
IRQF_SHARED
代替(參考網址)
解決方法:将
修改為SA_INTERRUPT
即可 。參考網址IRQF_DISABLED
-
原因:error: ‘struct device’ has no member named ‘driver_data’
已經被移入driver_data
中,該結構在struct device_private
中定義。/drivers/base/base.h
-
和error: ‘NOPAGE_SIGBUS’ undeclared (first use in this function)
原因:新版本error: unknown field ‘nopage’ specified in initializer
去掉了vm_operations_struct
成員,參見nopage
/include/linux/mm.h
。
解決方法:注釋掉相關内容參考網址
-
原因:新版本的核心中error: ‘struct device’ has no member named ‘bus_id’
已經沒有struct device
成員,而是通過bus_id
和static inline const char *dev_name(const struct device *dev)
extern int dev_set_name(struct device *dev, const char *name, ...)
對裝置的名字進行操作。參考網址
解決方法:針對我的代碼:将
改為strncpy(ldddev->dev.bus_id, ldddev->name, BUS_ID_SIZE);
dev_set_name(&ldddev->dev, ldddev->name);
-
原因:新版本核心‘struct attribute’ has no member named ‘owner’
結構中已經沒有struct attribute
owner
成員
解決方法:我的解決方法是先注釋掉相關語句。
-
原因:新版本核心error: unknown field ‘hotplug’ specified in initializer
結構中已經沒有struct bus_type
hotplug
成員
解決方法:我的解決方法是先注釋掉相關語句。
-
no symbol version for ...
原因:這是linux kernel 2.6.26 之後版本的bug。參考網址
解決方法:隻要将子產品中的Makefile中加上
,重新編譯子產品即可。KBUILD_EXTRA_SYMBOLS
LDD3示例代碼Scull編譯問題