久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

學嵌入式Linux內(nèi)核還有這個好處,?

 西北望msm66g9f 2018-07-02

就當我還在學校的時候,我就曾在一個裝機群里聽一位裝機圣手說,,驅動程序的安裝沒你想的那么簡單,分類型的,,分為字符設備驅動和塊設備驅動,。我當時就納悶了,,我說我裝機的時候好像沒看到啊,我就把光盤放過去然后就一直點下一步,,然后重啟就好了啊,。后面我在群里被幾位高手圍攻,敗下陣來,,時過境遷,,哥現(xiàn)在也算是道上混的兄弟了,再也沒那么容易被蒙了,。就算你DIY再牛,,你也不要和我說裝驅動要分類。否則我就和你講內(nèi)核,,講暈你再說,。看誰更能吹,,哈哈,。我得意的笑。我發(fā)現(xiàn)學內(nèi)核的一個好處,,就是非常好裝B,。你只要把內(nèi)核里面的名詞背熟了,拿出來去嚇唬嚇唬人,,挺管用的,,不過撞到行家的話,你就要注意了,。呵呵,。


好了,學內(nèi)核不是為了嚇唬人的,,是為了掌握其原理,,學習其技巧與方法,知其然而知其所以然,,另外內(nèi)核代碼是具有一定復雜度的,,看了內(nèi)核代碼再看看我們自已寫的,和玩具沒啥兩樣,,這就是學內(nèi)核的好處!


如果你已經(jīng)看過驅動模型應該有這種感受:你這玩意折騰來折騰去半天的,,昨不干活呢?


字符設備是傳說中的東西,玩過linux的人都知道這個東西,,很多同志也可以照貓畫虎的寫出一個字符設備,。但哥不,哥是有追求的人,,知其然,,必需得知其所以然,。我決不會不負責任的把大家領進門后就不管了。我依然會不惜筆墨的把該說的全都說清楚,。


我們先不用去摳概念,,不要說,什么是字符設備啊,,什么是塊設備啊,。這些都沒意義,你最需要知道的是這個叫字符設備的東西究竟都干了些啥?他到底是怎么工作的?搞清楚后,,什么是字符設備你就明白了,。如果再學塊設備,一對比,,差異在哪?你就明白了,。我學習一向都不喜歡摳概念。有的同志你叫字符設備他回答你說char設備,,你說塊設備他說block設備,,你說底半部他說下半部。你說NXP他說恩智浦,,還好哥是道上混的,,多少知道一點。否則就被人家給唬住了,。好了,,閑話不多說了,總的來說要表達的就是一種學習態(tài)度:不用摳概念,。


接下來我們欣賞一下字符設備,。


看過驅動模型系列的朋友現(xiàn)在應該有一種意識了,我們暫且把它叫做“初始化意識”,。就是說你用register_chrdev()注冊的時候是很爽,,但是那是因為前人把路鋪好了,好,,我們就來看看前人都做了些啥,,再提醒一次一定要有“初始化意識”。


我們在“初始化意識”的指引下找到了一個文件:char_dev.c,。打開這個文件一看,。有這么一個初始化函數(shù):

void __init chrdev_init(void)

{

cdev_map = kobj_map_init(base_probe, &chrdevs_lock);

bdi_init(&directly_mappable_cdev_bdi);

}

base_probe是一個很簡單的函數(shù):

static struct kobject *base_probe(dev_t dev, int *part, void *data)

{

if (request_module('char-major-%d-%d', MAJOR(dev), MINOR(dev)) > 0)

/* Make old-style 2.4 aliases work */

request_module('char-major-%d', MAJOR(dev));

return NULL;

}


request_module這個函數(shù)先大概知道意思就行了,他的意思是請求加載一個模塊,。

chrdevs_lock是一把大大的鎖,。沒別的,就這兩玩意。


關鍵在:

struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock)

{

struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);

struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);

int i;

if ((p == NULL) || (base == NULL)) {

kfree(p);

kfree(base);

return NULL;

}

base->dev = 1;

base->range = ~0;

base->get = base_probe;

for (i = 0; i < 255;="">

p->probes[i] = base;

p->lock = lock;

return p;

}

最關鍵的一個角色就在這種神不知鬼不覺的情況下登場了,,那就是struct kobj_map,。


我們可以看到首先用kmalloc分配了一塊內(nèi)存并賦值給struct kobj_map *p了。


struct kobj_map {

struct probe {

struct probe *next;

dev_t dev;

unsigned long range;

struct module *owner;

kobj_probe_t *get;

int (*lock)(dev_t, void *);

void *data;

} *probes[255];

struct mutex *lock;

};

里面內(nèi)嵌了一個長度為255的結構體數(shù)組和一把鎖,。


Linux內(nèi)核里面如果是直接分配比較大塊的內(nèi)存,基本都是有hash思想在里面的,,主要是為了效率,。這個結構體中的成員等會大家就知道干嘛用的了。


接下來

struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);

內(nèi)核作者你就賣弄吧,。寫成struct probe *base = kzalloc(sizeof(struct probe), GFP_KERNEL)這樣多好?不管了,,隨便了,反正我只取其精華,。


接下來:

if ((p == NULL) || (base == NULL)) {

kfree(p);

kfree(base);

return NULL;

}


如果對這個有疑問的同志可以仔細研究一下kfree函數(shù),。這個是沒有問題的。我再說一個思想,,有疑問就看源碼,,不要去翻書,或者google百度的,。Linux內(nèi)核里面的函數(shù)全都是自給自足的,,你所有的疑問都可以通過翻閱內(nèi)核源碼本身得到解決。當然啦,,如果不是說不要去看書,,我的意思是能不看就盡量不看。


接下來:

base->dev = 1;

base->range = ~0; //取反,,比你寫一堆0xff...好多了,,并且可移植性更好

base->get = base_probe;//把函數(shù)指針指向傳進來的那個回調函數(shù)。

接下來:

for (i = 0; i < 255;="">

p->probes[i] = base;

用base初始化整個kobj_map.probe[255],。

p->lock = lock;

return p;

最后把鎖也傳過來,,并返回指針。


接下來:

bdi_init(&directly_mappable_cdev_bdi);

這個玩意先不用管了,,這個對我們理解字符設備目前沒有任何幫助,,并且只能添亂。


好了,。今天就到這吧,。 





    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多