日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux内核学习的屠龙刀、倚天剑(需要搭配硬件调试环境)

發布時間:2023/12/20 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux内核学习的屠龙刀、倚天剑(需要搭配硬件调试环境) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??? 好久沒來這里寫博客了。看到瀏覽量有所增加,十分開心。希望自己的點滴付出對他人能有所幫助。要是有不對的地方,也希望博友能給予點出糾正。

要是能獲得博友的轉發,也希望能注明下原出處。打字不易,在此謝過啦!

??? 下面介紹下2個學習內核時很有用的工具(方法):

1.函數:dump_stack();??? -------------------屠龍刀

??? 內核中,在調試過程中使用printk打印信息當然是最直接的辦法。但當我們在剛開始學習內核時,要是一開始就定位到底層的某一個模塊(函數),往往想知道它(模塊、函數)到底是怎么被頂層一步一步調用下來,并最終調用到的。這時,我們可以利用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");...... } 這是在內核代碼 ./drivers/mtd/devices/m25p80.c 中的函數m25p80_read(...)內加入的。編譯該內核,下載到你的板子上。上電。

看看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===================== 以上可以看到調用dump_stack的函數是m25p80_read,并且也給出了函數m25p80_read的所在地址,

這樣:m25p80_read<--spi_nor_read<--part_read<--mtd_read<--mtdchar_read<--vfs_read(文件系統相關的)

我們就可以看到相關各個層的大體關系了:flash具體《==? spi-nor? 《==? mtd_part? 《==? mtdcore? 《==? mtdchar? 《== vfs。

對你去理解內核的運作是不是很有幫助 ^_^


以上是自底而上的方法,下面介紹一種自頂而下的方法:



2.運用printk打印函數指針?????????? ------------------倚天劍

當用函數指針調用一個函數時,我們在看代碼時,往往不知道它調用的是哪里(哪個函數),舉個例子,如下面的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值打印出來:

編譯該內核,下載到你的板子上。上電。log如下:

====master->transfer_one=c02be98c=================
拿著? c02be98c? ,進入編譯好的內核源碼根目錄下,打開文件:System.map,查找c02be98c,可以看到:

c02be884 t rspi_common_transfer
c02be98c t qspi_transfer_one??? (這里)
c02bec30 t rspi_rz_transfer_one


這個函數正是 master->transfer_one 指向的函數。

接下來,不用我說了,你也會拿著這個函數名去內核代碼里面查找了吧^_^

要是查找出一堆函數,不知道用的是哪一個,那就接著用printk在各個函數里將該函數名的值(即它的地址)也打印出來,一對比不就清楚孰是孰非了嗎。

祝你內核學習愉快^_^



總結

以上是生活随笔為你收集整理的linux内核学习的屠龙刀、倚天剑(需要搭配硬件调试环境)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。