linux驅動:使用者空間,核心空間記憶體互動測試
環境:
主機:fedora12
目標板:mini6410
目標板linux核心版本:2.6.38
實現功能:
使用read函式讀取核心空間開闢的陣列,使用write函式從使用者空間寫入資料到核心空間開闢的陣列
說明:
linux中核心空間和使用者空間有不同的記憶體定義,只能通過互動函式來互相訪問.
//檢測使用者空間位址是否合法,type選項:verify_read,verify_write
int access_ok(int type,const void *addr,unsigned long size);
//從使用者空間讀取記憶體
unsigned long copy_from_user(void *to,const void *from,unsigned long n);
//向使用者空間記憶體寫入
unsigned long copy_to_user(void *to,void *from,unsigned long len);
//寫入單值
int put_user(資料,ptr);
//讀取單值
int get_user(資料,ptr);
驅動源**:
test_driver.c:
#include #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define device_name "test_driver"
#define t_majors 800
//裝置結構
static struct _test_driver_device
;struct _test_driver_device *test_driver_device;
static dev_t dev;
static struct class *test_class;
//開闢快取,用來讀寫
#define len_buf 256
static unsigned char buffer[len_buf];
//初始化互斥鎖
static define_mutex(sem);
//功能:初始化快取
static void init_buf(void)
//功能:讀取快取
//返回:讀取的位元組數
ssize_t test_driver_read(struct file *filp,char __user *buf,size_t count,loff_t *f_pos)
//判斷讀取的位元組總數是否越界
if (count > (len_buf - *f_pos))
//拷貝資料到使用者空間
if (copy_to_user(buf,buffer + *f_pos,count))
//改變檔案的當前位置
*f_pos += count;
return count;
}//功能:寫入快取
//返回:寫入的位元組數
ssize_t test_driver_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_pos)
//判斷寫入的位元組總數是否越界
if (count > (len_buf - *f_pos))
//從使用者空間拷貝資料
if (copy_from_user(buffer + *f_pos,buf,count))
//改變檔案的當前位置
*f_pos += count;
return count;
err:
return err;
}//功能:偏移指標
//返回:當前指標
//off是偏移量,whence是偏移開始處
ssize_t test_driver_llseek(struct file *filp,size_t count,loff_t off,int whence)
//從當前位置開始
case 1:
case 2:
default:
}//判斷是否超出範圍
if (pos > len_buf || pos < 0)
//更改當前偏移量
filp->f_pos = pos;
return filp->f_pos;
}static struct file_operations io_dev_fops = ;
static int __init dev_init(void)
dev = mkdev(t_majors,0);
cdev_init(&test_driver_device->fun_cdev,&io_dev_fops);
ret = register_chrdev_region(dev,1,device_name);
if (ret < 0) return 0;
ret = cdev_add(&test_driver_device->fun_cdev,dev,1);
if (ret < 0) return 0;
printk (device_name"\tjdh:test_driver initialized!!\n");
test_class = class_create(this_module, "test_class1");
if (is_err(test_class))
device_create(test_class, null, dev, null, "test_driver");
return ret;
}static void __exit dev_exit(void)
module_init(dev_init);
module_exit(dev_exit);
module_license("gpl");
module_author("jdh");
使用者程式:
test_driver.c
#include #include #include #include "stdio.h"
#include "sys/types.h"
#include "sys/ioctl.h"
#include "stdlib.h"
#include "termios.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "sys/time.h"
#include #include int main(int argc, char** argv)
//寫入資料
for (i = 0;i < 256;i++)
write(fd,buf,256);
//偏移到第10位
lseek(fd,10,0);
//讀取資料
read(fd,temp,100);
//輸出
for (i = 0;i < 10;i++)
close(fd);
return 0;
}
測試說明:
將編譯所得的可執行檔案test_driver上傳到開發板
執行:
./test_driver
輸出:
10 11 12 13 14 15 16 17 18 19
linux核心空間與使用者空間
核心空間和使用者空間是作業系統理論的基礎之一,即核心功能模組執行在核心空間,而應用程式執行在使用者空間。現代的cpu都具有不同的操作模式,代表不同的級別,不同的級別具有不同的功能,在較低的級別中將禁止某些操作。linux系統設計時利用了這種硬體特性,使用了兩個級別,最高端別和最低級別,核心執行在最高...
Linux核心空間和使用者空間
在linux系統中存在程序的概念 程序的分類 使用者程序 執行在使用者空間的程序被稱為使用者程序 核心程序 執行在核心空間的程序被稱為核心程序 程序的空間 系統會為每乙個程序分0 4g的虛擬定址空間,在4g的空間中 0 3g 屬於使用者空間,用來執行使用者的相關程序 3 4g 屬於核心空間,用來執行...
Linux的使用者空間與核心空間
當核心模組 或執行緒訪問記憶體時,中的記憶體位址都為邏輯位址,而對應到真正的物理記憶體位址,需要位址一對一的對映,如邏輯位址0xc0000003對應的實體地址為0 3,0xc0000004對應的實體地址為0 4,邏輯位址與實體地址對應的關係為 邏輯位址物理記憶體位址 0xc0000000 0 00x...