自己動手寫驅動程式

2021-08-06 05:37:41 字數 4060 閱讀 4468

一、編碼思維導圖

二、編寫**

memdev.c

#include

#include

#include

#include

#include

struct cdev mdev;                                 //1.靜態分配cdev

dev_t devno;

int dev1_regs[5]

;int dev2_regs[5]

;loff_t mem_lseek(struct file *filep, loff_t offset,

int whence)

filep-

>f_pos = new_pos;

return new_pos;

}size_t mem_read(struct file *filep, char __user *buf, size_t size, loff_t *ppos)

size_t mem_write(struct file *filep,

const char __user *buf, size_t size, loff_t *ppos)

size_t mem_open(struct inode *node, struct file *filep)

int mem_close (struct inode *node, struct file *filep)

struct file_operations memfops =

;int memdev_init(

)void memdev_exit(

)module_init(memdev_init)

;                    //初始化入口

module_exit(memdev_exit)

;                    //模組退出

三、函式學習

裝置初始化:cdev_init

原型:void cdev_init(struct cdev *cdev, const struct file_operations *fops);

cdev:待初始化的cdev結構

fops:裝置對應的操作函式集

動態分配裝置號:alloc_chrdev_region

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name);

dev:分配後裝置號的位址

baseminor:起始地裝置序號

count:分配的個數

name:分配後的裝置別名

裝置註冊:cdev_add

int cdev_add(struct cdev *p, dev_t dev, unsigned count);

p:待新增的字元裝置結構

dev:裝置號

count:該類裝置的裝置個數

登出裝置:cdev_del

void cdev_del(struct cdev *p);

p:待登出的裝置結構

釋放裝置號:unregister_chrdev_region

void unregister_chrdev_region(dev_t from, unsigned count);

from:待釋放裝置號

count:釋放的裝置個數

四、驅動訪問模型

1.應用程式訪問read

arm-linux-objdump -d read_mem

00008228

:8228: e92d4800 push

822c: e28db004 add fp, sp, #4 ; 0x4

8230: e24dd008 sub sp, sp, #8 ; 0x8

8234: e3a03000 mov r3, #0 ; 0x0

8238: e50b3008 str r3,

[fp, #-8]

823c: e3a03000 mov r3, #0 ; 0x0

8240: e50b300c str r3,

[fp, #-12]

8244: e59f0044 ldr r0,

[pc, #68]

; 8290

8248: e3a01002 mov r1, #2 ; 0x2

824c: eb0028a3 bl 124e0 <__libc_open>

8250: e1a03000 mov r3, r0

8254: e50b3008 str r3,

[fp, #-8]

8258: e24b300c sub r3, fp, #12 ; 0xc

825c: e51b0008 ldr r0,

[fp, #-8]

8260: e1a01003 mov r1, r3

8264: e3a02004 mov r2, #4 ; 0x4

8268: eb0028c0 bl 12570 <__libc_read>

>>libc_read:

00012570 <__libc_read>

:12570: e51fc028 ldr ip

,[pc, #-40]

; 12550 <__libc_open>

12574: e79fc00c ldr ip

,[pc,ip]

12578: e33c0000 teq ip

, #0 ; 0x0

1257c: 1a000006 bne 1259c <__libc_read>

12580: e1a0c007 mov

ip, r7

12584: e3a07003 mov r7, #3 ; 0x3

12588: ef000000 svc 0x00000000

將3放入r7暫存器中

呼叫svc,進入核心空間

通過查表找到read並使用

在entry-common.s中

entry(sys_call_table)

#include "calls.s"

#undef abi

#undef obsolete/*

====

====

====

====

====

====

====

====

====

====

====

====

====

====

====

====

====

====

====

*/@ r0 = syscall number

@ r8 = syscall table

sys_syscall:

bic    scno, r0, #__nr_oabi_syscall_base

cmp    scno, #__nr_syscall - __nr_syscall_base

cmpne    scno, #nr_syscalls    @ check range

stmloia    sp,

@ shuffle args

movlo    r0, r1

movlo    r1, r2

movlo    r2, r3

movlo    r3, r4

ldrlo    pc,

[tbl, scno, lsl #2]

b    sys_ni_syscall

endproc(sys_syscall)

利用3這個編號找到sys_read

>>>read_write.c

ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)

inc_syscr(current);}

return ret;}

0 給主人留下些什麼吧!~~

自己動手寫bootloader

原始出處 作者資訊和本宣告。否則將追究法律責任。為了寫乙個bootloader讓板子跑起來,首先我們要知道bootloader是個什麼東東才行。簡單的說,bootloader就是乙個引導核心啟動的一段小 也就是說當啟動完核心之後,它的使命就已經結束。bootloader生命週期 初始化硬體 設定啟動...

自己動手寫CMS

簡易的cms外掛程式,可供借鑑或者擴充套件 流程 定義內容 分類與組織內容 儲存內容 操作控制內容 定義內容 制定目標 確定需要的內容型別 目標使用者定位 確定目標使用者需要何種技術 分類與組織內容 按內容所屬的邏輯層級關係來劃分 按內容的種類來劃分,比如video text audio等等 儲存內...

自己動手寫的UART2驅動

昨天發現新唐的bsp中沒有提供uart2的定義 即其操作,只定義了uart0和uart1及其驅動操作。但是涉及的板子中又弄了3路串列埠,當然uart2在其中。第一反應就是查閱新唐的資料,nuc1 的前期設計文件中,有些說可以支援uart2,但是又有很多定義的地方都reserve了,就是本該uart2...