�����ڵ�λ�ã���ҳ > ���� > Android���� > ����
Androidϵͳ�Ŀ���������ʾ���̷�����һ��
http://www.drovik.com/      2013-1-29 21:51:37      ��Դ�����޵�Android֮��      �����
 �ü����¶�û�и��¹������ˣ��ӽ��쿪ʼ�����޽����Զ�Androidϵͳ��UIʵ����һ��ϵͳ�ķ�����Ҳ������ʵ֮ǰ�������ij�ŵ���ᵽAndroidϵͳ��UI���������ȽӴ����ı���ϵͳ�����������������ֵĻ����ˡ�Androidϵͳ�������Ĺ����У������Գ����������棬ÿһ�����涼��������һ����ͬ�������׶Ρ����Ľ���ϸ���������������������ʾ���̣��Ա���Կ������Ƕ�AndroidϵͳUIʵ�ֵķ���֮·��

��һ���������������ں������Ĺ����г��ֵģ�����һ����̬�Ļ��档�ڶ���������������init���������Ĺ����г��ֵģ���Ҳ��һ����̬�Ļ��档������������������ϵͳ���������Ĺ����г��ֵģ�����һ����̬�Ļ��档��������һ�����棬���Ƕ�����һ����Ϊ֡��������frame buffer�����fb����Ӳ���豸�Ͻ�����Ⱦ�ġ������������Ǿͷֱ���������������������fb����ʾ�ġ�

1. ��һ�������������ʾ����

Androidϵͳ�ĵ�һ������������ʵ��Linux�ں˵��������档��Ĭ������£���������Dz�����ֵģ����������ڱ����ں˵�ʱ������������������ѡ�

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�У����ij�ʼ������������ʾ��

  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. static int __init
  10. fbmem_init(void)
  11. {
  12. proc_create("fb", 0, NULL, &fb_proc_fops);
  13. if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
  14. printk("unable to get major %d for fb devs\n", FB_MAJOR);
  15. fb_class = class_create(THIS_MODULE, "graphics");
  16. if (IS_ERR(fb_class)) {
  17. printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
  18. fb_class = NULL;
  19. }
  20. return 0;
  21. }
/** * fbmem_init - init frame buffer subsystem * * Initialize the frame buffer subsystem. * * NOTE: This function is _only_ to be called by drivers/char/mem.c. * */ static int __init fbmem_init(void) { proc_create("fb", 0, NULL, &fb_proc_fops); if (register_chrdev(FB_MAJOR,"fb",&fb_fops)) printk("unable to get major %d for fb devs\n", FB_MAJOR); fb_class = class_create(THIS_MODULE, "graphics"); if (IS_ERR(fb_class)) { printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class)); fb_class = NULL; } return 0; }����������ȵ��ú���proc_create��/procĿ¼�´�����һ��fb�ļ��������ֵ��ú���register_chrdev��ע����һ������Ϊfb���ַ��豸�������ú���class_create��/sys/classĿ¼�´�����һ��graphicsĿ¼�����������ں˵�ͼ��ϵͳ��

ģ��fbmem���˻�ִ��������ʼ������֮�⣬���ᵼ��һ������register_framebuffer��

  1. EXPORT_SYMBOL(register_framebuffer);
EXPORT_SYMBOL(register_framebuffer);����������ں˵��������̻ᱻ���ã��Ա�����ִ��ע��֡������Ӳ���豸�IJ���������ʵ��������ʾ��

  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. int
  11. register_framebuffer(struct fb_info *fb_info)
  12. {
  13. int i;
  14. struct fb_event event;
  15. ......
  16. if (num_registered_fb == FB_MAX)
  17. return -ENXIO;
  18. ......
  19. num_registered_fb++;
  20. for (i = 0 ; i < FB_MAX; i++)
  21. if (!registered_fb[i])
  22. break;
  23. fb_info->node = i;
  24. mutex_init(&fb_info->lock);
  25. fb_info->dev = device_create(fb_class, fb_info->device,
  26. MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
  27. if (IS_ERR(fb_info->dev)) {
  28. /* Not fatal */
  29. printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));
  30. fb_info->dev = NULL;
  31. } else
  32. fb_init_device(fb_info);
  33. ......
  34. registered_fb[i] = fb_info;
  35. event.info = fb_info;
  36. fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
  37. return 0;
  38. }
/** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure * * Registers a frame buffer device @fb_info. * * Returns negative errno on error, or zero for success. * */ int register_framebuffer(struct fb_info *fb_info) { int i; struct fb_event event; ...... if (num_registered_fb == FB_MAX) return -ENXIO; ...... num_registered_fb++; for (i = 0 ; i < FB_MAX; i++) if (!registered_fb[i]) break; fb_info->node = i; mutex_init(&fb_info->lock); fb_info->dev = device_create(fb_class, fb_info->device, MKDEV(FB_MAJOR, i), NULL, "fb%d", i); if (IS_ERR(fb_info->dev)) { /* Not fatal */ printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev)); fb_info->dev = NULL; } else fb_init_device(fb_info); ...... registered_fb[i] = fb_info; event.info = fb_info; fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); return 0; }����ϵͳ�п��ܻ���ڶ��֡������Ӳ���豸����ˣ�fbmemģ��ʹ��һ������registered_fb���������Ѿ�ע���˵�֡������Ӳ���豸�����У�ÿһ��֡������Ӳ������ʹ��һ���ṹ��fb_info�������ġ�

����֪������Linux�ں��У�ÿһ��Ӳ���豸����һ�����豸�ź�һ�����豸�ţ���������Ψһ�ر�ʶһ��Ӳ���豸������֡������Ӳ���豸��˵�����ǵ����豸�Ŷ���ΪFB_MAJOR��29���������豸������ע���˳���йأ����ǵ�ֵ���ε���0��1��2�ȡ�

ÿһ����ע���֡������Ӳ���豸��/dev/graphicsĿ¼�¶���һ����Ӧ���豸�ļ�fb�����У���ʾһ�����豸�š����磬��һ����ע���֡������Ӳ���豸��/dev/graphicsĿ¼�¶���һ����Ӧ���豸�ļ�fb0���û��ռ��Ӧ�ó���ͨ������豸�ļ��Ϳ��Բ���֡������Ӳ���豸�ˣ�����Ҫ��ʾ�Ļ�����Ⱦ��֡������Ӳ���豸��ȥ��

�����������ͨ�����ú���fb_notifier_call_chain��֪ͨ֡����������̨����һ���µ�֡�������豸��ע�ᵽ�ں������ˡ�

֡����������̨���ں��ж�Ӧ����������ģ��Ϊfbcon����ʵ�����ļ�kernel/goldfish/drivers/video/console/fbcon.c�У����ij�ʼ������������ʾ��

  1. static struct notifier_block fbcon_event_notifier = {
  2. .notifier_call = fbcon_event_notify,
  3. };
  4. ......
  5. static int __init fb_console_init(void)
  6. {
  7. int i;
  8. acquire_console_sem();
  9. fb_register_client(&fbcon_event_notifier);
  10. fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
  11. "fbcon");
  12. if (IS_ERR(fbcon_device)) {
  13. printk(KERN_WARNING "Unable to create device "
  14. "for fbcon; errno = %ld\n",
  15. PTR_ERR(fbcon_device));
  16. fbcon_device = NULL;
  17. } else
  18. fbcon_init_device();
  19. for (i = 0; i < MAX_NR_CONSOLES; i++)
  20. con2fb_map[i] = -1;
  21. release_console_sem();
  22. fbcon_start();
  23. return 0;
  24. }
static struct notifier_block fbcon_event_notifier = { .notifier_call = fbcon_event_notify, }; ...... static int __init fb_console_init(void) { int i; acquire_console_sem(); fb_register_client(&fbcon_event_notifier); fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL, "fbcon"); if (IS_ERR(fbcon_device)) { printk(KERN_WARNING "Unable to create device " "for fbcon; errno = %ld\n", PTR_ERR(fbcon_device)); fbcon_device = NULL; } else fbcon_init_device(); for (i = 0; i < MAX_NR_CONSOLES; i++) con2fb_map[i] = -1; release_console_sem(); fbcon_start(); return 0; }
����������˻���ú���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. switch(action) {
  10. ......
  11. case FB_EVENT_FB_REGISTERED:
  12. ret = fbcon_fb_registered(info);
  13. break;
  14. ......
  15. }
  16. done:
  17. return ret;
  18. }
static int fbcon_event_notify(struct notifier_block *self, unsigned long action, void *data) { struct fb_event *event = data; struct fb_info *info = event->info; ...... int ret = 0; ...... switch(action) { ...... case FB_EVENT_FB_REGISTERED: ret = fbcon_fb_registered(info); break; ...... } done: return ret; }
֡������Ӳ���豸��ע���¼��������ɺ���fbcon_fb_registered�������ģ�����ʵ��������ʾ��

  1. static int fbcon_fb_registered(struct fb_info *info)
  2. {
  3. int ret = 0, i, idx = info->node;
  4. fbcon_select_primary(info);
  5. if (info_idx == -1) {
  6. for (i = first_fb_vc; i <= last_fb_vc; i++) {
  7. if (con2fb_map_boot[i] == idx) {
  8. info_idx = idx;
  9. break;
  10. }
  11. }
  12. if (info_idx != -1)
  13. ret = fbcon_takeover(1);
  14. } else {
  15. for (i = first_fb_vc; i <= last_fb_vc; i++) {
  16. if (con2fb_map_boot[i] == idx)
  17. set_con2fb_map(i, idx, 0);
  18. }
  19. }
  20. return ret;
  21. }
static int fbcon_fb_registered(struct fb_info *info) { int ret = 0, i, idx = info->node; fbcon_select_primary(info); if (info_idx == -1) { for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map_boot[i] == idx) { info_idx = idx; break; } } if (info_idx != -1) ret = fbcon_takeover(1); } else { for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map_boot[i] == idx) set_con2fb_map(i, idx, 0); } } return ret; }����fbcon_select_primary������鵱ǰע���֡������Ӳ���豸�Ƿ���һ����֡������Ӳ���豸������ǵĻ�����ô�ͽ�������Ϣ��¼�������������ֻ�е�ָ����CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY����ѡ��ʱ����Ч������Ļ�������һ���պ�����

��Linux�ں��У�ÿһ������̨��ÿһ��֡������Ӳ���豸����һ����0��ʼ�ı�ţ����ǵij�ʼ��Ӧ��ϵ������ȫ������con2fb_map_boot�С�����̨��֡������Ӳ���豸�ij�ʼ��Ӧ��ϵ�ǿ���ͨ�������ں�������������ʼ���ġ���ģ��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��ʱ�򣬴���ȥ�IJ���Ϊ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. if (!num_registered_fb)
  5. return -ENODEV;
  6. if (!show_logo)
  7. logo_shown = FBCON_LOGO_DONTSHOW;
  8. for (i = first_fb_vc; i <= last_fb_vc; i++)
  9. con2fb_map[i] = info_idx;
  10. err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,
  11. fbcon_is_default);
  12. if (err) {
  13. for (i = first_fb_vc; i <= last_fb_vc; i++) {
  14. con2fb_map[i] = -1;
  15. }
  16. info_idx = -1;
  17. }
  18. return err;
  19. }
static int fbcon_takeover(int show_logo) { int err, i; if (!num_registered_fb) return -ENODEV; if (!show_logo) logo_shown = FBCON_LOGO_DONTSHOW; for (i = first_fb_vc; i <= last_fb_vc; i++) con2fb_map[i] = info_idx; err = take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); if (err) { for (i = first_fb_vc; i <= last_fb_vc; i++) { con2fb_map[i] = -1; } info_idx = -1; } return err; }ȫ�ֱ���logo_shown�ij�ʼֵΪ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. static const struct consw fb_con = {
  5. .owner = THIS_MODULE,
  6. .con_startup = fbcon_startup,
  7. .con_init = fbcon_init,
  8. .con_deinit = fbcon_deinit,
  9. .con_clear = fbcon_clear,
  10. .con_putc = fbcon_putc,
  11. .con_putcs = fbcon_putcs,
  12. .con_cursor = fbcon_cursor,
  13. .con_scroll = fbcon_scroll,
  14. .con_bmove = fbcon_bmove,
  15. .con_switch = fbcon_switch,
  16. .con_blank = fbcon_blank,
  17. .con_font_set = fbcon_set_font,
  18. .con_font_get = fbcon_get_font,
  19. .con_font_default = fbcon_set_def_font,
  20. .con_font_copy = fbcon_copy_font,
  21. .con_set_palette = fbcon_set_palette,
  22. .con_scrolldelta = fbcon_scrolldelta,
  23. .con_set_origin = fbcon_set_origin,
  24. .con_invert_region = fbcon_invert_region,
  25. .con_screen_pos = fbcon_screen_pos,
  26. .con_getxy = fbcon_getxy,
  27. .con_resize = fbcon_resize,
  28. };
/* * The console `switch' structure for the frame buffer based console */ static const struct consw fb_con = { .owner = THIS_MODULE, .con_startup = fbcon_startup, .con_init = fbcon_init, .con_deinit = fbcon_deinit, .con_clear = fbcon_clear, .con_putc = fbcon_putc, .con_putcs = fbcon_putcs, .con_cursor = fbcon_cursor, .con_scroll = fbcon_scroll, .con_bmove = fbcon_bmove, .con_switch = fbcon_switch, .con_blank = fbcon_blank, .con_font_set = fbcon_set_font, .con_font_get = fbcon_get_font, .con_font_default = fbcon_set_def_font, .con_font_copy = fbcon_copy_font, .con_set_palette = fbcon_set_palette, .con_scrolldelta = fbcon_scrolldelta, .con_set_origin = fbcon_set_origin, .con_invert_region = fbcon_invert_region, .con_screen_pos = fbcon_screen_pos, .con_getxy = fbcon_getxy, .con_resize = fbcon_resize, };
������������Ҫ��ע����fbcon_init��fbcon_switch��ʵ�֣�ϵͳ����ͨ��������ʼ�����л�����̨�ġ��ڳ�ʼ���Ĺ����У�������Ƿ���Ҫ׼����һ��������������ݣ������л�����̨�Ĺ����У�������Ƿ���Ҫ��ʾ��һ��������������ݡ�

����fbcon_init��ʵ��������ʾ��

  1. static void fbcon_init(struct vc_data *vc, int init)
  2. {
  3. struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
  4. struct fbcon_ops *ops;
  5. struct vc_data **default_mode = vc->vc_display_fg;
  6. struct vc_data *svc = *default_mode;
  7. struct display *t, *p = &fb_display[vc->vc_num];
  8. int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256;
  9. int cap;
  10. if (info_idx == -1 || info == NULL)
  11. return;
  12. ......
  13. if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
  14. (info->fix.type == FB_TYPE_TEXT))
  15. logo = 0;
  16. ......
  17. if (logo)
  18. fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
  19. ......
  20. }
static void fbcon_init(struct vc_data *vc, int init) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops; struct vc_data **default_mode = vc->vc_display_fg; struct vc_data *svc = *default_mode; struct display *t, *p = &fb_display[vc->vc_num]; int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; int cap; if (info_idx == -1 || info == NULL) return; ...... if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || (info->fix.type == FB_TYPE_TEXT)) logo = 0; ...... if (logo) fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); ...... }

��ǰ���ڳ�ʼ���Ŀ���̨ʹ�ò���vc�������������ij�Ա����vc_num����������ǰ���ڳ�ʼ���Ŀ���̨�ı�š�ͨ��������֮�󣬾Ϳ�����ȫ������con2fb_map���ҵ���Ӧ��֡������Ӳ���豸��š�����֡������Ӳ���豸���֮�󣬾Ϳ���������һ��ȫ��������registered_fb���ҵ�һ��fb_info�ṹ��info�����������뵱ǰ���ڳ�ʼ���Ŀ���̨����Ӧ��֡������Ӳ���豸��

����vc�ij�Ա����vc_display_fg��������ϵͳ��ǰ�ɼ��Ŀ���̨������һ������Ϊvc_data**��ָ�롣������Ϳ��Կ��������յõ���vc_data�ṹ��svc������������ϵͳ��ǰ�ɼ��Ŀ���̨�ġ�

����logo��ʼ��ʱ������Ϊ1����ʾ��Ҫ��ʾ��һ���������棬������������������£�����ֵ�ᱻ����Ϊ0����ʾ����Ҫ��ʾ�������棺

A. ����vc�ͱ���svcָ��IJ���ͬһ��vc_data�ṹ�壬����ǰ���ڳ�ʼ���Ŀ���̨����ϵͳ��ǰ�ɼ��Ŀ���̨��

B. ȫ�ֱ���logo_shown��ֵ����FBCON_LOGO_DONTSHOW����ϵͳ����Ҫ��ʾ��һ���������档

C. �뵱ǰ���ڳ�ʼ���Ŀ���̨����Ӧ��֡������Ӳ���豸����ʾ��ʽ������Ϊ�ı���ʽ����info->fix.type��ֵ����FB_TYPE_TEXT��

�����յõ��ı���logo��ֵ����1��ʱ�򣬽������ͻ���ú���fbcon_prepare_logo��׼��Ҫ��ʾ�ĵ�һ��������������ݡ�

�ں���fbcon_prepare_logo�У���һ�����������������ͨ�����ú���fb_prepare_logo��׼���ģ�������ʾ��

  1. static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
  2. int cols, int rows, int new_cols, int new_rows)
  3. {
  4. ......
  5. int logo_height;
  6. ......
  7. logo_height = fb_prepare_logo(info, ops->rotate);
  8. ......
  9. if (logo_lines > vc->vc_bottom) {
  10. ......
  11. } else if (logo_shown != FBCON_LOGO_DONTSHOW) {
  12. logo_shown = FBCON_LOGO_DRAW;
  13. ......
  14. }
  15. }
static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, int cols, int rows, int new_cols, int new_rows) { ...... int logo_height; ...... logo_height = fb_prepare_logo(info, ops->rotate); ...... if (logo_lines > vc->vc_bottom) { ...... } else if (logo_shown != FBCON_LOGO_DONTSHOW) { logo_shown = FBCON_LOGO_DRAW; ...... } }

�Ӻ���fb_prepare_logo������֮�����Ҫ��ʾ�ĵ�һ������������ռ�õĿ���̨����С�ڵ��ڲ���vc�������Ŀ���̨���������������ȫ�ֱ���logo_show��ֵ������FBCON_LOGO_DONTSHOW����ô��˵��ǰ�����ᵽ�ĵ�һ���������������ʾ�ڿ���̨�С���ʱ��ȫ�ֱ���logo_show��ֵ�ͻᱻ����ΪFBCON_LOGO_DRAW����ʾ��һ���������洦�ڵȴ���Ⱦ��״̬��

����fb_prepare_logoʵ�����ļ�kernel/goldfish/drivers/video/fbmem.c�У�������ʾ��

  1. int fb_prepare_logo(struct fb_info *info, int rotate)
  2. {
  3. int depth = fb_get_color_depth(&info->var, &info->fix);
  4. unsigned int yres;
  5. memset(&fb_logo, 0, sizeof(struct logo_data));
  6. ......
  7. if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
  8. depth = info->var.blue.length;
  9. if (info->var.red.length < depth)
  10. depth = info->var.red.length;
  11. if (info->var.green.length < depth)
  12. depth = info->var.green.length;
  13. }
  14. if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) {
  15. /* assume console colormap */
  16. depth = 4;
  17. }
  18. /* Return if no suitable logo was found */
  19. fb_logo.logo = fb_find_logo(depth);
  20. ......
  21. return fb_prepare_extra_logos(info, fb_logo.logo->height, yres);
  22. }
int fb_prepare_logo(struct fb_info *info, int rotate) { int depth = fb_get_color_depth(&info->var, &info->fix); unsigned int yres; memset(&fb_logo, 0, sizeof(struct logo_data)); ...... if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { depth = info->var.blue.length; if (info->var.red.length < depth) depth = info->var.red.length; if (info->var.green.length < depth) depth = info->var.green.length; } if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) { /* assume console colormap */ depth = 4; } /* Return if no suitable logo was found */ fb_logo.logo = fb_find_logo(depth); ...... return fb_prepare_extra_logos(info, fb_logo.logo->height, yres); }����������ȵõ�����info��������֡������Ӳ���豸����ɫ���depth�������ٵ��ú���fb_find_logo�����Ҫ��ʾ�ĵ�һ��������������ݣ����ұ�����ȫ�ֱ���fb_logo�ij�Ա����logo�С�

����fb_find_logoʵ�����ļ�kernel/goldfish/drivers/video/logo/logo.c�ļ��У�������ʾ��

  1. extern const struct linux_logo logo_linux_mono;
  2. extern const struct linux_logo logo_linux_vga16;
  3. extern const struct linux_logo logo_linux_clut224;
  4. extern const struct linux_logo logo_blackfin_vga16;
  5. extern const struct linux_logo logo_blackfin_clut224;
  6. extern const struct linux_logo logo_dec_clut224;
  7. extern const struct linux_logo logo_mac_clut224;
  8. extern const struct linux_logo logo_parisc_clut224;
  9. extern const struct linux_logo logo_sgi_clut224;
  10. extern const struct linux_logo logo_sun_clut224;
  11. extern const struct linux_logo logo_superh_mono;
  12. extern const struct linux_logo logo_superh_vga16;
  13. extern const struct linux_logo logo_superh_clut224;
  14. extern const struct linux_logo logo_m32r_clut224;
  15. static int nologo;
  16. module_param(nologo, bool, 0);
  17. MODULE_PARM_DESC(nologo, "Disables startup logo");
  18. /* logo's are marked __initdata. Use __init_refok to tell
  19. * modpost that it is intended that this function uses data
  20. * marked __initdata.
  21. */
  22. const struct linux_logo * __init_refok fb_find_logo(int depth)
  23. {
  24. const struct linux_logo *logo = NULL;
  25. if (nologo)
  26. return NULL;
  27. if (depth >= 1) {
  28. #ifdef CONFIG_LOGO_LINUX_MONO
  29. /* Generic Linux logo */
  30. logo = &logo_linux_mono;
  31. #endif
  32. #ifdef CONFIG_LOGO_SUPERH_MONO
  33. /* SuperH Linux logo */
  34. logo = &logo_superh_mono;
  35. #endif
  36. }
  37. if (depth >= 4) {
  38. #ifdef CONFIG_LOGO_LINUX_VGA16
  39. /* Generic Linux logo */
  40. logo = &logo_linux_vga16;
  41. #endif
  42. #ifdef CONFIG_LOGO_BLACKFIN_VGA16
  43. /* Blackfin processor logo */
  44. logo = &logo_blackfin_vga16;
  45. #endif
  46. #ifdef CONFIG_LOGO_SUPERH_VGA16
  47. /* SuperH Linux logo */
  48. logo = &logo_superh_vga16;
  49. #endif
  50. }
  51. if (depth >= 8) {
  52. #ifdef CONFIG_LOGO_LINUX_CLUT224
  53. /* Generic Linux logo */
  54. logo = &logo_linux_clut224;
  55. #endif
  56. #ifdef CONFIG_LOGO_BLACKFIN_CLUT224
  57. /* Blackfin Linux logo */
  58. logo = &logo_blackfin_clut224;
  59. #endif
  60. #ifdef CONFIG_LOGO_DEC_CLUT224
  61. /* DEC Linux logo on MIPS/MIPS64 or ALPHA */
  62. logo = &logo_dec_clut224;
  63. #endif
  64. #ifdef CONFIG_LOGO_MAC_CLUT224
  65. /* Macintosh Linux logo on m68k */
  66. if (MACH_IS_MAC)
  67. logo = &logo_mac_clut224;
  68. #endif
  69. #ifdef CONFIG_LOGO_PARISC_CLUT224
  70. /* PA-RISC Linux logo */
  71. logo = &logo_parisc_clut224;
  72. #endif
  73. #ifdef CONFIG_LOGO_SGI_CLUT224
  74. /* SGI Linux logo on MIPS/MIPS64 and VISWS */
  75. logo = &logo_sgi_clut224;
  76. #endif
  77. #ifdef CONFIG_LOGO_SUN_CLUT224
  78. /* Sun Linux logo */
  79. logo = &logo_sun_clut224;
  80. #endif
  81. #ifdef CONFIG_LOGO_SUPERH_CLUT224
  82. /* SuperH Linux logo */
  83. logo = &logo_superh_clut224;
  84. #endif
  85. #ifdef CONFIG_LOGO_M32R_CLUT224
  86. /* M32R Linux logo */
  87. logo = &logo_m32r_clut224;
  88. #endif
  89. }
  90. return logo;
  91. }
  92. EXPORT_SYMBOL_GPL(fb_find_logo);
extern const struct linux_logo logo_linux_mono; extern const struct linux_logo logo_linux_vga16; extern const struct linux_logo logo_linux_clut224; extern const struct linux_logo logo_blackfin_vga16; extern const struct linux_logo logo_blackfin_clut224; extern const struct linux_logo logo_dec_clut224; extern const struct linux_logo logo_mac_clut224; extern const struct linux_logo logo_parisc_clut224; extern const struct linux_logo logo_sgi_clut224; extern const struct linux_logo logo_sun_clut224; extern const struct linux_logo logo_superh_mono; extern const struct linux_logo logo_superh_vga16; extern const struct linux_logo logo_superh_clut224; extern const struct linux_logo logo_m32r_clut224; static int nologo; module_param(nologo, bool, 0); MODULE_PARM_DESC(nologo, "Disables startup logo"); /* logo's are marked __initdata. Use __init_refok to tell * modpost that it is intended that this function uses data * marked __initdata. */ const struct linux_logo * __init_refok fb_find_logo(int depth) { const struct linux_logo *logo = NULL; if (nologo) return NULL; if (depth >= 1) { #ifdef CONFIG_LOGO_LINUX_MONO /* Generic Linux logo */ logo = &logo_linux_mono; #endif #ifdef CONFIG_LOGO_SUPERH_MONO /* SuperH Linux logo */ logo = &logo_superh_mono; #endif } if (depth >= 4) { #ifdef CONFIG_LOGO_LINUX_VGA16 /* Generic Linux logo */ logo = &logo_linux_vga16; #endif #ifdef CONFIG_LOGO_BLACKFIN_VGA16 /* Blackfin processor logo */ logo = &logo_blackfin_vga16; #endif #ifdef CONFIG_LOGO_SUPERH_VGA16 /* SuperH Linux logo */ logo = &logo_superh_vga16; #endif } if (depth >= 8) { #ifdef CONFIG_LOGO_LINUX_CLUT224 /* Generic Linux logo */ logo = &logo_linux_clut224; #endif #ifdef CONFIG_LOGO_BLACKFIN_CLUT224 /* Blackfin Linux logo */ logo = &logo_blackfin_clut224; #endif #ifdef CONFIG_LOGO_DEC_CLUT224 /* DEC Linux logo on MIPS/MIPS64 or ALPHA */ logo = &logo_dec_clut224; #endif #ifdef CONFIG_LOGO_MAC_CLUT224 /* Macintosh Linux logo on m68k */ if (MACH_IS_MAC) logo = &logo_mac_clut224; #endif #ifdef CONFIG_LOGO_PARISC_CLUT224 /* PA-RISC Linux logo */ logo = &logo_parisc_clut224; #endif #ifdef CONFIG_LOGO_SGI_CLUT224 /* SGI Linux logo on MIPS/MIPS64 and VISWS */ logo = &logo_sgi_clut224; #endif #ifdef CONFIG_LOGO_SUN_CLUT224 /* Sun Linux logo */ logo = &logo_sun_clut224; #endif #ifdef CONFIG_LOGO_SUPERH_CLUT224 /* SuperH Linux logo */ logo = &logo_superh_clut224; #endif #ifdef CONFIG_LOGO_M32R_CLUT224 /* M32R Linux logo */ logo = &logo_m32r_clut224; #endif } return logo; } EXPORT_SYMBOL_GPL(fb_find_logo);�ļ���ʼ������һϵ��linux_logo�ṹ������ֱ���������kernel/goldfish/drivers/video/logoĿ¼�µ�һϵ��ppm����pbm�ļ������ݵġ���Щppm����pbm�ļ���������������һ����������ġ�

ȫ�ֱ���nologo��һ������Ϊ����������ģ�����������Ĭ��ֵ����0����ʾҪ��ʾ��һ���������档����������£�����fb_find_logo�ͻ���ݲ���depth��ֵ�Լ���ͬ�ı���ѡ����ѡ���һ��������������ݣ����ұ����ڱ���logo�з��ظ������ߡ�

��һ��ִ�����֮�󣬵�һ��������������ݾͱ�����ģ��fbmem��ȫ�ֱ���fb_logo�ij�Ա����logo���ˡ���ʱ�����̨�ij�ʼ������Ҳ�����ˣ�������ϵͳ�ͻ�ִ���л�����̨�IJ�����ǰ���ᵽ����ϵͳִ���л�����̨�IJ�����ʱ��ģ��fbcon�еĺ���fbcon_switch�ͻᱻ���á��ڵ��õĹ����У��ͻ�ִ����ʾ��һ����������IJ�����

����fbcon_switchʵ�����ļ�kernel/goldfish/drivers/video/console/fbcon.c�У���ʾ��һ����������Ĺ���������ʾ��

  1. static int fbcon_switch(struct vc_data *vc)
  2. {
  3. struct fb_info *info, *old_info = NULL;
  4. struct fbcon_ops *ops;
  5. struct display *p = &fb_display[vc->vc_num];
  6. struct fb_var_screeninfo var;
  7. int i, prev_console, charcnt = 256;
  8. ......
  9. if (logo_shown == FBCON_LOGO_DRAW) {
  10. logo_shown = fg_console;
  11. /* This is protected above by initmem_freed */
  12. fb_show_logo(info, ops->rotate);
  13. ......
  14. return 0;
  15. }
  16. return 1;
  17. }
static int fbcon_switch(struct vc_data *vc) { struct fb_info *info, *old_info = NULL; struct fbcon_ops *ops; struct display *p = &fb_display[vc->vc_num]; struct fb_var_screeninfo var; int i, prev_console, charcnt = 256; ...... if (logo_shown == FBCON_LOGO_DRAW) { logo_shown = fg_console; /* This is protected above by initmem_freed */ fb_show_logo(info, ops->rotate); ...... return 0; } return 1; }����ǰ����׼����һ��������������ݵ�ʱ��ȫ�ֱ���logo_show��ֵ������ΪFBCON_LOGO_DRAW����ˣ��������ͻ���ú���fb_show_logo����ʾ��һ���������档����ʾ֮ǰ����������Ὣȫ�ֱ���logo_shown��ֵ����Ϊfg_console�����߱�ʾϵͳ��ǰ�ɼ��Ŀ���̨�ı�š�

����fb_show_logoʵ�����ļ�kernel/goldfish/drivers/video/fbmem.c�У�������ʾ��

  1. int fb_show_logo(struct fb_info *info, int rotate)
  2. {
  3. int y;
  4. y = fb_show_logo_line(info, rotate, fb_logo.logo, 0,
  5. num_online_cpus());
  6. ......
  7. return y;
  8. }
int fb_show_logo(struct fb_info *info, int rotate) { int y; y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, num_online_cpus()); ...... return y; }���������������һ������fb_show_logo_line����һ��ִ����Ⱦ��һ����������IJ�����

����fb_show_logo_lineҲ��ʵ�����ļ�kernel/goldfish/drivers/video/fbmem.c�У�������ʾ��

  1. static int fb_show_logo_line(struct fb_info *info, int rotate,
  2. const struct linux_logo *logo, int y,
  3. unsigned int n)
  4. {
  5. u32 *palette = NULL, *saved_pseudo_palette = NULL;
  6. unsigned char *logo_new = NULL, *logo_rotate = NULL;
  7. struct fb_image image;
  8. /* Return if the frame buffer is not mapped or suspended */
  9. if (logo == NULL || info->state != FBINFO_STATE_RUNNING ||
  10. info->flags & FBINFO_MODULE)
  11. return 0;
  12. image.depth = 8;
  13. image.data = logo->data;
  14. if (fb_logo.needs_cmapreset)
  15. fb_set_logocmap(info, logo);
  16. if (fb_logo.needs_truepalette ||
  17. fb_logo.needs_directpalette) {
  18. palette = kmalloc(256 * 4, GFP_KERNEL);
  19. if (palette == NULL)
  20. return 0;
  21. if (fb_logo.needs_truepalette)
  22. fb_set_logo_truepalette(info, logo, palette);
  23. else
  24. fb_set_logo_directpalette(info, logo, palette);
  25. saved_pseudo_palette = info->pseudo_palette;
  26. info->pseudo_palette = palette;
  27. }
  28. if (fb_logo.depth <= 4) {
  29. logo_new = kmalloc(logo->width * logo->height, GFP_KERNEL);
  30. if (logo_new == NULL) {
  31. kfree(palette);
  32. if (saved_pseudo_palette)
  33. info->pseudo_palette = saved_pseudo_palette;
  34. return 0;
  35. }
  36. image.data = logo_new;
  37. fb_set_logo(info, logo, logo_new, fb_logo.depth);
  38. }
  39. image.dx = 0;
  40. image.dy = y;
  41. image.width = logo->width;
  42. image.height = logo->height;
  43. if (rotate) {
  44. logo_rotate = kmalloc(logo->width *
  45. logo->height, GFP_KERNEL);
  46. if (logo_rotate)
  47. fb_rotate_logo(info, logo_rotate, &image, rotate);
  48. }
  49. fb_do_show_logo(info, &image, rotate, n);
  50. kfree(palette);
  51. if (saved_pseudo_palette != NULL)
  52. info->pseudo_palette = saved_pseudo_palette;
  53. kfree(logo_new);
  54. kfree(logo_rotate);
  55. return logo->height;
  56. }
static int fb_show_logo_line(struct fb_info *info, int rotate, const struct linux_logo *logo, int y, unsigned int n) { u32 *palette = NULL, *saved_pseudo_palette = NULL; unsigned char *logo_new = NULL, *logo_rotate = NULL; struct fb_image image; /* Return if the frame buffer is not mapped or suspended */ if (logo == NULL || info->state != FBINFO_STATE_RUNNING || info->flags & FBINFO_MODULE) return 0; image.depth = 8; image.data = logo->data; if (fb_logo.needs_cmapreset) fb_set_logocmap(info, logo); if (fb_logo.needs_truepalette || fb_logo.needs_directpalette) { palette = kmalloc(256 * 4, GFP_KERNEL); if (palette == NULL) return 0; if (fb_logo.needs_truepalette) fb_set_logo_truepalette(info, logo, palette); else fb_set_logo_directpalette(info, logo, palette); saved_pseudo_palette = info->pseudo_palette; info->pseudo_palette = palette; } if (fb_logo.depth <= 4) { logo_new = kmalloc(logo->width * logo->height, GFP_KERNEL); if (logo_new == NULL) { kfree(palette); if (saved_pseudo_palette) info->pseudo_palette = saved_pseudo_palette; return 0; } image.data = logo_new; fb_set_logo(info, logo, logo_new, fb_logo.depth); } image.dx = 0; image.dy = y; image.width = logo->width; image.height = logo->height; if (rotate) { logo_rotate = kmalloc(logo->width * logo->height, GFP_KERNEL); if (logo_rotate) fb_rotate_logo(info, logo_rotate, &image, rotate); } fb_do_show_logo(info, &image, rotate, n); kfree(palette); if (saved_pseudo_palette != NULL) info->pseudo_palette = saved_pseudo_palette; kfree(logo_new); kfree(logo_rotate); return logo->height; }����logoָ����ǰ����׼���ĵ�һ��������������ݡ�����������ȸ��ݲ���logo������������һ��fb_image�ṹ��image��������������Ҫ��ʾ�ĵ�һ���������档���͵��ú���fb_do_show_logo������ִ����Ⱦ��һ����������IJ�����

����fb_do_show_logoҲ��ʵ�����ļ�kernel/goldfish/drivers/video/fbmem.c�У�������ʾ��

  1. static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
  2. int rotate, unsigned int num)
  3. {
  4. unsigned int x;
  5. if (rotate == FB_ROTATE_UR) {
  6. for (x = 0;
  7. x < num && image->dx + image->width <= info->var.xres;
  8. x++) {
  9. info->fbops->fb_imageblit(info, image);
  10. image->dx += image->width + 8;
  11. }
  12. } else if (rotate == FB_ROTATE_UD) {
  13. for (x = 0; x < num && image->dx >= 0; x++) {
  14. info->fbops->fb_imageblit(info, image);
  15. image->dx -= image->width + 8;
  16. }
  17. } else if (rotate == FB_ROTATE_CW) {
  18. for (x = 0;
  19. x < num && image->dy + image->height <= info->var.yres;
  20. x++) {
  21. info->fbops->fb_imageblit(info, image);
  22. image->dy += image->height + 8;
  23. }
  24. } else if (rotate == FB_ROTATE_CCW) {
  25. for (x = 0; x < num && image->dy >= 0; x++) {
  26. info->fbops->fb_imageblit(info, image);
  27. image->dy -= image->height + 8;
  28. }
  29. }
  30. }
static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, int rotate, unsigned int num) { unsigned int x; if (rotate == FB_ROTATE_UR) { for (x = 0; x < num && image->dx + image->width <= info->var.xres; x++) { info->fbops->fb_imageblit(info, image); image->dx += image->width + 8; } } else if (rotate == FB_ROTATE_UD) { for (x = 0; x < num && image->dx >= 0; x++) { info->fbops->fb_imageblit(info, image); image->dx -= image->width + 8; } } else if (rotate == FB_ROTATE_CW) { for (x = 0; x < num && image->dy + image->height <= info->var.yres; x++) { info->fbops->fb_imageblit(info, image); image->dy += image->height + 8; } } else if (rotate == FB_ROTATE_CCW) { for (x = 0; x < num && image->dy >= 0; x++) { info->fbops->fb_imageblit(info, image); image->dy -= image->height + 8; } } }����rotate����������Ļ�ĵ�ǰ��ת������Ļ��ת����ͬ����һ�������������Ⱦ��ʽҲ������ͬ�����磬����Ļ���µߵ�ʱ��FB_ROTATE_UD������һ���������������˳��͸պõ�����������ʱ�����Ҫ���ҵ�������Ⱦ��������������FB_ROTATE_UR��FB_ROTATE_CW��FB_ROTATE_CCW�ֱ��ʾû����ת��˳ʱ����ת90�Ⱥ���ʱ����ת90�ȡ�

����info��������Ҫ��Ⱦ��֡������Ӳ���豸�����ij�Ա����fbopsָ����һϵ�лص���������������֡������Ӳ���豸�����У��ص�����fb_imageblit����������ָ����֡������Ӳ���豸��Ⱦָ����ͼ��ġ�

���ˣ���һ�������������ʾ���̾ͷ�������ˡ�

2. �ڶ��������������ʾ����

���ڵڶ���������������init���������Ĺ�������ʾ�ģ���ˣ����Ǿʹ�init���̵���ں���main��ʼ�����ڶ��������������ʾ���̡�

init���̵���ں���mainʵ�����ļ�system/core/init/init.c�У�������ʾ��

  1. int main(int argc, char **argv)
  2. {
  3. int fd_count = 0;
  4. struct pollfd ufds[4];
  5. ......
  6. int property_set_fd_init = 0;
  7. int signal_fd_init = 0;
  8. int keychord_fd_init = 0;
  9. if (!strcmp(basename(argv[0]), "ueventd"))
  10. return ueventd_main(argc, argv);
  11. ......
  12. queue_builtin_action(console_init_action, "console_init");
  13. ......
  14. for(;;) {
  15. int nr, i, timeout = -1;
  16. execute_one_command();
  17. restart_processes();
  18. if (!property_set_fd_init && get_property_set_fd() > 0) {
  19. ufds[fd_count].fd = get_property_set_fd();
  20. ufds[fd_count].events = POLLIN;
  21. ufds[fd_count].revents = 0;
  22. fd_count++;
  23. property_set_fd_init = 1;
  24. }
  25. if (!signal_fd_init && get_signal_fd() > 0) {
  26. ufds[fd_count].fd = get_signal_fd();
  27. ufds[fd_count].events = POLLIN;
  28. ufds[fd_count].revents = 0;
  29. fd_count++;
  30. signal_fd_init = 1;
  31. }
  32. if (!keychord_fd_init && get_keychord_fd() > 0) {
  33. ufds[fd_count].fd = get_keychord_fd();
  34. ufds[fd_count].events = POLLIN;
  35. ufds[fd_count].revents = 0;
  36. fd_count++;
  37. keychord_fd_init = 1;
  38. }
  39. if (process_needs_restart) {
  40. timeout = (process_needs_restart - gettime()) * 1000;
  41. if (timeout < 0)
  42. timeout = 0;
  43. }
  44. if (!action_queue_empty() || cur_action)
  45. timeout = 0;
  46. ......
  47. nr = poll(ufds, fd_count, timeout);
  48. if (nr <= 0)
  49. continue;
  50. for (i = 0; i < fd_count; i++) {
  51. if (ufds[i].revents == POLLIN) {
  52. if (ufds[i].fd == get_property_set_fd())
  53. handle_property_set_fd();
  54. else if (ufds[i].fd == get_keychord_fd())
  55. handle_keychord();
  56. else if (ufds[i].fd == get_signal_fd())
  57. handle_signal();
  58. }
  59. }
  60. }
  61. return 0;
  62. }
int main(int argc, char **argv) { int fd_count = 0; struct pollfd ufds[4]; ...... int property_set_fd_init = 0; int signal_fd_init = 0; int keychord_fd_init = 0; if (!strcmp(basename(argv[0]), "ueventd")) return ueventd_main(argc, argv); ...... queue_builtin_action(console_init_action, "console_init"); ...... for(;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); if (!property_set_fd_init && get_property_set_fd() > 0) { ufds[fd_count].fd = get_property_set_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; property_set_fd_init = 1; } if (!signal_fd_init && get_signal_fd() > 0) { ufds[fd_count].fd = get_signal_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; signal_fd_init = 1; } if (!keychord_fd_init && get_keychord_fd() > 0) { ufds[fd_count].fd = get_keychord_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; keychord_fd_init = 1; } if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) timeout = 0; ...... nr = poll(ufds, fd_count, timeout); if (nr <= 0) continue; for (i = 0; i < fd_count; i++) { if (ufds[i].revents == POLLIN) { if (ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) handle_signal(); } } } return 0; }����һ��ʼ�������жϲ���argv[0]��ֵ�Ƿ���ڡ�ueventd��������ǰ���������Ľ��������Ƿ���ڡ�ueventd��������ǵĻ�����ô����ueventd_main����������ں�����������ô�����أ���ǰ���������Ľ��̲���init������������ô���ܻ���ڡ�ueventd����ԭ������Ŀ���豸�ϣ���ִ���ļ�/sbin/ueventd�ǿ�ִ���ļ�/init��һ�����������ļ�����Ӧ�ó���ueventd��init���е���ͬһ����ִ���ļ����ں��������֮�󣬿�ִ���ļ�/init���Ȼᱻִ�У���init���̻����ȱ�������init�����������Ĺ����У���������ű�/init.rc���н������������ű�/init.rc�У�������һ��ueventd���̣�����Ӧ�Ŀ�ִ���ļ�Ϊ/sbin/ueventd����ueventd���̼��صĿ�ִ���ļ�ҲΪ/init����ˣ�ͨ���жϲ���argv[0]��ֵ���Ϳ���֪����ǰ������������init���̻���ueventd���̡�

ueventd��������ʲô�õ��أ�������������uevent�¼��ģ�����������ϵͳ�豸�ġ���ǰ�����������֪��������������ں���Ϊueventd_main��ʵ����system/core/init/ueventd.c�С�ueventd���̻�ͨ��һ��socket�ӿ������ں�ͨ�ţ��Ա���Լ��ϵͳ�豸�¼������磬��ǰ����Ubuntu��ΪAndroidϵͳ��дLinux�ں���������һ���У� ���ǵ���device_create������������һ������Ϊ��hello�����ַ��豸����ʱ���ں˾ͻ���ǰ���ᵽ��socket����һ���豸�����¼���ueventd����ͨ�����socket���������豸�����¼�֮�󣬾ͻ�/devĿ¼�´���һ������Ϊ��hello�����豸�ļ��������û��ռ��Ӧ�ó���Ϳ���ͨ���豸�ļ�/dev/hello������������hello����ͨ���ˡ�

��������������һ������queue_builtin_action����init�����е�һ����ִ��action����������һ�����Ƶ��ڡ�console_init����action�����action��Ӧ��ִ�к���Ϊconsole_init_action��������������ʾ�ڶ�����������ġ�

����queue_builtin_actionʵ�����ļ�system/core/init/init_parser.c�ļ��У�������ʾ��

  1. static list_declare(action_list);
  2. static list_declare(action_queue);
  3. void queue_builtin_action(int (*func)(int nargs, char **args), char *name)
  4. {
  5. struct action *act;
  6. struct command *cmd;
  7. act = calloc(1, sizeof(*act));
  8. act->name = name;
  9. list_init(&act->commands);
  10. cmd = calloc(1, sizeof(*cmd));
  11. cmd->func = func;
  12. cmd->args[0] = name;
  13. list_add_tail(&act->commands, &cmd->clist);
  14. list_add_tail(&action_list, &act->alist);
  15. action_add_queue_tail(act);
  16. }
  17. void action_add_queue_tail(struct action *act)
  18. {
  19. list_add_tail(&action_queue, &act->qlist);
  20. }
static list_declare(action_list); static list_declare(action_queue); void queue_builtin_action(int (*func)(int nargs, char **args), char *name) { struct action *act; struct command *cmd; act = calloc(1, sizeof(*act)); act->name = name; list_init(&act->commands); cmd = calloc(1, sizeof(*cmd)); cmd->func = func; cmd->args[0] = name; list_add_tail(&act->commands, &cmd->clist); list_add_tail(&action_list, &act->alist); action_add_queue_tail(act); } void action_add_queue_tail(struct action *act) { list_add_tail(&action_queue, &act->qlist); }action_list�б���������������ű�/init.rc�����õ���һϵ��action���Լ�һϵ���ڽ���action������Щaction��Ҫִ�е�ʱ�����Ǿͻᱻ���ӵ�action_queue�б���ȥ���Ա�init���̿���ִ�����ǡ�

�ص�init���̵���ں���main�У����init���̻���뵽һ������ѭ����ȥ�����������ѭ���У�init���̻�������������飺

A. ���ú���execute_one_command�����action_queue�б��Ƿ�Ϊ�ա������Ϊ�յĻ�����ôinit���̾ͻὫ�������б�ͷ�е�action�Ƴ�������ִ��������Ƴ���action������ǰ�����ǽ�һ������Ϊ��console_init����action���ӵ���action_queue�б��У���ˣ����������ѭ���У����action�ͻᱻִ�У�������console_init_action�ᱻ���á�

B. ���ú���restart_processes�����ϵͳ���Ƿ��н�����Ҫ�������������ű�/init.rc�У����ǿ���ָ��һ���������˳�֮����Զ���������������������£�����restart_processes�ͻ����Ƿ������Ҫ���������Ľ��̣�������ڵĻ�����ô�ͻὫ����������������

C. ����ϵͳ���Ա仯�¼��������ǵ��ú���property_set���ı�һ��ϵͳ����ֵʱ��ϵͳ�ͻ�ͨ��һ��socket��ͨ�����ú���get_property_set_fd���Ի�������ļ�������������init���̷���һ������ֵ�ı��¼�֪ͨ��init���̽��յ��������ֵ�ı��¼�֮�󣬾ͻ���ú���handle_property_set_fd��������Ӧ�Ĵ����������ڷ��������������������ʾ����ʱ�����Ǿͻῴ����SurfaceFlinger�������ͨ���޸ġ�ctl.start���͡�ctl.stop������ֵ��������ֹͣ��������������ġ�

D. ����һ�ֳ�Ϊ��chorded keyboard���ļ��������¼�����������Ϊchorded keyboard���ļ����豸ͨ����ͬ��識������������ͬ��������߲���������Ӧ���豸�ļ�Ϊ/dev/keychord�����ǿ���ͨ�����ú���get_keychord_fd���������豸���ļ����������Ա���Լ�����������¼������ҵ��ú���handle_keychord������Щ�����¼����д�����

E. ���ս�ʬ���̡�����֪������Linux�ں��У���������̲��ȴ��ӽ��̽������˳�����ô���ӽ��̽�����ʱ�򣬾ͻ���һ����ʬ���̣��Ӷ�ռ��ϵͳ����Դ��Ϊ�˻�����Щ��ʬ���̣�init���̻ᰲװһ��SIGCHLD�źŽ�����������Щ�������Ѿ��˳��˵��ӽ����˳���ʱ���ں˾ͻᷢ��һ��SIGCHLD�źŸ�init���̡�init���̿���ͨ��һ��socket��ͨ�����ú���get_signal_fd���Ի�������ļ����������������յ���SIGCHLD�źŶ�ȡ���������ҵ��ú���handle_signal���Խ��յ���SIGCHLD�źŽ��д�������������Щ�Ѿ�����˽�ʬ���ӽ��̡�

ע�⣬���ں��������¼����ǿ���ͨ���ļ��������������ģ���ˣ�init���̵���ں���mainʹ��poll������ͬʱ��ѯ���ǣ��Ա�������Ч�ʡ�

���������Ǿ��ص��������console_init_action��ʵ�֣��Ա�����˽�ڶ��������������ʾ���̣�

  1. static int console_init_action(int nargs, char **args)
  2. {
  3. int fd;
  4. char tmp[PROP_VALUE_MAX];
  5. if (console[0]) {
  6. snprintf(tmp, sizeof(tmp), "/dev/%s", console);
  7. console_name = strdup(tmp);
  8. }
  9. fd = open(console_name, O_RDWR);
  10. if (fd >= 0)
  11. have_console = 1;
  12. close(fd);
  13. if( load_565rle_image(INIT_IMAGE_FILE) ) {
  14. fd = open("/dev/tty0", O_WRONLY);
  15. if (fd >= 0) {
  16. const char *msg;
  17. msg = "\n"
  18. "\n"
  19. "\n"
  20. "\n"
  21. "\n"
  22. "\n"
  23. "\n" // console is 40 cols x 30 lines
  24. "\n"
  25. "\n"
  26. "\n"
  27. "\n"
  28. "\n"
  29. "\n"
  30. "\n"
  31. " A N D R O I D ";
  32. write(fd, msg, strlen(msg));
  33. close(fd);
  34. }
  35. }
  36. return 0;
  37. }
static int console_init_action(int nargs, char **args) { int fd; char tmp[PROP_VALUE_MAX]; if (console[0]) { snprintf(tmp, sizeof(tmp), "/dev/%s", console); console_name = strdup(tmp); } fd = open(console_name, O_RDWR); if (fd >= 0) have_console = 1; close(fd); if( load_565rle_image(INIT_IMAGE_FILE) ) { fd = open("/dev/tty0", O_WRONLY); if (fd >= 0) { const char *msg; msg = "\n" "\n" "\n" "\n" "\n" "\n" "\n" // console is 40 cols x 30 lines "\n" "\n" "\n" "\n" "\n" "\n" "\n" " A N D R O I D "; write(fd, msg, strlen(msg)); close(fd); } } return 0; }���������Ҫ���������¼���

A. ��ʼ������̨��init������������ʱ�򣬻�����ں˵������������������ļ�/proc/cmdline�У�����������ں˵����������а�������һ������Ϊ��androidboot.console�������ԣ���ô�ͻὫ������Ե�ֵ�������ַ�����console�С��������ǾͿ���ͨ���豸�ļ�/dev/������ϵͳ�Ŀ���̨������ں˵���������û�а�������Ϊ��androidboot.console�������ԣ���ôĬ�Ͼ�ͨ���豸�ļ�/dev/console������ϵͳ�Ŀ���̨������ܹ��ɹ��ش��豸�ļ�/dev/����/dev/console����ô��˵��ϵͳ֧�ַ��ʿ���̨����ˣ�ȫ�ֱ���have_console�ľͻᱻ����Ϊ1��

B. ��ʾ�ڶ����������档��ʾ�ڶ�������������ͨ�����ú���load_565rle_image��ʵ�ֵġ��ڵ��ú���load_565rle_image��ʱ��ָ���Ŀ��������ļ�ΪINIT_IMAGE_FILE��INIT_IMAGE_FILE��һ���꣬������system/core/init/init.h�ļ��У�������ʾ��

  1. #define INIT_IMAGE_FILE "/initlogo.rle"
#define INIT_IMAGE_FILE "/initlogo.rle"
���ڶ���������������������ļ�/initlogo.rle��ָ���ġ�����ļ�/initlogo.rle�����ڣ���������ʾ���Ĺ����г����쳣����ô����load_565rle_image�ķ���ֵ�ͻ����-1����ʱ����console_init_action�����ı��ķ�ʽ����ʾ�ڶ����������棬������Ϊ0�Ŀ���̨��/dev/tty0�������ANDROID����7���ַ���

����load_565rle_imageʵ�����ļ�system/core/init/logo.c�У�������ʾ��

  1. /* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
  2. int load_565rle_image(char *fn)
  3. {
  4. struct FB fb;
  5. struct stat s;
  6. unsigned short *data, *bits, *ptr;
  7. unsigned count, max;
  8. int fd;
  9. if (vt_set_mode(1))
  10. return -1;
  11. fd = open(fn, O_RDONLY);
  12. if (fd < 0) {
  13. ERROR("cannot open '%s'\n", fn);
  14. goto fail_restore_text;
  15. }
  16. if (fstat(fd, &s) < 0) {
  17. goto fail_close_file;
  18. }
  19. data = mmap(0, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
  20. if (data == MAP_FAILED)
  21. goto fail_close_file;
  22. if (fb_open(&fb))
  23. goto fail_unmap_data;
  24. max = fb_width(&fb) * fb_height(&fb);
  25. ptr = data;
  26. count = s.st_size;
  27. bits = fb.bits;
  28. while (count > 3) {
  29. unsigned n = ptr[0];
  30. if (n > max)
  31. break;
  32. android_memset16(bits, ptr[1], n << 1);
  33. bits += n;
  34. max -= n;
  35. ptr += 2;
  36. count -= 4;
  37. }
  38. munmap(data, s.st_size);
  39. fb_update(&fb);
  40. fb_close(&fb);
  41. close(fd);
  42. unlink(fn);
  43. return 0;
  44. fail_unmap_data:
  45. munmap(data, s.st_size);
  46. fail_close_file:
  47. close(fd);
  48. fail_restore_text:
  49. vt_set_mode(0);
  50. return -1;
  51. }
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ int load_565rle_image(char *fn) { struct FB fb; struct stat s; unsigned short *data, *bits, *ptr; unsigned count, max; int fd; if (vt_set_mode(1)) return -1; fd = open(fn, O_RDONLY); if (fd < 0) { ERROR("cannot open '%s'\n", fn); goto fail_restore_text; } if (fstat(fd, &s) < 0) { goto fail_close_file; } data = mmap(0, s.st_size, PROT_READ, MAP_SHARED, fd, 0); if (data == MAP_FAILED) goto fail_close_file; if (fb_open(&fb)) goto fail_unmap_data; max = fb_width(&fb) * fb_height(&fb); ptr = data; count = s.st_size; bits = fb.bits; while (count > 3) { unsigned n = ptr[0]; if (n > max) break; android_memset16(bits, ptr[1], n << 1); bits += n; max -= n; ptr += 2; count -= 4; } munmap(data, s.st_size); fb_update(&fb); fb_close(&fb); close(fd); unlink(fn); return 0; fail_unmap_data: munmap(data, s.st_size); fail_close_file: close(fd); fail_restore_text: vt_set_mode(0); return -1; }

�������Ƚ�����̨����ʾ��ʽ����Ϊͼ�η�ʽ������ͨ�����ú���vt_set_mode��ʵ�ֵģ�������ʾ��

  1. static int vt_set_mode(int graphics)
  2. {
  3. int fd, r;
  4. fd = open("/dev/tty0", O_RDWR | O_SYNC);
  5. if (fd < 0)
  6. return -1;
  7. r = ioctl(fd, KDSETMODE, (void*) (graphics ? KD_GRAPHICS : KD_TEXT));
  8. close(fd);
  9. return r;
  10. }
static int vt_set_mode(int graphics) { int fd, r; fd = open("/dev/tty0", O_RDWR | O_SYNC); if (fd < 0) return -1; r = ioctl(fd, KDSETMODE, (void*) (graphics ? KD_GRAPHICS : KD_TEXT)); close(fd); return r; }����vt_set_mode���ȴ򿪿���̨�豸�ļ�/dev/tty0��������ͨ��IO��������KDSETMODE��������̨����ʾ��ʽ����Ϊ�ı���ʽ����ͼ�η�ʽ��ȡ���ڲ���graphics��ֵ����ǰ��ĵ��ù��̿���֪��������graphics��ֵ����1����ˣ������ǽ�����̨����ʾ��ʽ�豸Ϊͼ�η�ʽ��

�ص�����load_565rle_image�У���ǰ��ĵ��ù��̿���֪��������fn��ֵ���ڡ�/initlogo.rle������ָ��Ŀ���豸�ϵ�initlogo.rle�ļ�������load_565rle_image���ȵ��ú���open������ļ������ҽ���õ��ļ������������ڱ���fd�У������ٵ��ú���fstat���������ļ��Ĵ�С��������Щ��Ϣ֮�󣬺���load_565rle_image�Ϳ��Ե��ú���mmap�����ļ�/initlogo.rleӳ�䵽init���̵ĵ�ַ�ռ����ˣ��Ա���Զ�ȡ�������ݡ�

���ļ�/initlogo.rleӳ�䵽init���̵ĵ�ַ�ռ�֮�󣬽������ٵ��ú���fb_open�����豸�ļ�/dev/graphics/fb0��ǰ���ڽ��ܵ�һ�������������ʾ�������ᵽ���豸�ļ�/dev/graphics/fb0����������ϵͳ��֡������Ӳ���豸�ģ���ˣ������豸�ļ�/dev/graphics/fb0֮�����ǾͿ��Խ��ļ�/initlogo.rle�����������֡������Ӳ���豸��ȥ�ˡ�

����fb_open��ʵ��������ʾ��

  1. static int fb_open(struct FB *fb)
  2. {
  3. fb->fd = open("/dev/graphics/fb0", O_RDWR);
  4. if (fb->fd < 0)
  5. return -1;
  6. if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->fi) < 0)
  7. goto fail;
  8. if (ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vi) < 0)
  9. goto fail;
  10. fb->bits = mmap(0, fb_size(fb), PROT_READ | PROT_WRITE,
  11. MAP_SHARED, fb->fd, 0);
  12. if (fb->bits == MAP_FAILED)
  13. goto fail;
  14. return 0;
  15. fail:
  16. close(fb->fd);
  17. return -1;
  18. }
static int fb_open(struct FB *fb) { fb->fd = open("/dev/graphics/fb0", O_RDWR); if (fb->fd < 0) return -1; if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->fi) < 0) goto fail; if (ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vi) < 0) goto fail; fb->bits = mmap(0, fb_size(fb), PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0); if (fb->bits == MAP_FAILED) goto fail; return 0; fail: close(fb->fd); return -1; }�����豸�ļ�/dev/graphics/fb0֮�󣬽����ٷֱ�ͨ��IO��������FBIOGET_FSCREENINFO��FBIOGET_VSCREENINFO�����֡����Ӳ���豸�Ĺ̶���Ϣ�Ϳɱ���Ϣ���̶���Ϣʹ��һ��fb_fix_screeninfo�ṹ�������������������֡������Ӳ���豸���е����ԣ���Щ������֡������Ӳ���豸����ʼ����֮�󣬾Ͳ��ᷢ���ı䣬������Ļ��С�Լ�������ַ����Ϣ���ɱ���Ϣʹ��һ��fb_var_screeninfo�ṹ�������������������֡������Ӳ���豸�ɱ�����ԣ���Щ������ϵͳ���е��ڼ��ǿ��Ըı�ģ�������Ļ��ʹ�õķֱ��ʡ���ɫ����Լ���ɫ��ʽ�ȡ�

���˻��֡������Ӳ���豸�Ĺ̶���Ϣ�Ϳɱ���Ϣ֮�⣬����fb_open���Ὣ�豸�ļ�/dev/graphics/fb0������ӳ�䵽init���̵ĵ�ַ�ռ���������init���̾Ϳ���ͨ��ӳ��õ��������ַ������֡������Ӳ���豸�������ˡ�

�ص�����load_565rle_image�У��������ֱ�ʹ�ú�fb_width��fb_height�������Ļ��ʹ�õĵķֱ��ʣ�����Ļ�Ŀ��Ⱥ͸߶ȡ���fb_width��fb_height�Ķ���������ʾ��

  1. #define fb_width(fb) ((fb)->vi.xres)
  2. #define fb_height(fb) ((fb)->vi.yres)
#define fb_width(fb) ((fb)->vi.xres) #define fb_height(fb) ((fb)->vi.yres)��Ļ����ʹ�õķֱ���ʹ�ýṹ��fb_var_screeninfo�ij�Ա����xres��yres�����������У���Ա����xres����������Ļ�Ŀ��ȣ�����Ա������Ա����yres����������Ļ�ĸ߶ȡ��õ�����Ļ�ķֱ���֮�󣬾Ϳ���֪����������֡������Ӳ���豸д����ֽ����Ĵ�С�ˣ������С�͵�����Ļ�Ŀ��ȳ��Ը߶ȣ������ڱ���max�С�

�������Ƿֱ�õ����ļ�initlogo.rle��֡������Ӳ���豸��init�����е�������ʵ�ַ�Լ���С���������ǾͿ��Խ��ļ�initlogo.rle������д�뵽֡������Ӳ���豸��ȥ���Ա���Խ��ڶ�������������ʾ����������ͨ������load_565rle_image�е�whileѭ����ʵ�ֵġ�

�ļ�initlogo.rle����ĵڶ������������ͼ���ʽ��565rle�ġ�rle��ȫ����run-length encoding������Ϊ�γ̱�������г̳��ȱ��룬������ʹ��4���ֽ�������һ�������ľ�����ͬ��ɫֵ�����С���rle565��ʽ��ǰ��2���ֽ��������������еĸ�����������2���ֽ���������һ���������ɫ�����У���ɫ��RGBֵ�ֱ�ռ5λ��6λ��5λ��������565rleͼ���ʽ֮�����ǾͿ������⺯��load_565rle_image�е�whileѭ����ʵ���߼��ˡ���ÿһ��ѭ���У��������δ��ļ�initlogo.rle�ж���4���ֽڣ����У�ǰ�����ֽڵ����ݱ����ڱ���n�У�������2���ֽڵ���������д�뵽֡������Ӳ���豸��ȥ������2���ֽڸպþͿ���ʹ��һ���޷��Ŷ���������������ˣ�����load_565rle_imageͨ�����ú���android_memset16�������ļ�initlogo.rle�ж�ȡ��������ɫֵд�뵽֡������Ӳ���豸��ȥ��

����android_memset16��ʵ��������ʾ��

  1. void android_memset16(void *_ptr, unsigned short val, unsigned count)
  2. {
  3. unsigned short *ptr = _ptr;
  4. count >>= 1;
  5. while(count--)
  6. *ptr++ = val;
  7. }
void android_memset16(void *_ptr, unsigned short val, unsigned count) { unsigned short *ptr = _ptr; count >>= 1; while(count--) *ptr++ = val; }����ptrָ��д��ĵ�ַ����������������У������ַ��Ϊ֡������Ӳ���豸ӳ�䵽init�����е������ֵַ��

����val����������д���ֵ����������������У����ֵ��Ϊ���ļ�initlogo.rle�ж�ȡ��������ɫֵ��

����count����������д��ĵ�ַ�ij��ȣ��������ֽ�Ϊ��λ�ġ������ڽ�����val��ֵд�뵽����ptr�������ĵ�ַ��ȥʱ�������޷��Ŷ�����Ϊ��λ�ģ�������2���ֽ�Ϊ��λ�ģ���ˣ�����android_memset16�ڽ�����valд�뵽��ַptr��ȥ֮ǰ�����ȻὫ����count��ֵ����2����Ӧ�ĵأ��ں���load_565rle_image�У���Ҫ��������ͬ��ɫֵ�����еĸ�������2֮���ٵ��ú���android_memset16��

�ص�����load_565rle_image�У����ļ�/initlogo.rle������д�뵽֡������Ӳ���豸ȥ֮�󣬵ڶ�����������Ϳ�����ʾ�����ˡ�����������load_565rle_image�ͻ���ú���munmap��ע���ļ�/initlogo.rle��init�����е�ӳ�䣬���ҵ��ú���close���ر��ļ�/initlogo.rle���ر����ļ�/initlogo.rle֮�󣬻�����ú���unlink��ɾ��Ŀ���豸�ϵ�/initlogo.rle�ļ���ע�⣬��ֻ��ɾ����Ŀ���豸�ϵ�/initlogo.rle�ļ���������ɾ��ramdiskӳ���е�initlogo.rle�ļ�����ˣ�ÿ�ιػ�����֮��ϵͳ�������½�ramdiskӳ���е�initlogo.rle�ļ���װ��Ŀ���豸�ϵĸ�Ŀ¼���������Ϳ�����ÿ�ο�����ʱ���ܽ�����ʾ������

������Ҫע���ļ�/initlogo.rle��init�����е�ӳ��͹ر��ļ�/initlogo.rle֮�⣬����Ҫע���ļ�/dev/graphics/fb0��init�����е�ӳ���Լ��ر��ļ�/dev/graphics/fb0������ͨ������fb_close������ʵ�ֵģ�������ʾ��

  1. static void fb_close(struct FB *fb)
  2. {
  3. munmap(fb->bits, fb_size(fb));
  4. close(fb->fd);
  5. }
static void fb_close(struct FB *fb) { munmap(fb->bits, fb_size(fb)); close(fb->fd); }�ڵ���fb_close����֮ǰ������load_565rle_image�����������һ������fb_update��������Ļ�ϵĵڶ����������棬����ʵ��������ʾ��

  1. static void fb_update(struct FB *fb)
  2. {
  3. fb->vi.yoffset = 1;
  4. ioctl(fb->fd, FBIOPUT_VSCREENINFO, &fb->vi);
  5. fb->vi.yoffset = 0;
  6. ioctl(fb->fd, FBIOPUT_VSCREENINFO, &fb->vi);
  7. }
static void fb_update(struct FB *fb) { fb->vi.yoffset = 1; ioctl(fb->fd, FBIOPUT_VSCREENINFO, &fb->vi); fb->vi.yoffset = 0; ioctl(fb->fd, FBIOPUT_VSCREENINFO, &fb->vi); }�ڽṹ��fb_var_screeninfo�У�����ʹ�ó�Ա����xres��yres��������Ļ��ʹ�õķֱ���֮�⣬��ʹ�ó�Ա����xres_virtual��yres_virtual��������Ļ��ʹ�õ�����ֱ��ʡ���Ա����xres��yres��������Ļ�ķֱ��ʳ�Ϊ���ӷֱ��ʡ����ӷֱ��ʺ�����ֱ�����ʲô��ϵ�أ����ӷֱ�������Ļʵ����ʹ�õķֱ��ʣ����û��������ķֱ��ʣ�������ֱ�������ϵͳ�ڲ�ʹ�õģ����Dz��ɼ��ģ����ҿ��Դ��ڿ��ӷֱ��ʡ����磬������ӷֱ�����800 x 600����ô����ֱ��ʿ�������Ϊ1600 x 600��������Ļ���ֻ������ʾ800 x 600�����أ���ˣ���ϵͳ�ڲ�������Ҫ������1600 x 600��ȡ��800 x 600����������ʾ������ͨ���ṹ��fb_var_screeninfo�ij�Ա����xoffset��yoffset��ֵ�������ġ���Ա����xoffset��yoffset��Ĭ��ֵ����0����Ĭ�ϴ�����ֱ��ʵ����Ͻ�ȡ������ӷֱ��ʴ�С��ȵ����س�����ʾ������Ļ����ͻ���ݳ�Ա����xoffset��yoffset��ֵ��������ֱ��ʵ��м�λ��ȡ������ӷֱ��ʴ�С��ȵ����س�����ʾ��

֡�������Ĵ�С��������ֱ��ʾ����ģ���ˣ����ǾͿ�����֡������д�����Ļ��С��Ҫ�������ֵ��������������������ֵ�Ϳ�������˫���塣������Ȼ������ӷֱ��ʺ�����ֱ��ʷֱ���800 x 600��1600 x 600����ô���ǾͿ����Ƚ�ǰһ��ͼ�������д�뵽֡��������ǰ��800 x 600��������ȥ�������ٽ���һ��ͼ�������д�뵽֡�������ĺ���800 x 600�������С�ͨ���ֱ���������֡������Ӳ���豸��fb_var_screeninfo�ṹ��ij�Ա����yoffset��ֵ����Ϊ0��800���Ϳ���ƽ������ʾ����ͼ��

������֡������Ӳ���豸�Ŀ��ӷֱ��Ժ�����ֱ���֮�󣬺���fb_update��ʵ���߼��Ϳ��Ժܺõ������ˡ�

���ˣ��ڶ��������������ʾ���̾ͷ�������ˡ�

3. �����������������ʾ����

������������������Ӧ�ó���bootanimation��������ʾ�ġ�Ӧ�ó���bootanimation�������ű�init.rc�б����ó���һ������������ʾ��

  1. service bootanim /system/bin/bootanimation
  2. user graphics
  3. group graphics
  4. disabled
  5. oneshot
service bootanim /system/bin/bootanimation user graphics group graphics disabled oneshotӦ�ó���bootanimation���û����û������Ʒֱ�����Ϊgraphics��ע�⣬ ��������Ӧ�ó���bootanimation�ķ�����disable�ģ���init������������ʱ�򣬲���������Ӧ�ó���bootanimation������������SurfaceFlinger����������ʱ������ͨ���޸�ϵͳ����ctl.start��ֵ��֪ͨinit��������Ӧ�ó���bootanimation���Ա������ʾ�������������棬����System���̽�ϵͳ�еĹؼ�������������֮��ActivityManagerService����ͻ�֪ͨSurfaceFlinger�������޸�ϵͳ����ctl.stop��ֵ���Ա����֪ͨinit����ִֹͣ��Ӧ�ó���bootanimation����ֹͣ��ʾ�������������档���������Ǿͷֱ���������������������ʾ���̺�ֹͣ���̡�

��ǰ��Androidϵͳ����Zygote�������̵�Դ�������һ�Ŀ���֪����Zygote�����������Ĺ����У��ὫSystem������������������ǰ��AndroidӦ�ó���װ����Դ�������һ���ֿ���֪����System�����������Ĺ��̣�Step 3���У������SurfaceFlinger��ľ�̬��Ա����instantiate������SurfaceFlinger����Sytem����������SurfaceFlinger����Ĺ����У����Ȼᴴ��һ��SurfaceFlingerʵ����Ȼ���ٽ����ʵ��ע�ᵽService Manager��ȥ����ע��Ĺ��̣�ǰ�洴����SurfaceFlingerʵ���ᱻһ��spָ�����á���ǰ��Androidϵͳ������ָ�루������ָ�롢ǿָ�����ָ�룩��ʵ��ԭ������һ������֪������һ�������һ�α�����ָ�����õ�ʱ���������ij�Ա����onFirstRef�ͻᱻ���á�����SurfaceFlinger��д�˸���RefBase�ij�Ա����onFirstRef����ˣ���ע��SurfaceFlinger����Ĺ����У��������SurfaceFlinger��ij�Ա����onFirstRef���ڵ��õĹ��̣��ͻᴴ��һ���߳��������������������档

SurfaceFlinger��ʵ�����ļ�frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp �У����ij�Ա����onFirstRef��ʵ��������ʾ��

  1. void SurfaceFlinger::onFirstRef()
  2. {
  3. run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
  4. // Wait for the main thread to be done with its initialization
  5. mReadyToRunBarrier.wait();
  6. }
void SurfaceFlinger::onFirstRef() { run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); // Wait for the main thread to be done with its initialization mReadyToRunBarrier.wait(); }SurfaceFlinger��̳���Thread�࣬�����ij�Ա����run�����õ�ʱ��ϵͳ�ͻᴴ��һ���µ��̡߳�����߳��ڵ�һ������֮ǰ�������SurfaceFlinger��ij�Ա����readyToRun��֪ͨSurfaceFlinger����׼�������ˡ�������߳�׼������֮�����ͻ�ѭ��ִ��SurfaceFlinger��ij�Ա����threadLoop��ֱ�������Ա�����ķ���ֵ����falseΪֹ��

ע�⣬SurfaceFlinger��ij�Ա����onFirstRef����System���̵����߳��е��õģ�����Ҫ�ȴ�ǰ�洴�����߳�׼������֮���ټ�����ǰִ�У����ͨ������SurfaceFlinger��ij�Ա����mReadytoRunBarrier��������һ��Barrier����ij�Ա����wait��ʵ�ֵġ�ÿһ��Barrier�������ʶ���װ��һ������������Condition Variable��������������������ͬ���̵߳ġ�

�����������Ǽ�������SurfaceFlinger��ij�Ա����readyToRun��ʵ�֣�������ʾ��

  1. status_t SurfaceFlinger::readyToRun()
  2. {
  3. LOGI( "SurfaceFlinger's main thread ready to run. "
  4. "Initializing graphics H/W...");
  5. ......
  6. mReadyToRunBarrier.open();
  7. /*
  8. * We're now ready to accept clients...
  9. */
  10. // start boot animation
  11. property_set("ctl.start", "bootanim");
  12. return NO_ERROR;
  13. }
status_t SurfaceFlinger::readyToRun() { LOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); ...... mReadyToRunBarrier.open(); /* * We're now ready to accept clients... */ // start boot animation property_set("ctl.start", "bootanim"); return NO_ERROR; }
ǰ�洴�����߳�����SurfaceFlinger�����̡߳�����߳���������ʱ�򣬻���豸����Ļ�Լ�OpenGL����г�ʼ������ʼ�����֮�󣬽��žͻ����SurfaceFlinger��ij�Ա����mReadyToRunBarrier��������һ��Barrier����ij�Ա����open������System���̵����̣߳��Ա������Լ�����ǰִ�С����SurfaceFlinger��ij�Ա����readyToRun�ij�Ա��������ú���property_set����ϵͳ���ԡ�ctl.start����ֵ����Ϊ��bootanim������ʾҪ��Ӧ�ó���bootanimation�����������Ա������ʾ�������������档

 

������������

 

����ת�ԣ�http://blog.csdn.net/luoshengyang/article/details/7691321

 

��������
��������(2)
������  ������  2015-2-16 23:34:37
���������£�������и�ɻ�. ������
�������  ������  2015-7-1 11:14:01
�����£�����һ���Ѫ.��ֹ����Ϣ��nolinkok@163.com ������� http://www.hbbuxiugangwang.com/
���� *
�������� *
��֤�� *ͼƬ�����壿������µõ���֤��