/********************************************************************************************
* author:conowen@大钟
* E-mail:conowen@hotmail.com
* http://blog.youkuaiyun.com/conowen
* 注:本文为原创,仅作为学习交流使用,转载请标明作者及出处。
********************************************************************************************/
1、修改Android的开关机铃声
待续……
2、修改Android开关机画面
开机画面包括三个过程
2.1、bootloader的开机画面
待续……
2.2、Android系统init时的开机画面
2.2.1、Android系统init时,装载initlogo.rle的简单流程。
Androidinit时,会读取 /initlogo.rle文件,如果读取成功,就会在/dev/graphics/fb0显示initlogo.rle;如果读取失败,打开/dev/tty0,输出文本“A N D R I O D”字样。
相关代码:
/system/core/init/init.c
/system/core/init/init.h
/system/core/init/init.rc
/system/core/init/logo.c
@/system/core/init/init.c
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) ) {//在init.h文件定义
//#define INIT_IMAGE_FILE "/initlogo.rle"
fd = open("/dev/tty0", O_WRONLY);
if (fd >= 0) {//如果找不到initlog.rle图片,则打开TEXT模式,
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 ";//打印ANDROID字样的问题。
write(fd, msg, strlen(msg));
close(fd);
}
}
return 0;
}
@/system/core/init/logo.c
static int fb_open(struct FB *fb)
{
fb->fd = open("/dev/graphics/fb0", O_RDWR);//会在/dev/graphics/fb0显示initlogo.rle
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;
}
/************部分省略****************/
/* 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;
}
2.2.2、修改方法:
2.2.2.1、找到一张符合机器分辨率的bmp图像,把bmp图片转换成为raw图像
要注意分辨率问题,若是不符合机器分辨率,可能显示拉伸或者花屏之类等等各种情况。
使用到的工具imagemagick,若没有,用apt安装即可。
convert -depth 8 initlog.bmp rgb:initlogo.raw
2.2.2.2、把raw图像转换为rle图像即可。
使用的工具rgb2565,编译Android系统源代码成功时,最红再编译SDK(执行make PRODUCT-sdk-sdk),编译SDK成功之后,在\out\host\linux-x86\bin生成rgb2565。然后在rgb2565目录下执行如下命令
./rgb2565 -rle < initlog.raw > initlogo.rle
2.2.2.3、替换文件
若是想在虚拟机上面测试,当系统编译完成之后,把initlogo.rle文件copy到\out\target\product\generic\root目录下,然后把\out\target\product\generic的ramdisk.img删除掉,再执行以下make命令,就可以生成新的ramdisk.img了,把ramdisk.img替代虚拟机镜像的ramdisk.img目录即可。因为root目录是ramdisk.img解包之后的文件夹,这一步只是把rle文件打包到ramdisk.img里面。
若是在一些机器的SDK修改开机画面,则可以到devices目录下的相应芯片厂商那里找找mk文件,然后编辑
如tcc892X是如下路径
\device\telechips\tcc8920st\device_base.mk
修改或者添加为
PRODUCT_COPY_FILES += \
device/telechips/common/initlogo_conowen.rle:root/initlogo.rle
事实上,这就是一个copy的过程,和之前的添加第三方apk没啥区别。
2.3、Android系统最后的开机动画(类似windows的进度条)
待续……
