android分層學習筆記(五)

來源:互聯網
上載者:User

在android系統中,以上幾個小節文章中,把它的分層做了一些簡單的描述,接下就是核心驅動相關的內容。這是一個自由的世界,當然很複雜。也正是因為自由,才可以構建不同的作業系統世界,android是其中之一。不管android是不是傳統意義上的linux上的作業系統,它畢竟實現了一些很有用的東西。

     對於核心這裡不想詳細展開,畢竟自己的功底也有限。單說一些簡單的驅動。事實上,自己所接觸的驅動頗為簡單,無外乎管腳的控制。下面以一個簡單char驅動來說明android底層的東西,其實就是linux驅動內容:

 

對於驅動開發,那麼肯定是要看“
Linux
裝置驅動程式第三版
2.6
”(
LDDP
)這本書了。目前已經是
2.6
版本了,有中文版本。

      

看完這本書,再看以下例子,你會覺得非常簡單。不看那本書,按照以下例子,當然也可以寫一個簡單的驅動程式,需要注意的下面的例子是字元驅動。

      


linux
下驅動有一個架構,一般來說完成以下幾個函數就可以了。

xxx_read(struct file *filp, char __user
*buff, size_t count, loff_t *offp)

xxx_write(struct file *filp, const char
__user *buff, size_t count, loff_t *offp)

xxx_open(struct inode *inode, struct file
*filp)

xxx_release(struct inode *inode, struct
file *filp)

xxx_ioctl(struct inode *inode, struct file
*file,

                                  
unsigned
int cmd, unsigned long arg)

static int __init xxx_init(void)

static void __exit xxx_exit(void)

 

module_init(xxx_init);

module_exit(xxx_exit);

 

      

實際應用中,字元驅動
write/read
函數很少用到。一般也可以不實現,可以由
ioctl
函數來實現。

      

驅動與應用程式介面函數對應,看驅動函數的名字就知道了。

      
xxx_read 
<---> read

xxx_write 
<---> write

xxx_open 
<---> open

xxx_release 
<---> close

xxx_ioctl 
<---> ioctl

      

也就是說,在應用程式調用
read,write,open,ioctl
函數,最終就是調用其驅動的對應的函數。

      


insmod
時,會調用
xxx_init

      


rmmod
時,會調用
xxx_exit

 

對於
xxx_init
函數,那麼要實現的東西比較多,比如
io
口的設定,或其他變數的初始賦值,驅動的註冊,裝置節點的建立等。相應地,
xxx_exit
就完成
xxx_init
所做事下結逆過程。此處詳說:

每個驅動都有一個主裝置號和次裝置號,可以固定設定,但不能有衝突。最好的方法是系統分配,這也是
LDDP
作者所建議的。

static struct
file_operations xxx_fops =

{

   
.owner     

=   
THIS_MODULE,

   
.open      

=   
xxx_open,

   
.release   

=   
xxx_release,

   
.ioctl     

=   
xxx_ioctl,

   
.read      

=   
xxx_read,

   
.write     

=   
xxx_write,

};

struct cdev xxx_cdev;

struct class *xxx_class;

Int
xxx_init(void)

{

int res, err;

   
dev_t dev = MKDEV(xxx_major, 0);

   
if (xxx_major)

   
{

       
res = register_chrdev_region(dev, 1,
DEVICE_NAME); //
固定分配

   
}

   
else

   
{

       
res = alloc_chrdev_region(&dev, 0,
1, DEVICE_NAME);//
動態分配

       
xxx_major = MAJOR(dev);

   
}

 

   
if (res < 0)

   
{

       
printk("xxx_device: unable to get
major %d/n", xxx_major);

       
return res;

 

   
}

 

   
if (xxx_major == 0)

   
{

       
xxx_major = res;

   
}

   
cdev_init(&xxx_cdev, &xxx_fops);

      
xxx_cdev.owner = THIS_MODULE;

      
xxx_cdev.ops = &xxx_fops;

      
err = cdev_add (&xxx_cdev, dev, 1);
//
註冊
cdev

      
if (err)

      
{

             
printk ("Error %d adding xxx%d",
err, 0);

      
}

   
xxx_class = class_create(THIS_MODULE,
"xxx_class");

   
device_create(xxx_class, NULL, dev,
DEVICE_NAME, "xxx%d", 0);

   
other_init();

}

 

int xxx_exit(void)

{

      
xxx_release(NULL, NULL);

cdev_del(&xxx_cdev);

device_destroy(xxx_class, MKDEV(xxx_major, 0));

class_destroy(xxx_class);

unregister_chrdev_region(MKDEV(xxx_major, 0), 1);

}

對於
xxx_open,
可以簡單提示一些資訊,表示此驅動載入。
同樣
xxx_release
也可以用簡單的提示一些資訊,表明關閉驅動了。

重點是在
xxx_ioctl
函數,我們基本所有的操作就在這裡了。

static int
epi_ioctl(struct inode *inode, struct file *file,

                                  
unsigned int
cmd, unsigned long arg)

{

  
char val = 1;

  
switch (cmd)

  
{

    
case IO_CMD_TEST_SET:

    
copy_from_user(&val, (char *)arg, 1);

      
 
printk(“%d”, val);

    
break;

case IO_CMD_TEST_GET:

    
copy_to_user( (char *)arg, &val, 1);

    
break;

    
default:

      
break;

  
}

  
return 0;

}

      

以上所實現的是從
arg
中取得資料,把資料放到
arg
中兩個功能。用到了
copy_from_usr

copy_to_usr
兩個函數。為什麼有這兩個函數:是因為驅動是工作核心空間,應用程式是工作在使用者空間。如果直接用
memcpy
這些函數,可能核心空間的資料已經實效,那麼複製到使用者空間的則可能得到錯誤的資訊。

 

      

寫完驅動,就可進行編譯,那麼要寫
Makefile
以方便編譯。

obj-m += xxx.o

#
核心代碼樹位置

KDIR:=/home/alsa/kernel/linux_2.6.28

#
設定編譯器

CROSS_COMPILE = arm-none-linux-gnueabi-

CC := $(CROSS_COMPILE)gcc

LD := $(CROSS_COMPILE)ld

PWD=$(shell pwd)

all: build install

build: clean

      
$(MAKE)
-C $(KDIR) M=$(PWD) modules

clean:

      
rm
-rf *.o *.ko

儲存,後運行
make
,則在目前的目錄下產生
xxx.ko
檔案。

 

最後通過載入驅動:

載入: insmod xxx.ko

卸載:  rmmod xxx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.