Android x86如何啟動到圖形介面 device/generic/common/init.sh 分析
# Android系統在啟動的過程中,最多可以出現三個畫面
- 第一個開機畫面是在核心啟動的過程中出現的,它是一個靜態的畫面。在預設情況下,這個畫面是不會出現的,除非我們在編譯核心的時候,
- 第二個開機畫面是在init程序啟動的過程中出現的,它也是一個靜態的畫面。
- 第三個開機畫面由應用程式bootanimation來負責顯示的。是在系統服務啟動的過程中出現的,它是一個動態的畫面。無論是哪一個畫面,它們都是在一個稱為幀緩衝區(frame buffer,簡稱fb)的硬體裝置上進行渲染的。
具體
- Android系統的SurfaceFlinger服務有兩種啟動方式:
1、 在SystemServer程序中以服務執行緒的方式提供服務;啟動Zygote=》呼叫SystemServer.java[frameworks\base\services\java\com\android\server]的main函式,=》呼叫本地函式init1()=》frameworks\base\services\java JNI的com_android_server_SystemServer.cpp裡面的android_server_SystemServer_init1函式=》然後呼叫System_init.cpp[frameworks\base\cmds\system_server\library]的system_init函式,通過獲取屬性欄位system_init.startsurfaceflinger,如果欄位值為1,那麼就在這裡啟動surfaceflinger。
2、啟動SurfaceFlinger獨立的程序通過服務。第二中方式是在Android啟動指令碼init.rc中配置SurfaceFlinger服務,通過init程序來啟動的。具體:有一個可執行檔案surfaceflinger,由framework/base/cmds/surfaceflinger編譯產生,目錄下的主要檔案main_surfaceflinger.cpp裡面就一個main函式:以上兩者都會呼叫SurfaceFlinger.cpp檔案的instantiate函式
-
啟動surfaceflinger後:1、 surfaceflinger建構函式呼叫readyToRun函式, 該函式定義了執行緒迴圈前需要初始化的內容。readyToRun()呼叫過程:(1)執行new DisplayHardware(this,dpy),通過DisplayHardware初始化Framebuffer、EGL並獲取OpenGL ES資訊。(2)建立共享的記憶體控制塊。(3)將EGL與當前螢幕繫結。(4)初始化共享記憶體控制塊。(5)初始化OpenGL ES。(6)顯示開機動畫。
-
相關的函式及位置:DisplayHardware.cpp[frameworks\base\libs\surfaceflinger\displayhardware]
gralloc.cpp [hardware\libhardware\modules\gralloc]
gralloc.h[hardware\libhardware\include\hardware]
/andriod-x86/device/generic/common/init.sh 的分析
- 和顯示相關的程式碼主要有兩部分
1、表示初始化
function do_init() { init_misc init_hal_audio init_hal_bluetooth init_hal_camera init_hal_gps init_hal_gralloc //初始化gralloc init_hal_hwcomposer init_hal_lights init_hal_power init_hal_sensors init_tscal init_ril chmod 640 /x86.prop post_init }
2、 幀緩衝的初始化
function init_hal_gralloc()
{
case "$(cat /proc/fb | head -1)" in // 幀緩衝裝置列表,包括數量和控制它的驅動
0*inteldrmfb|0*radeondrmfb|0*nouveaufb|0*svgadrmfb)
set_property ro.hardware.gralloc drm // ro.hardware.gralloc = drm . drm 是一個 Linux 核心的顯示系統驅動框架,模擬一個 fb device
set_drm_mode //設定解析度1366x768
;;
"")
init_uvesafb //根據情況設定為:1280x800,1600x900,1024x600,1024x768
;&
0*)
[ "$HWACCEL" = "1" ] || set_property debug.egl.hw 0 //debug.egl.hw = 0
;;
esac