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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DRM驱动代码分析:开机过程中显示驱动做了什么

發布時間:2024/1/18 编程问答 92 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DRM驱动代码分析:开机过程中显示驱动做了什么 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:

有些信息是在網上查資料后總結的,沒有去追代碼驗證。如果有說得不對的地方,歡迎提出指正。感謝!

手機啟動的大致流程


1.長按開機鍵



2.執行存儲在ROM里(應該是某一個固定地址或是預定義的地址)的Primary Bootloader,會做以下事情:
初始化RAM
將secondary stage bootloader拷貝到內存



3.secondary stage bootloader會做以下事情
準備好device tree,告訴內核dtb的首地址
初始化一些硬件設備,比如顯示
啟動內核,傳遞參數

與顯示相關的部分:dpu、dsi、dphy、屏幕上電,讀屏幕ID來識別屏幕,屏幕初始化,顯示開機logo



4.Kernel
啟動init進程
掛載根文件系統(init進程內核態)
解析cmdline參數
創建各種服務進程(init進程用戶態)

bootloader階段,顯示做了什么

目前在網上沒有找到高通最新的uefi源碼,先空著吧。

內核啟動時,顯示驅動做了什么

module_init

vendor\qcom\opensource\display-drivers\msm\msm_drv.c module_init(msm_drm_register);

module_init是一個宏定義:#define module_init(x) __initcall(x);

將msm_drm_register函數放在.initcall6.init段中,在內核啟動過程中通過start_kernel -> reset_init -> kernel_init->do_initcalls調用通過module_init注冊的msm_drm_register函數。[10][11]

那register函數做了什么?

vendor\qcom\opensource\display-drivers\msm\msm_drv.c static int __init msm_drm_register(void) {...platform_driver_register(&msm_platform_driver);dsi_display_register();... } vendor\qcom\opensource\display-drivers\msm\dsi\dsi_display.c void __init dsi_display_register(void) {...dsi_phy_drv_register();dsi_ctrl_drv_register();dsi_display_parse_boot_display_selection();-------------2platform_driver_register(&dsi_display_driver); }

調用platform_driver_register函數注冊以下platform driver:
msm_platform_driver、dsi_phy_platform_driver、dsi_ctrl_driver、dsi_display_driver

從名字上可以看出來,dsi_phy_platform_driver對于dphy模塊,dsi_ctrl_driver對應dsi模塊,其它兩個呢?


2.解析屏幕名字。具體分析參考DRM驅動代碼分析:uboot和kernel之間屏幕是如何匹配的

tips:
宏定義__init,用于告訴編譯器相關函數或變量僅用于初始化。
編譯器將標__init的所有代碼存在特殊的內存段中,初始化結束后就釋放這段內存。
來源:百度百科-__init

qcom DRM driver里的platform driver:

unisoc DRM driver里的platform driver:

static const struct of_device_id dsi_display_dt_match[] = {{.compatible = "qcom,dsi-display"},{} };

不管是高通還是展訊,驅動里都定義了of_match_table的compatible變量,有的還定義了data。接下來看看compatible的作用。

drivers\base\platform.c static int platform_match(struct device *dev, struct device_driver *drv) {.../* Attempt an OF style match first */if (of_driver_match_device(dev, drv))------------------------1return 1;/* Then try to match against the id table */if (pdrv->id_table)return platform_match_id(pdrv->id_table, pdev) != NULL;-----2/* fall-back to driver name match */return (strcmp(pdev->name, drv->name) == 0);------------------3 }

總線上的device和driver進行匹配的時候會調用bus的match函數,對于platform bus而言就是platform_match。
來源:Linux設備模型(8)_platform設備

1.將驅動of_match_table變量中的compatible、type、name和dts節點對應的值進行比較,來判斷設備和驅動是否匹配。

2.目前看起來顯示驅動的這幾個模塊都沒有定義id_table,暫時不管。

3.比較platform driver的name值。

module_platform_driver

除了module_init();也可以用module_platform_driver();

include\linux\platform_device.h /* module_platform_driver() - Helper macro for drivers that don't do* anything special in module init/exit. This eliminates a lot of* boilerplate. Each module may only use this macro once, and* calling it replaces module_init() and module_exit()*/ #define module_platform_driver(__platform_driver) \module_driver(__platform_driver, platform_driver_register, \platform_driver_unregister)include\linux\device\driver.h #define module_driver(__driver, __register, __unregister, ...) \ static int __init __driver##_init(void) \ { \return __register(&(__driver) , ##__VA_ARGS__); \ } \ module_init(__driver##_init); \ static void __exit __driver##_exit(void) \ { \__unregister(&(__driver) , ##__VA_ARGS__); \ } \ module_exit(__driver##_exit);

如注釋所說,如果不需要在module init和exit函數里完成特定的操作,則可以使用module_platform_driver()。

LK、UEFI、uboot、bootloader是什么?
LK、UEFI、uboot都屬于bootloader。

設備驅動prove的時機有如下幾種(分為自動觸發和手動觸發):
將struct device類型的變量注冊到內核中時自動觸發(device_register,device_add,device_create_vargs,device_create)
將struct device_driver類型的變量注冊到內核中時自動觸發(driver_register)
手動查找同一bus下的所有device_driver,如果有和指定device同名的driver,執行probe操作(device_attach)
手動查找同一bus下的所有device,如果有和指定driver同名的device,執行probe操作(driver_attach)
自行調用driver的probe接口,并在該接口中將該driver綁定到某個device結構中----即設置dev->driver(device_bind_driver)
來源:Linux設備模型(5)_device和device driver

static int msm_pdev_probe(struct platform_device *pdev)|add_display_components(&pdev->dev, &match);|component_master_add_with_match(&pdev->dev, &msm_drm_ops, match);static const struct component_master_ops msm_drm_ops = {.bind = msm_drm_bind,.unbind = msm_drm_unbind, }; static int add_display_components(struct device *dev,struct component_match **matchptr) {struct device *mdp_dev = NULL;struct device_node *node;int ret;if (of_device_is_compatible(dev->of_node, "qcom,sde-kms")) {struct device_node *np = dev->of_node;unsigned int i;for (i = 0; ; i++) {node = of_parse_phandle(np, "connectors", i);if (!node)break;component_match_add(dev, matchptr, compare_of, node);}return 0;}... } &soc {mdss_mdp: qcom,mdss_mdp@ae00000 {compatible = "qcom,sde-kms";...}; };&mdss_mdp {connectors = <&smmu_sde_unsec &smmu_sde_sec &sde_dp &sde_wb &sde_dsi &sde_dsi1 &sde_rscc>; };

mdss_mdp是master,相關聯的設備有smmu_sde_unsec、smmu_sde_sec、sde_dp、sde_wb、sde_dsi、sde_dsi1、sde_rscc。 如果某些設備不支持,則需要刪掉。
todo:為什么是這些設備作為component?

int dsi_display_dev_probe(struct platform_device *pdev)|rc = dsi_display_init(display);|rc = component_add(&pdev->dev, &dsi_display_comp_ops);static const struct component_ops dsi_display_comp_ops = {.bind = dsi_display_bind,.unbind = dsi_display_unbind, };sde_dsi: qcom,dsi-display-primary {compatible = "qcom,dsi-display";... };

調用component_add注冊sde_dsi設備。

static int msm_drm_bind(struct device *dev)|msm_drm_component_init(dev);|msm_component_bind_all(dev, ddev);|component_bind_all(dev, drm_dev);

在master的bind函數msm_drm_bind中調用component_bind_all,從而調用各個子設備的bind函數。[14]

縮寫:
PBL:Primary Bootloader
UEFI:Unified extensible firmware interface統一的可擴展固件接口
MDP:mobile display processor

參考資料
[1]CSDN 木希 《安卓開機流程》
[2]《高通平臺UEFI有關介紹》
[3]《聊一聊汽車控制器的啟動——BOOT》
[4]CSDN 沒有皮卡丘的小志《 Android開機啟動流程簡析》
[5]CSDN 河馬虛擬化 《Linux啟動過程 - 從MBR到第一個應用》
[6]CSDN 花生醬拌面 《uboot移植——啟動內核》
[7]wowotech linuxer 《ARM64的啟動過程之(一):內核第一個腳印》
[8]Documentation/arm64/booting.txt
[9]CSDN 天糊土 《init進程的詳解》
[10]CSDN Richard_LiuJH《linux驅動 之 module_init解析 (上)》
[11]CSDN Richard_LiuJH《linux驅動 之 module_init解析 (下)》
[12]Linux設備模型(8)_platform設備
[13]Linux設備模型(5)_device和device driver
[14]linux kernel component框架分析

總結

以上是生活随笔為你收集整理的DRM驱动代码分析:开机过程中显示驱动做了什么的全部內容,希望文章能夠幫你解決所遇到的問題。

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