日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

access驱动程序_Linux驱动程序学习二 (续) scull 源码在内核5.4.0上的编译调试

發布時間:2024/7/23 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 access驱动程序_Linux驱动程序学习二 (续) scull 源码在内核5.4.0上的编译调试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

《LINUX設備驅動程序》第三章提供了源碼scull,但是由于我用的是5.4.0內核,書中的是2.6.10內核,內核發生了很大的變化,因此編譯scull源碼花費了不少時間,下面是編譯調試記錄。(這個編譯調試記錄應該是目前網絡上適應內核版本最高的,所以也希望給近期加入《LINUX設備驅動程序》學習的小白們一個參考)。

一、main.c

1、make出現以下兩個錯誤:

/home/valian/scull/main.c:17:26: fatal error: linux/config.h: 沒有那個文件或目錄 /home/valian/scull/main.c:32:46: fatal error: asm/system.h: 沒有那個文件或目錄

直接在main.c中刪除這兩個頭文件.在新的內核里棄用了這兩個.

2、copy_to_user copy_from_user

/home/valian/scull/main.c:324:6: error: implicit declaration of function ‘copy_to_user’ [-Werror=implicit-function-declaration]if (copy_to_user(buf, dptr->data[s_pos] + q_pos, count)) {^ /home/valian/scull/main.c: In function ‘scull_write’: /home/valian/scull/main.c:373:6: error: implicit declaration of function ‘copy_from_user’ [-Werror=implicit-function-declaration]if (copy_from_user(dptr->data[s_pos]+q_pos, buf, count)) {

新內核修改了這兩個函數名稱,更改如下:

copy_to_user()改為raw_copy_to_user(); copy_from_user()改為raw_copy_from_user();

3、access_ok

/home/valian/scull/main.c:414:68: error: macro "access_ok" passed 3 arguments, but takes just 2err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));^ /home/valian/scull/main.c:414:10: error: ‘access_ok’ undeclared (first use in this function)err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));^ /home/valian/scull/main.c:414:10: note: each undeclared identifier is reported only once for each function it appears in /home/valian/scull/main.c:416:68: error: macro "access_ok" passed 3 arguments, but takes just 2err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));

從錯誤提示看,大概是新內核的access_ok的參數為2個,但是原來內核為3個。

通過以下指令在源碼中查找access的出出處:

find /lib/modules/5.4.0/build/include/linux -type f -exec grep "access_ok" {} ; -print

得到以下提示:

從提示看到新的access_ok的參數為(ptr,len),于是修改代碼如下:

err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); 改為err = !access_ok((void __user *)arg, _IOC_SIZE(cmd));

4 、.ioctl (可參考CSDN-專業IT技術社區-登錄)

make -C /lib/modules/5.4.0/build M=/home/valian/scull LDDINC=/home/valian/scull/../include modules make[1]: Entering directory '/usr/src/linux-5.4'CC [M] /home/valian/scull/main.o /home/valian/scull/main.c:558:2: error: unknown field ‘ioctl’ specified in initializer.ioctl = scull_ioctl,^ /home/valian/scull/main.c:558:14: error: positional initialization of field in ‘struct’ declared with ‘designated_init’ attribute [-Werror=designated-init].ioctl = scull_ioctl,

ioctl是未知域,同樣檢索ioctl

find /lib/modules/5.4.0/build/include/linux -type f -exec grep "ioctl" {} ; -print

得到(在/lib/modules/5.4.0/build/include/linux/fs.h)

long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); // 5.4.0int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long); // 2.6.10 網絡上查找

對比發現.ioctl變為.unlocked_ioctl,函數指針的原型也變了,少了struct inode * 這個指針參數,而且函數類型也由int變為long。修改如下;

.ioctl = scull_ioctl改為 .unlocked_ioctl = scull_ioctl;

函數scull_ioctl改為(main.c 和scull.h)

long scull_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); // int 改為long,struct inode* 刪除

5、init_MUTEX

/home/valian/scull/main.c: In function ‘scull_init_module’: /home/valian/scull/main.c:653:3: error: implicit declaration of function ‘init_MUTEX’ [-Werror=implicit-function-declaration]init_MUTEX(&scull_devices[i].sem);


通過以下命令

find /lib/modules/5.4.0/build/include/linux -type f -exec grep "init_MUTEX" {} ; -print

查找,結果沒有找到,應該是這個函數名稱被棄用。在網絡中找到解決方法init_MUTEX(&sem)被sema_init(&sem,1)替換了。

init_MUTEX(&scull_devices[i].sem); 改為sema_init((&scull_devices[i].sem),1);

sema_init的定義可參考/lib/modules/5.4.0/build/include/linux/semaphore.h

static inline void sema_init(struct semaphore *sem, int val)

pipe.c

1:init_MUTEX

同main.c,init_MUTEX改為sema_init;

//init_MUTEX(&scull_p_devices[i].sem); sema_init((&scull_p_devices[i].sem),1);

2、signal_pending

/home/valian/scull/pipe.c: In function ‘scull_getwritespace’: /home/valian/scull/pipe.c:172:7: error: implicit declaration of function ‘signal_pending’ [-Werror=implicit-function-declaration]if (signal_pending(current))

從錯誤代碼查找關鍵詞signal_pending的定義:

查找命令

find /lib/modules/5.4.0/build/include/linux -name '*.h' | xargs grep -w "signal_pending"

得到如下信息:

valian@valian-TM1703:~/scull$ find /lib/modules/5.4.0/build/include/linux -name '*.h' | xargs grep -w "signal_pending" /lib/modules/5.4.0/build/include/linux/sched/signal.h:static inline int signal_pending(struct task_struct *p)

從signal_pending定義看函數參數沒有改變,但是沒有包含/linux/sched/signal.h頭文件。

加上頭文件:

#include <linux/sched/signal.h>

access.c

1、.ioctl 錯誤,參考上面的改正方法。

2、init_MUTEX

init_MUTEX(&(lptr->device.sem));改為sema_init(&(lptr->device.sem),1);

3、SPIN_LOCK_UNLOCKED

/home/valian/scull/access.c:98:34: error: ‘SPIN_LOCK_UNLOCKED’ undeclared here (not in a function)static spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED;

從提示看沒有定義。查找關鍵詞

find /lib/modules/5.4.0/build/include/linux -type f -exec grep "SPIN_LOCK_UNLOCKED" {} ; -print

得到以下信息

#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x) /lib/modules/5.4.0/build/include/linux/spinlock_types.h

根據以上信息與源碼中“static spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED;”對比發現,宏定義 DEFINESPINLOCK(x) 代替了源碼中spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED。因此按以下修改即可。

//static spinlock_t scull_u_lock = SPIN_LOCK_UNLOCKED; //static spinlock_t scull_c_lock = SPIN_LOCK_UNLOCKED; //static spinlock_t scull_w_lock = SPIN_LOCK_UNLOCKED;static DEFINE_SPINLOCK(scull_u_lock) ;static DEFINE_SPINLOCK(scull_c_lock) ;static DEFINE_SPINLOCK(scull_w_lock) ;

4、uid euid

/home/valian/scull/access.c:108:29: error: ‘struct task_struct’ has no member named ‘uid’(scull_u_owner != current->uid) && /* allow user */^ /home/valian/scull/access.c:109:29: error: ‘struct task_struct’ has no member named ‘euid’(scull_u_owner != current->euid) && /* allow whoever did su */

查找關鍵詞struct task_struct

find /lib/modules/5.4.0/build/include/linux -type f -exec grep "struct task_struct" {} ; -print

眾多信息中找到定義在/lib/modules/5.4.0/build/include/linux/sched.h

struct task_struct { ........... } /lib/modules/5.4.0/build/include/linux/sched.h

但是查找sched.h中struct task_struct的定義,沒有找到“uid,euid”。網絡搜尋得知新的struct taskstruct 定義有變化,uid和euid在cred結構體中(在頭文件/lib/modules/5.4.0/build/include/linux/cred.h中)。如下圖找到uid,euid,其類型為kuid_t。

在</lib/modules/5.4.0/build/include/linux/uidgid.h>中查到kuid_t為結構體類型,定義如下:

typedef struct {uid_t val; } kuid_t;

access.c中scull_u_owner的類型為static uid_t scull_u_owner。因此需要修改代碼如下:

(current->uid改為current->cred->uid,current->euid改為current->cred->euid)

//scull_w_owner == current->uid || //scull_w_owner == current->euid || 改為 scull_w_owner == current->cred->uid.val || scull_w_owner == current->cred->euid.val ||// (scull_u_owner != current->uid) && /* allow user */ // (scull_u_owner != current->euid) && /* allow whoever did su */ 改為(scull_u_owner != current->cred->uid.val) && /* allow user */(scull_u_owner != current->cred->euid.val) && /* allow whoever did su */

過程中出現以下錯誤可參考[PATCH 0/5] PMFS: Rebase to Linux 3.9

/home/valian/SLAM/linux/scull/access.c:115:19: error: invalid operands to binary != (have ‘uid_t {aka unsigned int}’ and ‘kuid_t {aka const struct <anonymous>}’)(scull_u_owner != current->cred->uid) && /* allow user */^ /home/valian/SLAM/linux/scull/access.c:116:19: error: invalid operands to binary != (have ‘uid_t {aka unsigned int}’ and ‘kuid_t {aka const struct <anonymous>}’)(scull_u_owner != current->cred->euid) && /* allow whoever did su */

5、struct signal_struct

/home/valian/SLAM/linux/scull/access.c:283:22: error: dereferencing pointer to incomplete type ‘struct signal_struct’if (!current->signal->tty) {

錯誤提示可能是沒有聲明對應結構體定義的頭文件。查找struct signal_struct的定義:

find /lib/modules/5.4.0/build/include/linux -type f -exec grep "struct signal_struct" {} ; -print

得到以下結果,在/lib/modules/5.4.0/build/include/linux/sched/signal.h。

struct signal_struct { static inline void signal_set_stop_flags(struct signal_struct *sig, static inline int signal_group_exit(const struct signal_struct *sig) /lib/modules/5.4.0/build/include/linux/sched/signal.h

在assess.c中加上頭文件;

#include <linux/sched/signal.h>

至此scull源碼在內核linux5.4.0上編譯通過。

總結

以上是生活随笔為你收集整理的access驱动程序_Linux驱动程序学习二 (续) scull 源码在内核5.4.0上的编译调试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。