精品日韩在线,日韩精品福利一区二区三区,日韩午夜黄色,国产日韩欧美高清免费

始創于2000年 股票代碼:831685
咨詢熱線:0371-60135900 注冊有禮 登錄
  • 掛牌上市企業
  • 60秒人工響應
  • 99.99%連通率
  • 7*24h人工
  • 故障100倍補償
您的位置: 網站首頁 > 幫助中心>文章內容

Android系統的開機畫面顯示過程分析

發布時間:  2012/8/30 17:29:52
好幾個月都沒有更新過博客了,從今天開始,老羅將嘗試對Android系統的UI實現作一個系統的分析,也算是落實之前所作出的承諾。提到Android系統的UI,我們最先接觸到的便是系統在啟動過程中所出現的畫面了。Android系統在啟動的過程中,最多可以出現三個畫面,每一個畫面都用來描述一個不同的啟動階段。本文將詳細分析這三個開機畫面的顯示過程,以便可以開啟我們對Android系統UI實現的分析之路。
        第一個開機畫面是在內核啟動的過程中出現的,它是一個靜態的畫面。第二個開機畫面是在init進程啟動的過程中出現的,它也是一個靜態的畫面。第三個開機畫面是在系統服務啟動的過程中出現的,它是一個動態的畫面。無論是哪一個畫面,它們都是在一個稱為幀緩沖區(frame buffer,簡稱fb)的硬件設備上進行渲染的。接下來,我們就分別分析這三個畫面是如何在fb上顯示的。
        1. 第一個開機畫面的顯示過程
        Android系統的第一個開機畫面其實是Linux內核的啟動畫面。在默認情況下,這個畫面是不會出現的,除非我們在編譯內核的時候,啟用以下兩個編譯選項:
        CONFIG_FRAMEBUFFER_CONSOLE
        CONFIG_LOGO
        第一個編譯選項表示內核支持幀緩沖區控制臺,它對應的配置菜單項為:Device Drivers ---> Graphics support ---> Console display driver support ---> Framebuffer Console support。第二個編譯選項表示內核在啟動的過程中,需要顯示LOGO,它對應的配置菜單項為:Device Drivers ---> Graphics support ---> Bootup logo。配置Android內核編譯選項可以參考在Ubuntu上下載、編譯和安裝Android最新內核源代碼(Linux Kernel)一文。
        幀緩沖區硬件設備在內核中有一個對應的驅動程序模塊fbmem,它實現在文件kernel/goldfish/drivers/video/fbmem.c中,它的初始化函數如下所示:
  1. /**  
  2.  *      fbmem_init - init frame buffer subsystem  
  3.  *  
  4.  *      Initialize the frame buffer subsystem.  
  5.  *  
  6.  *      NOTE: This function is _only_ to be called by drivers/char/mem.c.  
  7.  *  
  8.  */   
  9.    
  10. static int __init   
  11. fbmem_init(void)   
  12. {   
  13.         proc_create("fb", 0, NULL, &fb_proc_fops);   
  14.    
  15.         if (register_chrdev(FB_MAJOR,"fb",&fb_fops))   
  16.                 printk("unable to get major %d for fb devs\n", FB_MAJOR);   
  17.    
  18.         fb_class = class_create(THIS_MODULE, "graphics");   
  19.         if (IS_ERR(fb_class)) {   
  20.                 printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));   
  21.                 fb_class = NULL;   
  22.         }   
  23.         return 0;   
  24. }   
        這個函數首先調用函數proc_create在/proc目錄下創建了一個fb文件,接著又調用函數register_chrdev來注冊了一個名稱為fb的字符設備,最后調用函數class_create在/sys/class目錄下創建了一個graphics目錄,用來描述內核的圖形系統。

 

 
        模塊fbmem除了會執行上述初始化工作之外,還會導出一個函數register_framebuffer:
  1. EXPORT_SYMBOL(register_framebuffer);   

 

        這個函數在內核的啟動過程會被調用,以便用來執行注冊幀緩沖區硬件設備的操作,它的實現如下所示:
  1. /**  
  2.  *      register_framebuffer - registers a frame buffer device  
  3.  *      @fb_info: frame buffer info structure  
  4.  *  
  5.  *      Registers a frame buffer device @fb_info.  
  6.  *  
  7.  *      Returns negative errno on error, or zero for success.  
  8.  *  
  9.  */   
  10.    
  11. int   
  12. register_framebuffer(struct fb_info *fb_info)   
  13. {   
  14.         int i;   
  15.         struct fb_event event;   
  16.         ......   
  17.    
  18.         if (num_registered_fb == FB_MAX)   
  19.                 return -ENXIO;   
  20.    
  21.         ......   
  22.    
  23.         num_registered_fb++;   
  24.         for (i = 0 ; i < FB_MAX; i++)   
  25.                 if (!registered_fb[i])   
  26.                         break;   
  27.         fb_info->node = i;   
  28.         mutex_init(&fb_info->lock);   
  29.         fb_info->dev = device_create(fb_class, fb_info->device,   
  30.                                      MKDEV(FB_MAJOR, i), NULL"fb%d", i);   
  31.         if (IS_ERR(fb_info->dev)) {   
  32.                 /* Not fatal */   
  33.                 printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));   
  34.                 fb_info->dev = NULL;   
  35.         } else   
  36.                 fb_init_device(fb_info);   
  37.    
  38.         ......   
  39.    
  40.         registered_fb[i] = fb_info;   
  41.    
  42.         event.info = fb_info;   
  43.         fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);   
  44.         return 0;   
  45. }   
        由于系統中可能會存在多個幀緩沖區硬件設備,因此,fbmem模塊使用一個數組registered_fb保存所有已經注冊了的幀緩沖區硬件設備,其中,每一個幀緩沖區硬件都是使用一個結構體fb_info來描述的。

 

 
        我們知道,在Linux內核中,每一個硬件設備都有一個主設備號和一個從設備號,它們用來唯一地標識一個硬件設備。對于幀緩沖區硬件設備來說,它們的主設備號定義為FB_MAJOR(29),而從設備號則與注冊的順序有關,它們的值依次等于0,1,2等。
        每一個被注冊的幀緩沖區硬件設備在/dev/graphics目錄下都有一個對應的設備文件fb<minor>,其中,<minor>表示一個從設備號。例如,第一個被注冊的幀緩沖區硬件設備在/dev/graphics目錄下都有一個對應的設備文件fb0。用戶空間的應用程序通過這個設備文件就可以操作幀緩沖區硬件設備了,即將要顯示的畫面渲染到幀緩沖區硬件設備上去。
        這個函數最后會通過調用函數fb_notifier_call_chain來通知幀緩沖區控制臺,有一個新的幀緩沖區設備被注冊到內核中來了。
        幀緩沖區控制臺在內核中對應的驅動程序模塊為fbcon,它實現在文件kernel/goldfish/drivers/video/console/fbcon.c中,它的初始化函數如下所示:
  1. static struct notifier_block fbcon_event_notifier = {   
  2.         .notifier_call  = fbcon_event_notify,   
  3. };   
  4.    
  5. ......   
  6.    
  7. static int __init fb_console_init(void)   
  8. {   
  9.         int i;   
  10.    
  11.         acquire_console_sem();   
  12.         fb_register_client(&fbcon_event_notifier);   
  13.         fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,   
  14.                                      "fbcon");   
  15.    
  16.         if (IS_ERR(fbcon_device)) {   
  17.                 printk(KERN_WARNING "Unable to create device "   
  18.                        "for fbcon; errno = %ld\n",   
  19.                        PTR_ERR(fbcon_device));   
  20.                 fbcon_device = NULL;   
  21.         } else   
  22.                 fbcon_init_device();   
  23.    
  24.         for (i = 0; i < MAX_NR_CONSOLES; i++)   
  25.                 con2fb_map[i] = -1;   
  26.    
  27.         release_console_sem();   
  28.         fbcon_start();   
  29.         return 0;   
  30. }   

 

        這個函數除了會調用函數device_create來創建一個類別為graphics的設備fbcon之外,還會調用函數fb_register_client來監聽幀緩沖區硬件設備的注冊事件,這是由函數fbcon_event_notify來實現的,如下所示:
  1. static int fbcon_event_notify(struct notifier_block *self,   
  2.                               unsigned long action, void *data)   
  3. {   
  4.         struct fb_event *event = data;   
  5.         struct fb_info *info = event->info;   
  6.         ......   
  7.         int ret = 0;   
  8.    
  9.         ......   
  10.    
  11.         switch(action) {   
  12.         ......   
  13.         case FB_EVENT_FB_REGISTERED:   
  14.                 ret = fbcon_fb_registered(info);   
  15.                 break;   
  16.         ......   
  17.    
  18.         }   
  19.    
  20. done:   
  21.         return ret;   
  22. }   
     幀緩沖區硬件設備的注冊事件最終是由函數fbcon_fb_registered來處理的,它的實現如下所示:
  1. static int fbcon_fb_registered(struct fb_info *info)   
  2. {   
  3.         int ret = 0, i, idx = info->node;   
  4.    
  5.         fbcon_select_primary(info);   
  6.    
  7.         if (info_idx == -1) {   
  8.                 for (i = first_fb_vc; i <= last_fb_vc; i++) {   
  9.                         if (con2fb_map_boot[i] == idx) {   
  10.                                 info_idx = idx;   
  11.                                 break;   
  12.                         }   
  13.                 }   
  14.    
  15.                 if (info_idx != -1)   
  16.                         ret = fbcon_takeover(1);   
  17.         } else {   
  18.                 for (i = first_fb_vc; i <= last_fb_vc; i++) {   
  19.                         if (con2fb_map_boot[i] == idx)   
  20.                                 set_con2fb_map(i, idx, 0);   
  21.                 }   
  22.         }   
  23.    
  24.         return ret;   
  25. }   
        函數fbcon_select_primary用來檢查當前注冊的幀緩沖區硬件設備是否是一個主幀緩沖區硬件設備。如果是的話,那么就將它的信息記錄下來。這個函數只有當指定了CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY編譯選項時才有效,否則的話,它是一個空函數。

 

 
        在Linux內核中,每一個控制臺和每一個幀緩沖區硬件設備都有一個從0開始的編號,它們的初始對應關系保存在全局數組con2fb_map_boot中。控制臺和幀緩沖區硬件設備的初始對應關系是可以通過設置內核啟動參數來初始化的。在模塊fbcon中,還有另外一個全局數組con2fb_map,也是用來映射控制臺和幀緩沖區硬件設備的對應關系,不過它映射的是控制臺和幀緩沖區硬件設備的實際對應關系。
        全局變量first_fb_vc和last_fb_vc是全局數組con2fb_map_boot和con2fb_map的索引值,用來指定系統當前可用的控制臺編號范圍,它們也是可以通過設置內核啟動參數來初始化的。全局變量first_fb_vc的默認值等于0,而全局變量last_fb_vc的默認值等于MAX_NR_CONSOLES - 1。
        全局變量info_idx表示系統當前所使用的幀緩沖區硬件的編號。如果它的值等于-1,那么就說明系統當前還沒有設置好當前所使用的幀緩沖區硬件設備。在這種情況下,函數fbcon_fb_registered就會在全局數組con2fb_map_boot中檢查是否存在一個控制臺編號與當前所注冊的幀緩沖區硬件設備的編號idx對應。如果存在的話,那么就會將當前所注冊的幀緩沖區硬件設備編號idx保存在全局變量info_idx中。接下來還會調用函數fbcon_takeover來初始化系統所使用的控制臺。在調用函數fbcon_takeover的時候,傳進去的參數為1,表示要顯示第一個開機畫面。
        如果全局變量info_idx的值不等于-1,那么函數fbcon_fb_registered同樣會在全局數組con2fb_map_boot中檢查是否存在一個控制臺編號與當前所注冊的幀緩沖區硬件設備的編號idx對應。如果存在的話,那么就會調用函數set_con2fb_map來調整當前所注冊的幀緩沖區硬件設備與控制臺的映射關系,即調整數組con2fb_map_boot和con2fb_map的值。
        為了簡單起見,我們假設系統只有一個幀緩沖區硬件設備,這樣當它被注冊的時候,全局變量info_idx的值就會等于-1。當函數fbcon_fb_registered在全局數組con2fb_map_boot中發現有一個控制臺的編號與這個幀緩沖區硬件設備的編號idx對應時,接下來就會調用函數fbcon_takeover來設置系統所使用的控制臺。
        函數fbcon_takeover的實現如下所示:
  1. static int fbcon_takeover(int show_logo)   
  2. {   
  3.         int err, i;   
  4.    
  5.         if (!num_registered_fb)   
  6.                 return -ENODEV;   
  7.    
  8.         if (!show_logo)   
  9.                 logo_shown = FBCON_LOGO_DONTSHOW;   
  10.    
  11.         for (i = first_fb_vc; i <= last_fb_vc; i++)   
  12.                 con2fb_map[i] = info_idx;   
  13.    
  14.         err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,   
  15.                                 fbcon_is_default);   
  16.    
  17.         if (err) {   
  18.                 for (i = first_fb_vc; i <= last_fb_vc; i++) {   
  19.                         con2fb_map[i] = -1;   
  20.                 }   
  21.                 info_idx = -1;   
  22.         }   
  23.    
  24.         return err;   
  25. }   

 

        全局變量logo_shown的初始值為FBCON_LOGO_CANSHOW,表示可以顯示第一個開機畫面。但是當參數show_logo的值等于0的時候,全局變量logo_shown的值會被重新設置為FBCON_LOGO_DONTSHOW,表示不可以顯示第一個開機畫面。

 

 
        中間的for循環將當前可用的控制臺的編號都映射到當前正在注冊的幀緩沖區硬件設備的編號info_idx中去,表示當前可用的控制臺與緩沖區硬件設備的實際映射關系。
        函數take_over_console用來初始化系統當前所使用的控制臺。如果它的返回值不等于0,那么就表示初始化失敗。在這種情況下,最后的for循環就會將全局數組con2fb_map的各個元素的值設置為-1,表示系統當前可用的控制臺還沒有映射到實際的幀緩沖區硬件設備中去。這時候全局變量info_idx的值也會被重新設置為-1。
       調用函數take_over_console來初始化系統當前所使用的控制臺,實際上就是向系統注冊一系列回調函數,以便系統可以通過這些回調函數來操作當前所使用的控制臺。這些回調函數使用結構體consw來描述。這里所注冊的結構體consw是由全局變量fb_con來指定的,它的定義如下所示:
  1. /*  
  2.  *  The console `switch' structure for the frame buffer based console  
  3.  */   
  4.    
  5. static const struct consw fb_con = {   
  6.         .owner                  = THIS_MODULE,   
  7.         .con_startup            = fbcon_startup,   
  8.         .con_init               = fbcon_init,   
  9.         .con_deinit             = fbcon_deinit,   
  10.         .con_clear              = fbcon_clear,   
  11.         .con_putc               = fbcon_putc,   
  12.         .con_putcs              = fbcon_putcs,   
  13.         .con_cursor             = fbcon_cursor,   
  14.         .con_scroll             = fbcon_scroll,   
  15.         .con_bmove              = fbcon_bmove,   
  16.         .con_switch             = fbcon_switch,   
  17.         .con_blank              = fbcon_blank,   
  18.         .con_font_set           = fbcon_set_font,   
  19.         .con_font_get           = fbcon_get_font,   
  20.         .con_font_default       = fbcon_set_def_font,   
  21.         .con_font_copy          = fbcon_copy_font,   
  22.         .con_set_palette        = fbcon_set_palette,   
  23.         .con_scrolldelta        = fbcon_scrolldelta,   
  24.         .con_set_origin         = fbcon_set_origin,   
  25.         .con_invert_region      = fbcon_invert_region,   
  26.         .con_screen_pos         = fbcon_screen_pos,   
  27.         .con_getxy              = fbcon_getxy,   
  28.         .con_resize             = fbcon_resize,   
  29. };   

本文出自:億恩科技【www.zuiquanben.com】

服務器租用/服務器托管中國五強!虛擬主機域名注冊頂級提供商!15年品質保障!--億恩科技[ENKJ.COM]

  • 您可能在找
  • 億恩北京公司:
  • 經營性ICP/ISP證:京B2-20150015
  • 億恩鄭州公司:
  • 經營性ICP/ISP/IDC證:豫B1-20183354
  • 億恩南昌公司:
  • 經營性ICP/ISP證:贛B2-20080012
  • 服務器/云主機 24小時售后服務電話:0371-60135900
  • 虛擬主機/智能建站 24小時售后服務電話:0371-60135900
  • 網絡版權侵權舉報電話:0371-60135995
  • 警情提示:注意防范電信網絡詐騙
  • 專注服務器托管17年
    掃掃關注-微信公眾號
    0371-60135900
    Copyright© 1999-2026 ENKJ All Rights Reserved 地址:鄭州市高新區翠竹街1號總部企業基地億恩大廈  法律顧問:河南亞太人律師事務所郝建鋒、杜慧月律師  B1-20183354   京公網安備41019702002023號 
      0
     
     
     
     

    0371-60135900
    7*24小時客服服務熱線

     
     
    精品日韩在线,日韩精品福利一区二区三区,日韩午夜黄色,国产日韩欧美高清免费
    久久免费高清| 精品视频91| 国产主播一区| 日韩和的一区二在线| 亚洲一级少妇| 欧美日中文字幕| 免费观看不卡av| 一区免费在线| 久久国产精品久久久久久电车 | 国产经典一区| 免费看一区二区三区| 欧美日韩一区二区三区不卡视频 | 久久免费国产| 欧美在线资源| 免费在线欧美视频| 日韩中文字幕在线一区| 69堂精品视频在线播放| 91福利精品在线观看| 国产精品久久久久久久久免费高清| 国产精品大片| sm久久捆绑调教精品一区| 成人啊v在线| 国产亚洲精品久久久久婷婷瑜伽| 日韩专区欧美专区| 奇米狠狠一区二区三区| 老牛国内精品亚洲成av人片| 99久久视频| 一区二区国产精品| 国产精品夜夜夜| 日本免费一区二区三区四区| 一本色道久久精品| 日韩av一区二区三区四区| 日韩av在线免费观看不卡| 成人在线免费观看网站| 美女网站一区| 欧美一区不卡| 日韩免费福利视频| 免费国产自线拍一欧美视频| 国产日韩在线观看视频| 夜鲁夜鲁夜鲁视频在线播放| 老司机精品久久| 国产精品天天看天天狠| 日韩精品免费一区二区三区| 综合一区二区三区| 国产精品二区不卡| 一区二区日韩免费看| 成人在线观看免费视频| 九九久久婷婷| 国产精品高潮呻吟久久久久| 激情欧美丁香| 国产精品免费大片| 免费久久精品| 欧美激情一区| 亚洲一区欧美激情| 国产一区三区在线播放| 久久亚洲国产精品一区二区| 麻豆91小视频| 在线视频亚洲欧美中文| 国产成人a视频高清在线观看| 亚洲综合电影一区二区三区| 国产精品成人国产| 国产精品日韩久久久| 免费在线亚洲欧美| 99视频在线精品国自产拍免费观看| 国产乱码精品| 国产精品视区| 一本大道色婷婷在线| 日韩av午夜在线观看| 欧美成人高清| 久久久亚洲欧洲日产| 爽好多水快深点欧美视频| 国产videos久久| 亚洲精品黄色| 亚洲黄页一区| av综合电影网站| 国产乱码精品一区二区亚洲| 亚洲一级在线| 国产福利片在线观看| 日韩中文一区二区| 2023国产精品久久久精品双| 国产成人精品亚洲线观看| 日韩区欧美区| 午夜在线一区二区| 久久精选视频| 国产传媒在线观看| 国产精品tv| 亚洲精品影院在线观看| 久久国产欧美| а√天堂8资源中文在线| 欧美日一区二区在线观看| 亚洲专区在线| 免费观看不卡av| 成人在线免费观看91| 日韩精品乱码av一区二区| 影音国产精品| 欧美日韩中文一区二区| 国产欧洲在线| 精品网站999| 国产精品玖玖玖在线资源| 青草av.久久免费一区| 首页欧美精品中文字幕| 亚洲午夜黄色| 日韩精品欧美| 久久久久久婷| 精品国产鲁一鲁****| 国产亚洲第一伦理第一区| 亚洲日产国产精品| 在线综合视频| 亚洲先锋成人| 亚洲一级二级| 精品日韩毛片| 激情久久五月| 亚洲欧美伊人| 五月天激情综合网| 亚洲天堂黄色| 欧洲毛片在线视频免费观看| 久久一区二区三区电影| 欧美片第1页| 日韩一区三区| 99久久亚洲精品蜜臀| 99精品国产一区二区三区| 久久三级福利| 久久天堂精品| 91精品二区| 欧美精选一区二区三区| 午夜电影亚洲| 男人的天堂亚洲一区| 免费不卡在线视频| 综合国产在线| 青草国产精品久久久久久| 国产午夜精品一区在线观看| 国产欧美午夜| 麻豆精品久久久| 精品国产三区在线| 欧美一级鲁丝片| 久久影视一区| 免费精品国产| 国产精品毛片| 蜜臀久久99精品久久久久宅男 | 日韩在线麻豆| 日本欧美大码aⅴ在线播放| 日韩激情啪啪| 久久不卡日韩美女| 六月婷婷综合| 欧美日韩国产传媒| 石原莉奈一区二区三区在线观看| 五月亚洲婷婷 | 日本久久成人网| 国产二区精品| 中文字幕日韩欧美精品高清在线| 日韩精品第一| 久久精品亚洲| 91精品国产成人观看| 亚洲色诱最新| 欧美日本久久| 黄毛片在线观看| 国精品一区二区| 在线视频亚洲欧美中文| 国产乱码精品一区二区三区四区| 日韩成人精品一区二区| 婷婷中文字幕一区| 日韩不卡一区二区三区| 国产一区二区三区不卡av| 亚洲国产影院| 日本精品另类| 水蜜桃精品av一区二区| 日韩视频不卡| 欧美日韩视频免费看| 天堂av在线| 亚洲香蕉久久| 欧美经典一区| 久久久久久久久丰满| 免费的成人av| 精品视频一区二区三区在线观看 | 免费成人在线视频观看| 国产毛片精品| 久久香蕉国产| 欧美影院精品| 欧美精品高清| 亚洲v天堂v手机在线| 国产在线一区不卡| 国产一区视频在线观看免费| 日韩高清电影免费| 国产欧洲在线| 婷婷亚洲成人| 亚洲天堂资源| 日本va欧美va欧美va精品| 午夜欧美巨大性欧美巨大| 亚洲91在线| 国产 日韩 欧美一区| 亚洲精品免费观看| 日韩免费小视频| 日本在线视频一区二区| 青青久久av| 国产精品调教视频| 亚洲免费高清| 加勒比视频一区| 中文字幕中文字幕精品| 久久精品高清| 欧美激情日韩|