在使用linux的ramoops驅動模組時,在編譯完載入時,會發現驅動載入不成功。明明直接使用的核心代碼,為什麼會出現這樣的情況呢。
首先看一下ramoops的初始化代碼:
180 static int __init ramoops_init(void)181 {182 return platform_driver_probe(&ramoops_driver, ramoops_probe);183 }184185 static void __exit ramoops_exit(void)186 {187 platform_driver_unregister(&ramoops_driver);188 }189190 module_init(ramoops_init);180行開始的ramoops_init函數是不是有點奇怪。直接就調用了probe函數。標準的platform驅動程式的流程是這樣的:
怎麼看起來好像缺少platform_device的定義和註冊,到底是不是因為這個呢。我們來看一下Document/ramoops.txt的相關說明:
38 2. Setting the parameters 39 40 Setting the ramoops parameters can be done in 2 different manners: 41 1. Use the module parameters (which have the names of the variables described 42 as before). 43 For quick debugging, you can also reserve parts of memory during boot 44 and then use the reserved memory for ramoops. For example, assuming a machine 45 with > 128 MB of memory, the following kernel command line will tell the 46 kernel to use only the first 128 MB of memory, and place ECC-protected ramoops 47 region at 128 MB boundary: 48 "mem=128M ramoops.mem_address=0x8000000 ramoops.ecc=1" 49 2. Use a platform device and set the platform data. The parameters can then 50 be set through that platform data. An example of doing that is: 51 52 #include <linux/pstore_ram.h> 53 [...] 54 55 static struct ramoops_platform_data ramoops_data = { 56 .mem_size = <...>, 57 .mem_address = <...>, 58 .record_size = <...>, 59 .dump_oops = <...>, 60 .ecc = <...>, 61 }; 62 63 static struct platform_device ramoops_dev = { 64 .name = "ramoops", 65 .dev = { 66 .platform_data = &ramoops_data, 67 }, 68 }; 69 70 [... inside a function ...] 71 int ret; 72 73 ret = platform_device_register(&ramoops_dev); 74 if (ret) { 75 printk(KERN_ERR "unable to register platform device\n"); 76 return ret; 77 }原來真的是因為少了platform_device的緣故,趕緊加上。
追加platform_device的操作比較簡單,按照Document上的來就可以了。有一點需要主要,就是ramoops_dev的name這個成員,這個成員的值必須是"ramoops"。為什麼呢。這是因為platform匯流排在調用自身的match函數,將driver與device進行匹配時,就是判斷兩個結構體中的name成員是否相等。而platform_driver結構體中的name成員的值,從下面的代碼中可以看出,已經寫定為"ramoops",如果platform_device中的值不同,則驅動同樣無法載入。
172 static struct platform_driver ramoops_driver = {173 .remove = __exit_p(ramoops_remove),174 .driver = {175 .name = "ramoops",176 .owner = THIS_MODULE,177 },178 };
有沒有想過,為什麼沒註冊platform_device,ramoops的驅動代碼就不能載入呢。再回過頭來看一下ramoops的初始化代碼:
180 static int __init ramoops_init(void)181 {182 return platform_driver_probe(&ramoops_driver, ramoops_probe);183 }之前說過,一般init函數中會調用register函數,還說這是標準流程了呢。看一下platform_driver_probe函數的定義:
477 int __init_or_module platform_driver_probe(struct platform_driver *drv, 478 int (*probe)(struct platform_device *)) 479 { 480 int retval, code; 481 482 /* make sure driver won't have bind/unbind attributes */ 483 drv->driver.suppress_bind_attrs = true; 484 485 /* temporary section violation during probe() */ 486 drv->probe = probe; 487 retval = code = platform_driver_register(drv); 488。。。}看到platform_driver_register函數沒。原來是將register函數封裝了一層。看到這裡應該明白了,為什麼沒有註冊platform_device,驅動會載入失敗了吧。
什麼,還是不知道。那你一定沒看我之前寫的關於linux裝置驅動程式的註冊流程,如果看完了還沒明白,那就是我的問題。連結在此:http://blog.csdn.net/tuzhutuzhu/article/details/34847619