分类: LINUX
2008-10-02 23:52:24
GRUB的splashimage补丁分析
By tbfly
|
由于前面网友已经分析了GRUB的其它方面。本着不重复发明轮子的精神,本文主要分析splash补丁部分的代码。
不可避免的要参考经典链接:
其中splashimage指令的用法如下:
splashimage (hd0,0)/grub/images/debian_cooleye-dither.xpm.gz
指定splash image的路径及名称。
链接中详述了splashimage补丁的历史。大意是:Paulo César Pereira de Andrade最先写了这个补丁,给GRUB增加功能。但GRUB的上游代码维护者,不同意将splashimage patch加入到上游代码中。
所以,至今GRUB的代码中,关于splashimage的代码也默认不在其中。这个patch由各家发行版维护。
最早的发行版维护版本大概是:
~mcgrof/grub-images/patches/historic/redhat/grub-0.93-graphics.patch
本文基于的源码:grub4dos-0.4.4-2008-08-08,其中包含了spashimage补丁。对比了一下,也是基于上面链接的补丁发展而来。
这个patch主要在stage2目录增加了graphics.c文件。并在stage2/asm.S、stage2/builtins.c
等文件中添加graphics模式支持。
对menu.lst中的splashimage指令,解析的函数是:
builtin数据结构中的函数指针:splashimage_func。
splashimage_func先根据menu.list中的配置,读取splash图像的名字。
再通过asm.S中的set_videomode函数,设置视频显示模式。代码中默认,set_videomode函数中的AH=0,AL=0x12(640x480 16色图形EGA)。
再根据splash图像的名称,并解析XPM格式,读取splash图像内容和调试板。通过asm.S中的graphics_set_palette函数设置显示所用的调色板。
读取的图像内容先存放在物理地址:0x3A0000、0x3A9600、0x3B2C00和0x3BC200处,分别存放4字节中的低字节到高字节。
因为显示模式设置为:640x480 16bit,而VGA16显示模式,最小单元为8x16,所以可以显示的所有字符为80x30(HxW)。而图形为16色,所以图形所占空间大小为:80x30x16 = 38400 byte(即0x9600)。
显示的内存物理位置VIDEOMEM为:0xA0000。
最后,通过函数grub_memcpy把图像内容显示出来。
再通过asm.S中的graphics_get_font,显示8x16大小的字符。从而显示mean.lst中各启动选项。
光标选项的移动显示由graphics_cursor、graphics_setxy、graphics_scroll等函数实现。
上面一段,分析了splashimage的实现。该实现比较底层,目前限于VGA-16bit模式,基于framebuffer的splashimage实现目前还没看到。
splashimage是GRUB运行时,图形化的补丁。
实际上,Linux内核加载过程中,支持图形化显示的程序还很不少。其实现在Linux下有多种实现方式。总的可以分成两种:内核态与用户态。
内核态的实现方式:bootsplash,SLED就是采用这个方法。需要给内核打patch,用传统的__setup来处理内核参数splash等。Gentoo用uvesafb支持,打fbcondecor补丁支持fbsplash。
用户态的实现方式:usplash、splashy等。Ubuntu就采用这种方法,无需修改内核。用解析/proc/cmdline的方法处理内核参数splash等。Debian支持usplash也支持splashy。
参考链接:
2.
3.
4.
5.
6.
7.
8.