RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

嵌入式Linux內(nèi)核字符設(shè)備的詳細(xì)資料概述

Q4MP_gh_c472c21 ? 來(lái)源:未知 ? 作者:易水寒 ? 2018-07-06 09:57 ? 次閱讀

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

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

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

字符設(shè)備是傳說(shuō)中的東西,玩過(guò)linux的人都知道這個(gè)東西,很多同志也可以照貓畫(huà)虎的寫(xiě)出一個(gè)字符設(shè)備。但哥不,哥是有追求的人,知其然,必需得知其所以然。我決不會(huì)不負(fù)責(zé)任的把大家領(lǐng)進(jìn)門(mén)后就不管了。我依然會(huì)不惜筆墨的把該說(shuō)的全都說(shuō)清楚。

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

接下來(lái)我們欣賞一下字符設(shè)備。

看過(guò)驅(qū)動(dòng)模型系列的朋友現(xiàn)在應(yīng)該有一種意識(shí)了,我們暫且把它叫做“初始化意識(shí)”。就是說(shuō)你用register_chrdev()注冊(cè)的時(shí)候是很爽,但是那是因?yàn)榍叭税崖蜂伜昧?,好,我們就?lái)看看前人都做了些啥,再提醒一次一定要有“初始化意識(shí)”。

我們?cè)凇俺跏蓟庾R(shí)”的指引下找到了一個(gè)文件:char_dev.c。打開(kāi)這個(gè)文件一看。有這么一個(gè)初始化函數(shù):

void __init chrdev_init(void)

{

cdev_map = kobj_map_init(base_probe, &chrdevs_lock);

bdi_init(&directly_mappable_cdev_bdi);

}

base_probe是一個(gè)很簡(jiǎn)單的函數(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這個(gè)函數(shù)先大概知道意思就行了,他的意思是請(qǐng)求加載一個(gè)模塊。

chrdevs_lock是一把大大的鎖。沒(méi)別的,就這兩玩意。

關(guān)鍵在:

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; i++)

p->probes[i] = base;

p->lock = lock;

return p;

}

最關(guān)鍵的一個(gè)角色就在這種神不知鬼不覺(jué)的情況下登場(chǎng)了,那就是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)嵌了一個(gè)長(zhǎng)度為255的結(jié)構(gòu)體數(shù)組和一把鎖。

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

接下來(lái)

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

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

接下來(lái):

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

kfree(p);

kfree(base);

return NULL;

}

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

接下來(lái):

base->dev = 1;

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

base->get = base_probe;//把函數(shù)指針指向傳進(jìn)來(lái)的那個(gè)回調(diào)函數(shù)。

接下來(lái):

for (i = 0; i < 255; i++)

p->probes[i] = base;

用base初始化整個(gè)kobj_map.probe[255]。

p->lock = lock;

return p;

最后把鎖也傳過(guò)來(lái),并返回指針。

接下來(lái):

bdi_init(&directly_mappable_cdev_bdi);

這個(gè)玩意先不用管了,這個(gè)對(duì)我們理解字符設(shè)備目前沒(méi)有任何幫助,并且只能添亂。

好了。今天就到這吧。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5082

    文章

    19104

    瀏覽量

    304807
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1372

    瀏覽量

    40276
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11292

    瀏覽量

    209327

原文標(biāo)題:學(xué)嵌入式Linux內(nèi)核還有這個(gè)好處?

文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    分享 嵌入式測(cè)試詳細(xì)資料 嵌入式教學(xué)資料

    實(shí)時(shí)、閉環(huán)、非侵入測(cè)試的自動(dòng)化測(cè)試平臺(tái),適用于嵌入式系統(tǒng)在設(shè)計(jì)、仿真、開(kāi)發(fā)、調(diào)試、測(cè)試、集成驗(yàn)證和維護(hù)等各階段配置項(xiàng)級(jí)別和系統(tǒng)級(jí)別的動(dòng)態(tài)測(cè)試與驗(yàn)證。有嵌入式視頻教學(xué),電子版教科書(shū),詳細(xì)資料
    發(fā)表于 02-06 09:50

    嵌入式Linux學(xué)習(xí)步驟

    系統(tǒng)概述 交叉編譯 配置TFTP服務(wù) 配置NFS服務(wù) 下載Bootloader和內(nèi)核 嵌入式Linux應(yīng)用軟件開(kāi)發(fā)流程熟悉嵌入式系統(tǒng)概念以及
    發(fā)表于 07-03 00:56

    嵌入式 linux字符設(shè)備驅(qū)動(dòng)的設(shè)計(jì)與應(yīng)用,看完你就懂了

    本文通過(guò)實(shí)現(xiàn)對(duì) PXA255開(kāi)發(fā)板外圍字符設(shè)備(電機(jī)、數(shù)碼管、串口和 mini鍵盤(pán))的操作和控制,詳細(xì)討論了嵌入式 linux
    發(fā)表于 04-26 06:35

    嵌入式Linux字符設(shè)備驅(qū)動(dòng)的設(shè)計(jì)與應(yīng)用

    描述了基于嵌入式Linux字符設(shè)備驅(qū)動(dòng)程序的設(shè)計(jì)方法和實(shí)現(xiàn)過(guò)程。以電機(jī)、數(shù)碼管、串口和mini鍵盤(pán)的驅(qū)動(dòng)設(shè)計(jì)為例,詳細(xì)闡述了
    發(fā)表于 02-23 15:45 ?24次下載

    嵌入式Linux字符設(shè)備驅(qū)動(dòng)的設(shè)計(jì)與應(yīng)用

    描述了基于嵌入式Linux字符設(shè)備驅(qū)動(dòng)程序的設(shè)計(jì)方法和實(shí)現(xiàn)過(guò)程。以電機(jī)、數(shù)碼管、串口和mini鍵盤(pán)的驅(qū)動(dòng)設(shè)計(jì)為例,詳細(xì)闡述了
    發(fā)表于 07-14 17:31 ?31次下載

    嵌入式linux開(kāi)發(fā)詳細(xì)資料

    本文主要介紹了嵌入式linux開(kāi)發(fā)詳細(xì)資料
    發(fā)表于 06-05 08:00 ?3次下載

    構(gòu)建嵌入式開(kāi)發(fā)平臺(tái)簡(jiǎn)明指導(dǎo)編譯內(nèi)核鏡像的詳細(xì)資料概述

    本文檔的主要內(nèi)容詳細(xì)介紹的是構(gòu)建嵌入式開(kāi)發(fā)平臺(tái)簡(jiǎn)明指導(dǎo)編譯內(nèi)核鏡像的詳細(xì)資料概述
    發(fā)表于 06-19 08:00 ?10次下載

    基于PXA255開(kāi)發(fā)板外圍字符設(shè)備嵌入式Linux字符設(shè)備驅(qū)動(dòng)設(shè)計(jì)與應(yīng)用

    的驅(qū)動(dòng)程序和應(yīng)用程序的需求在成倍增長(zhǎng)。本文通過(guò)實(shí)現(xiàn)對(duì) PXA255開(kāi)發(fā)板外圍字符設(shè)備(電機(jī)、數(shù)碼管、串口和 mini鍵盤(pán))的操作和控制,詳細(xì)討論了嵌入式
    發(fā)表于 08-21 10:19 ?1184次閱讀
    基于PXA255開(kāi)發(fā)板外圍<b class='flag-5'>字符</b><b class='flag-5'>設(shè)備</b>的<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b><b class='flag-5'>字符</b><b class='flag-5'>設(shè)備</b>驅(qū)動(dòng)設(shè)計(jì)與應(yīng)用

    嵌入式開(kāi)發(fā)Linux網(wǎng)絡(luò)編程培訓(xùn)資料詳細(xì)資料免費(fèi)下載

    本文檔的作用內(nèi)容詳細(xì)介紹的是嵌入式開(kāi)發(fā)Linux網(wǎng)絡(luò)編程培訓(xùn)資料詳細(xì)資料免費(fèi)下載。
    發(fā)表于 09-12 11:55 ?34次下載
    <b class='flag-5'>嵌入式</b>開(kāi)發(fā)<b class='flag-5'>Linux</b>網(wǎng)絡(luò)編程培訓(xùn)<b class='flag-5'>資料</b>的<b class='flag-5'>詳細(xì)資料</b>免費(fèi)下載

    嵌入式教程之嵌入式系統(tǒng)基礎(chǔ)的詳細(xì)資料說(shuō)明

    本文檔的主要內(nèi)容詳細(xì)介紹的是嵌入式教程之嵌入式系統(tǒng)基礎(chǔ)的詳細(xì)資料說(shuō)明主要內(nèi)容包括了:1.系統(tǒng)概述
    發(fā)表于 12-06 17:31 ?30次下載
    <b class='flag-5'>嵌入式</b>教程之<b class='flag-5'>嵌入式</b>系統(tǒng)基礎(chǔ)的<b class='flag-5'>詳細(xì)資料</b>說(shuō)明

    嵌入式教程之Linux的基礎(chǔ)命令詳細(xì)資料說(shuō)明

    本文檔的主要內(nèi)容詳細(xì)介紹的是嵌入式教程之Linux的基礎(chǔ)命令詳細(xì)資料說(shuō)明主要內(nèi)容包括了:1.Linux常用命令2
    發(fā)表于 12-06 17:31 ?8次下載
    <b class='flag-5'>嵌入式</b>教程之<b class='flag-5'>Linux</b>的基礎(chǔ)命令<b class='flag-5'>詳細(xì)資料</b>說(shuō)明

    如何吧Mysql數(shù)據(jù)庫(kù)移植到嵌入式Linux詳細(xì)資料說(shuō)明

    本文檔的主要內(nèi)容詳細(xì)介紹的是如何吧Mysql數(shù)據(jù)庫(kù)移植到嵌入式Linux詳細(xì)資料說(shuō)明。
    發(fā)表于 01-18 08:00 ?4次下載
    如何吧Mysql數(shù)據(jù)庫(kù)移植到<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>的<b class='flag-5'>詳細(xì)資料</b>說(shuō)明

    如何吧SQLite移植到嵌入式Linux系統(tǒng)的詳細(xì)資料說(shuō)明

    本文檔的主要內(nèi)容詳細(xì)介紹的是如何吧SQLite移植到嵌入式Linux系統(tǒng)的詳細(xì)資料說(shuō)明。
    發(fā)表于 01-18 08:00 ?8次下載
    如何吧SQLite移植到<b class='flag-5'>嵌入式</b><b class='flag-5'>Linux</b>系統(tǒng)的<b class='flag-5'>詳細(xì)資料</b>說(shuō)明

    嵌入式硬件系統(tǒng)教程之嵌入式存儲(chǔ)技術(shù)的詳細(xì)資料說(shuō)明

    本文檔的主要內(nèi)容詳細(xì)介紹的是嵌入式硬件系統(tǒng)教程之嵌入式的存儲(chǔ)技術(shù)詳細(xì)資料說(shuō)明包括了:概述,存儲(chǔ)器的性能指標(biāo),存儲(chǔ)器的分類
    發(fā)表于 07-19 17:08 ?14次下載
    <b class='flag-5'>嵌入式</b>硬件系統(tǒng)教程之<b class='flag-5'>嵌入式</b>存儲(chǔ)技術(shù)的<b class='flag-5'>詳細(xì)資料</b>說(shuō)明

    嵌入式LINUX系統(tǒng)內(nèi)核內(nèi)核模塊調(diào)試

    嵌入式LINUX系統(tǒng)內(nèi)核內(nèi)核模塊調(diào)試(嵌入式開(kāi)發(fā)和硬件開(kāi)發(fā))-嵌入式
    發(fā)表于 07-30 13:55 ?10次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>LINUX</b>系統(tǒng)<b class='flag-5'>內(nèi)核</b>和<b class='flag-5'>內(nèi)核</b>模塊調(diào)試
    RM新时代网站-首页