亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 895 | 回復(fù): 0
打印 上一主題 下一主題

關(guān)于2.6.32內(nèi)核bus_id的問題 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-12-23 03:35 |只看該作者 |倒序瀏覽

這個問題困擾了我好久,對于內(nèi)核的不熟悉,一開始是出現(xiàn)了使用空指針的問題,部分錯誤提示如下

Unable to handle kernel NULL pointer dereference at virtual address 00000000    
pgd = c3ab4000                                                                  
[00000000] *pgd=33b11031, *pte=00000000, *ppte=00000000                         
Internal error: Oops: 17 [#1]                                                   
last sysfs file: /sys/devices/virtual/vc/vcsa4/dev                              
Modules linked in: usb_driver(+) usb_device usb_bus                             
CPU: 0    Not tainted  (2.6.32.2-FriendlyARM #1)                                
PC is at strcmp+0x10/0x40                                                       
LR is at usb_bus_match+0x2c/0x60 [usb_bus] 
后面我?guī)捉?jīng)周轉(zhuǎn)發(fā)現(xiàn)是原來match函數(shù)中設(shè)備名為空,這個我是照著其他人寫的博客上面弄的,只知道照著弄,其他的就不清楚了,后面上網(wǎng)搜的下面這篇文章,本想自己總結(jié)一下,不過發(fā)現(xiàn)他們總結(jié)的很好了,而且我完全保留原作者的文章,沒有改動。

原文地址  http://hi.baidu.com/tracyangrad/blog/item/88437f5b188d74302934f042.html

實驗環(huán)境:
linux2.6.32.2

    在做bus驅(qū)動實驗的時候,出現(xiàn)了一個問題:
提示bus_id找不到。于是到內(nèi)核源代碼找了一番,果然沒有看見。直接到device結(jié)構(gòu)體中看,找到的最像的也就
const char *init_name; /* initial name of the device */
想到這個也可以作為標(biāo)識,并且BUS_ID_SIZE也找不到,于是將strncpy(my_dev.init_name, "my_dev", BUS_ID_SIZE);注釋掉,直接在mydev中添

.init_name="my_dev"。
    但是在注冊驅(qū)動時又出現(xiàn)了段錯誤,根據(jù)console打印,知道在strncmp時,也就是總線在比較驅(qū)動和設(shè)備的名字的時候出問題了。
于是在比較函數(shù)里加入
printk("dev->init_name:%s\tdriver->name:%s\n", dev->init_name, driver->name);
想看看到底是怎么比較的。結(jié)果console上打印出來的是
dev->init_name:<NULL>   driver->name:my_dev (與下面亮點關(guān)聯(lián))
Unable to handle kernel NULL pointer dereference at virtual address 00000000
dev->init_name不存在?
    于是baidu了一下,發(fā)現(xiàn)了了下面網(wǎng)友的那段,我用對了init_name,卻沒直接在內(nèi)核里搜到dev_name(dev),于是又在內(nèi)核搜索一番。可以找到下面一段總線上的比較函數(shù):
static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
{
    struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
    int len = strlen(sub->wanted);

    if (0 == strncmp(dev_name(dev), sub->wanted, len))
    return 1;
    return 0;
}
它用的是dev_name(dev)而不是dev->init_name。還是在match函數(shù)里加入輸出語句,打印如下:
dev_name(dev):my_dev       driver->name:my_dev
成功了!

    那我們深究下,dev_name()是什么東東呢?
static inline const char *dev_name(const struct device *dev)
{
    return kobject_name(&dev->kobj);
}
├───static inline const char *kobject_name(const struct kobject *kobj)
    {
        return kobj->name;
    }
其實就是kobj->name;
dev_name(dev)怎么和dev->kobj-name聯(lián)系上的呢?找遍“可見”代碼找不到,猜測很可能是在device_register里面。
從源碼里順蔓摸瓜:

└─device_register
    └─device_add
        └─if (dev->init_name)
            {
                dev_set_name(dev, "%s", dev->init_name);
                dev->init_name = NULL; (亮點。
            }
                dev_set_name
                └─kobject_set_name_vargs (看到希望了!)
                    └─kobj->name= kvasprintf(GFP_KERNEL, fmt, vargs);(找到了,這個就是的了。 
找到了!就是在注冊設(shè)備的時候?qū)nit_name成員賦給了kobj->name,發(fā)現(xiàn)那個"亮點"沒,不是說說寫得有多漂亮(也不是說寫得不漂亮,糾結(jié)了。。),“亮

點”的意思是發(fā)現(xiàn)了新大陸那種感覺,越說越遠(yuǎn)。。看到前面我為了查錯誤從控制臺打出來的信息,dev->init_name:<NULL>   driver->name:my_dev中,dev-

>init_name等于NULL就是在這個dev->init_name = NULL;“亮點”的地方被置空了。這也是為什么用strncmp比較會出錯的原因。

要感謝下面這個網(wǎng)友,才想到要到內(nèi)核去搜一下dev_name。內(nèi)核版本號不同,必然有一些改動,當(dāng)我們發(fā)現(xiàn)不同后,要善于從中去找到不同,找到解決問題的方

法。

以下是轉(zhuǎn)載自
網(wǎng)友ying_seven的博客(看到其也是轉(zhuǎn)載的,但是并沒有注明來處)

--------------------------------------------------------------------------------------------------------------------------
按照國嵌的代碼(LDD那本書上的代碼也一樣):
struct device my_bus = {
    .bus_id = "my_bus0",
    .release = my_bus_release,
};

static int my_match(struct device *dev, struct device_driver *driver)
{
return !strncmp(dev->bus_id, driver->name, strlen(driver->name));
}

編譯時,提示 struct device 中沒有bus_id 這樣的錯誤。打開/lib/modules/2.6.35-28-generic/build/include/linux/device.h
找到struct device  的定義,里面沒有bus_id,但有:
const char *init_name; /* initial name of the device */                      這句。

可見,要把上面結(jié)構(gòu)中的.bus_id = "my_bus0",         改為       .init_name = "my_bus0",
同時上網(wǎng)搜到,return !strncmp(dev->bus_id, driver->name, strlen(driver->name));這句也要改成:
return !strncmp(dev_name(dev), driver->name, strlen(driver->name));

這樣編譯即可成功!

另注:
如果要設(shè)置設(shè)備的名字,也不再使用strncpy(my_dev.bus_id, "my_dev", BUS_ID_SIZE);     而改用:
dev_set_name(&dev, "name");

--------------------------------------------------------------------------------------------------------------------------

您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP