在Android 5.0以前的版本,我们这里以Android4.4为例,它在Android4.4/system/core/init目录下存在logo.c文件,用于显示android第一阶段图片logo;而在Android 5.0以后版本中,我们这里以Android-5.0.2为例,在Android-5.0.2/system/core/init目录下根本不存在logo.c这个文件!我本人结合了网上的很多资料,进行了修改总结,但是还是出现了一些问题,就是不能显示!
Android启动阶段的logo显示过程如下面图片:
file:///C:\Users\dell\AppData\Local\Temp\ksohtml\wpsF472.tmp.png
先将我修改的过程总结如下:
1. 制作要显示的图片
使用PS制作一张和当前lcd分辨率相同的图片,保存时选“存储为 Web 所用格式”,然后在弹开的窗口上,“预设”项选择“PNG-24”,保存为android_logo.png。(图片名字可以随意,但必须是英文字母或数字组成)
2. 将图片转换为raw格式
使用linux下的ImageMagick自带的convert命令,进行raw格式转换,命令为:
convert -depth 8 android_logo.png rgb:android_logo.raw
如果当前系统没有安装该工具,可以执行下面的命令安装:
sudo apt-get install imagemagick
3. 将raw格式转化为rle文件
需要用到android-5.0.2编译后的rgb2565工具,该工具是在android-5.0.2/out/host/linux-x86/bin目录下(android-5.0.2为当前源码所在目录,如果没有的话,则再android-5.0.2/build/tools/rgb2565目录下进行编译 mmm build/tools/rgb2565 生成后在android-5.0.2/out/host/linux-x86/bin目录下 ),转换命令如下:
./rgb2565 -rle < android_logo.raw > initlogo.rle
至此,需要显示的图像已经做好了,即initlogo.rle。
4.将initlogo.rle拷贝到文件系统中
将initlogo.rle拷贝到/work/android-5.0.2/out/target/product/tiny4412/
root/下(与init.rc同目录)
到此Android第一阶段要显示的图片文件已经制作好并且拷贝到了指定的文件夹下。
5.在/work/android-5.0.2/system/core/init/目录下的init.h文件中增加下面两行:
#define INIT_IMAGE_FILE "/initlogo.rle"
int load_565rle_image( char *file_name );
6.在/work/android-5.0.2/system/core/init/目录下的init.c文件中console_init_action函数下修改为下面的内容:
static int console_init_action(int nargs, char **args)
{
int fd;
if (console[0]) {
snprintf(console_name, sizeof(console_name), "/dev/%s", console);
}
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;
}
7.将Android4.4/system/core/init目录下的logo.c文件拷贝到/work/android-5.0.2/system/core/init/目录下
8.修改/work/android-5.0.2/system/core/init/目录下的Android.mk文件,增加编译logo.c文件:
LOCAL_SRC_FILES:= \
builtins.c \
init.c \
devices.c \
property_service.c \
util.c \
parser.c \
logo.c \ //增加的编译文件
keychords.c \
signal_handler.c \
init_parser.c \
9.将/work/android-5.0.2/out/target/product/tiny4412/目录下的ramdisk.img和system.img文件删除掉并重新编译Android系统
. setenv --> lunch -->15 -->make -j4 -->./gen-img.sh
重新烧写ramdisk-u.img和system.img文件,重新启动系统发现kernel logo快结束时屏幕上出现要显示的logo,不过是花屏、不是全屏而且只是很短时间,就又是黑屏,过一段时间就是启动Android第四阶段图片动画了!还是没能解决这些问题!
后来又在网上查了部分资料:
第一种修改方法:
修改了/work/android-5.0.2/system/core/init/目录下的logo.c文件中的fb_open函数:
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);
/* add , reset fb format */
fb->vi.bits_per_pixel = 16;
fb->vi.yres_virtual=fb->vi.yres*2;
fb->vi.red.offset = 11;
fb->vi.red.length = 5;
fb->vi.green.offset = 5;
fb->vi.green.length = 6;
fb->vi.blue.offset = 0;
fb->vi.blue.length = 5;
fb->vi.transp.offset = 0;
fb->vi.transp.length = 0;
fb->vi.nonstd =4;
fb->vi.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
if(ioctl(fb->fd, FBIOPUT_VSCREENINFO, &fb->vi) < 0)
{
ERROR("Put screen info failed !!!");
goto fail;
}
/* end add */
if (fb->bits == MAP_FAILED)
goto fail;
return 0;
fail:
close(fb->fd);
return -1;
}
重新编译烧写结果就是:kernel logo显示完成后-->黑屏-->Android第四阶段图片动画;
也就说,Android第三阶段的logo就没有显示或者其他异常!
第二种修改方法:
也是修改/work/android-5.0.2/system/core/init/目录下的logo.c文件中
①#define fb_bpp(fb) ((fb)->vi.bits_per_pixel)//增加
//#define fb_size(fb) ((fb)->vi.xres * (fb)->vi.yres * 2)
#define fb_size(fb) ((fb)->vi.xres * (fb)->vi.yres * ((fb)->vi.bits_per_pixel / 8))
②增加下面代码
void convert_565rle_to_32(unsigned short val,unsigned short ** pbits,unsigned int *pn)
{
uint32_t rgb32, red, green, blue, alpha;
red = ((val >> 11) & 0x1F);
red = (red << 3) | (red >> 2);
green = ((val >> 5) & 0x3F);
green = (green << 2) | (green >> 4);
blue = ((val) & 0x1F);
blue = (blue << 3) | (blue >> 2);
alpha = 0xff;
rgb32 = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
android_memset32((uint32_t *)(*pbits), rgb32, (*pn) << 2);
*pbits += ((*pn) * 2);
}
③ 修改int load_565rle_image(char *fn)函数中的代码
去掉下面代码
//android_memset16(bits, ptr[1], n << 1);
//bits += n;
修改为:
if (fb_bpp(&fb) == 16) { //16位
android_memset16(bits, ptr[1], n << 1);
bits += n;
} else if(32 == fb_bpp(&fb)){ // 32位
convert_565rle_to_32(ptr[1],&bits,&n);
}
重新编译烧写结果就是:kernel logo显示完成后-->黑屏-->Android第四阶段图片动画;
也就说,Android第三阶段的logo就没有显示或者其他异常!
和第一种情况修改后效果是一致的,现象也是一样的!
总结:
通过移植和修改部分代码后,还是不能够实现Android第三阶段的图片logo显示:
不修改logo.c文件现象:
Kernel logo快结束时屏幕上出现要显示的logo,不过是花屏、不全屏而且只是很短时间,就又是黑屏,然后就是启动Android第四阶段图片动画
修改logo.c文件后的现象是:
kernel logo显示完成后-->黑屏-->Android第四阶段图片动画
(有可能是显示出来第三幅logo但是时间很短,只是我这里的图片和kernel logo一致,这一点我将继续进行验证)
希望有移植成功的大神们能告诉我一下,是怎么来解决这个问题的!
更正:经过更换Android第三张图片即与kernel logo中的图片不同,按照第一种方法测试后,发现Android第三幅logo可以全屏显示而且显示正常,只不过显示大概有1秒左右就黑屏了,然后过一段时间就进入Android第四阶段图片动画。现在需要解决的就是:从kernel logo显示结束就显示Android initlogo,一直显示到Android第四阶段图片动画就可以了!也就是一直显示Android 第三张图片直到Android第四阶段图片动画开始为止!