linux内核学习的屠龙刀、倚天剑(需要搭配硬件调试环境)
??? 好久沒來這里寫博客了。看到瀏覽量有所增加,十分開心。希望自己的點(diǎn)滴付出對他人能有所幫助。要是有不對的地方,也希望博友能給予點(diǎn)出糾正。
要是能獲得博友的轉(zhuǎn)發(fā),也希望能注明下原出處。打字不易,在此謝過啦!
??? 下面介紹下2個學(xué)習(xí)內(nèi)核時很有用的工具(方法):
1.函數(shù):dump_stack();??? -------------------屠龍刀
??? 內(nèi)核中,在調(diào)試過程中使用printk打印信息當(dāng)然是最直接的辦法。但當(dāng)我們在剛開始學(xué)習(xí)內(nèi)核時,要是一開始就定位到底層的某一個模塊(函數(shù)),往往想知道它(模塊、函數(shù))到底是怎么被頂層一步一步調(diào)用下來,并最終調(diào)用到的。這時,我們可以利用dump_stack來最根溯源。
??? 以下用例子做使用說明:
static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len,size_t *retlen, u_char *buf) {......printk(KERN_DEBUG "==============m25p80_read=======dump_stack s=====================\n");dump_stack();printk(KERN_DEBUG "==============m25p80_read=======dump_stack e=====================\n");...... } 這是在內(nèi)核代碼 ./drivers/mtd/devices/m25p80.c 中的函數(shù)m25p80_read(...)內(nèi)加入的。編譯該內(nèi)核,下載到你的板子上。上電。看看dump_stack()能打印出什么信息:
==============m25p80_read=======dump_stack s===================== CPU: 0 PID: 284 Comm: hexdump Not tainted 3.10.31-ltsi #269 Backtrace: [<c0012f24>] (dump_backtrace+0x0/0x110) from [<c001313c>] (show_stack+0x18/0x1c)r6:d6057810 r5:00000000 r4:d6057814 r3:00000000 [<c0013124>] (show_stack+0x0/0x1c) from [<c04968a4>] (dump_stack+0x24/0x28) [<c0496880>] (dump_stack+0x0/0x28) from [<c02b87a8>] (m25p80_read+0x34/0x148) [<c02b8774>] (m25p80_read+0x0/0x148) from [<c02b927c>] (spi_nor_read+0x60/0x7c)r9:00001000 r8:d6225ef0 r7:00000000 r6:d6057814 r5:00000000 r4:00700000 [<c02b921c>] (spi_nor_read+0x0/0x7c) from [<c02aa52c>] (part_read+0x70/0xa8)r7:d632b000 r6:d606c400 r5:00000000 r4:00000000 [<c02aa4bc>] (part_read+0x0/0xa8) from [<c02a7d9c>] (mtd_read+0xc0/0xec) [<c02a7cdc>] (mtd_read+0x0/0xec) from [<c02abcf4>] (mtdchar_read+0xe0/0x20c) [<c02abc14>] (mtdchar_read+0x0/0x20c) from [<c00c49e4>] (vfs_read+0xa0/0x14c) [<c00c4944>] (vfs_read+0x0/0x14c) from [<c00c5070>] (SyS_read+0x44/0x80)r8:00000000 r7:b6f26000 r6:d6145cc0 r5:00000000 r4:00000000 [<c00c502c>] (SyS_read+0x0/0x80) from [<c000f100>] (ret_fast_syscall+0x0/0x30)r9:d6224000 r8:c000f2a8 r7:00000003 r6:b6effcb8 r5:0000000a r4:00000000 ==============m25p80_read=======dump_stack e===================== 以上可以看到調(diào)用dump_stack的函數(shù)是m25p80_read,并且也給出了函數(shù)m25p80_read的所在地址,這樣:m25p80_read<--spi_nor_read<--part_read<--mtd_read<--mtdchar_read<--vfs_read(文件系統(tǒng)相關(guān)的)
我們就可以看到相關(guān)各個層的大體關(guān)系了:flash具體《==? spi-nor? 《==? mtd_part? 《==? mtdcore? 《==? mtdchar? 《== vfs。
對你去理解內(nèi)核的運(yùn)作是不是很有幫助 ^_^
以上是自底而上的方法,下面介紹一種自頂而下的方法:
2.運(yùn)用printk打印函數(shù)指針?????????? ------------------倚天劍
當(dāng)用函數(shù)指針調(diào)用一個函數(shù)時,我們在看代碼時,往往不知道它調(diào)用的是哪里(哪個函數(shù)),舉個例子,如下面的ret = master->transfer_one(master, msg->spi, xfer) :
static int spi_transfer_one_message(struct spi_master *master, struct spi_message *msg) {.............printk(KERN_DEBUG "====master->transfer_one=%p=================\n",master->transfer_one); //這里是額外加入的,查看master->transfer_one值ret = master->transfer_one(master, msg->spi, xfer);............. } 這時,我們在它的上面加上printk,把master->transfer_one值打印出來:編譯該內(nèi)核,下載到你的板子上。上電。log如下:
====master->transfer_one=c02be98c=================拿著? c02be98c? ,進(jìn)入編譯好的內(nèi)核源碼根目錄下,打開文件:System.map,查找c02be98c,可以看到:
c02be884 t rspi_common_transfer
c02be98c t qspi_transfer_one??? (這里)
c02bec30 t rspi_rz_transfer_one
這個函數(shù)正是 master->transfer_one 指向的函數(shù)。
接下來,不用我說了,你也會拿著這個函數(shù)名去內(nèi)核代碼里面查找了吧^_^
要是查找出一堆函數(shù),不知道用的是哪一個,那就接著用printk在各個函數(shù)里將該函數(shù)名的值(即它的地址)也打印出來,一對比不就清楚孰是孰非了嗎。
祝你內(nèi)核學(xué)習(xí)愉快^_^
總結(jié)
以上是生活随笔為你收集整理的linux内核学习的屠龙刀、倚天剑(需要搭配硬件调试环境)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: layui实现后台管理系统界面:对示例代
- 下一篇: 爱情大观