1. 程式人生 > >更換核心logo

更換核心logo

apt-get install netpbm
拷貝png圖片到核心目錄的drivers/video/logo目錄下
pngtopnm wml.png > wml.pnm
pnmquant 224 wml.pnm > logo224.pnm
pnmtoplainpnm logo224.pnm > logo_linux_clut224.ppm
chmod 777 logo_linux_clut224.ppm
rm logo_linux_clut224.c logo_linux_clut224.o //這倆檔案是編譯核心的時候根據圖片生成的
重新編譯核心即可

呼叫關係梳理
fbcon.c
static const struct consw fb_con = {
.con_init = fbcon_init,
.con_switch = fbcon_switch,
}

fbcon.c
fbcon_init(struct vc_data *vc, int init)//fbcon.c
fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); //fbcon.c

fbcon.c
fbcon_switch(struct vc_data *vc) // fbcon.c
fb_show_logo(info, ops->rotate); // fbcon.c

#define update_screen(x) redraw_screen(x, 0) //vt_kern.h
#define switch_screen(x) redraw_screen(x, 1) //vt_kern.h
update_screen(vc);

//fbcon.c裡面很多地方有,但實際上被呼叫了兩次
redraw_screen(struct vc_data *vc, int is_switch) //vt.c
update = vc->vc_sw->con_switch(vc); //vt.c
fbcon_switch(struct vc_data *vc) // fbcon.c
fb_show_logo(info, ops->rotate); // fbcon.c

vt.c
do_bind_con_driver(const struct consw *csw, int first, int last,int deflt)
visual_init(vc, i, 0);
vc->vc_sw->con_init(vc, init);// fbcon_init
set_origin(vc);
update_attr(vc);

//final conclusion
module_init(fb_console_init);//fbcon.c
fb_console_init //fbcon.c
fb_register_client(&fbcon_event_notifier);//fbcon.c
fbcon_event_notify //fbcon.c
fbcon_fb_registered //fbcon.c
do_fbcon_takeover //fbcon.c
do_take_over_console //vt.c
do_register_con_driver
vtconsole_init_device
do_bind_con_driver(csw, first, last, deflt);//vt.c
vc->vc_sw->con_deinit(vc);
visual_init(vc, i, 0);
vc->vc_sw->con_init(vc, init);// fbcon_init fbcon.c
fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);//fbcon.c
fb_prepare_logo(info, ops->rotate); //fbcon.c
set_origin(vc);
update_attr(vc);
update_screen(vc);
redraw_screen(struct vc_data *vc, int is_switch)
vc->vc_sw->con_switch(vc);// fbcon_switch fbcon.c
fb_show_logo(info, ops->rotate);//fbcon.c
fb_show_logo_line(info, rotate, fb_logo.logo, 0,1);//fbmem.c
fb_rotate_logo(info, logo_rotate, &image, rotate);
fb_rotate_logo_cw
fb_do_show_logo(info, &image, rotate, 1);

修改點記錄

  1. 系統啟動後預設是兩隻企鵝
    fb_show_logo
    y = fb_show_logo_line(info, rotate, fb_logo.logo, 0,num_online_cpus());
    呼叫原型是這樣的,列印的num_online_cpus的值是2;
    改成fb_show_logo_line(info, rotate, fb_logo.logo, 0,1);
    就只有一隻企鵝了,所以這裡企鵝的數量想代表的意思應該是晶片的核數
  2. fbcon_prepare_logo
    fb_prepare_logo(info, ops->rotate);
    fb_prepare_extra_logos(info, fb_logo.logo->height, yres); //這個函式的定義有兩個,經過跟蹤執行,發現實際會呼叫那個空的函式,不起作用,所以程式碼裡直接註釋掉這個函式的呼叫,這個函式是獲取圖片的高度,所以直接在fb_prepare_logo來寫了,fb_prepare_logo改寫部分如下:

在這裡插入圖片描述

3.fbcon_prepare_logo裡面有這麼一句
logo_height = fb_prepare_logo(info, ops->rotate);
經過測試,發現把logo_height改到592及以上,圖片就會顯示失敗
在後面執行到的fb_do_show_logo裡面,可以看到有
image->dy += image->height + 8;
這個高度被自動加了8,592+8=600,超過592就超出了螢幕的範圍了,導致失敗;
//這裡沒作修改,只是做一下注釋

4.在fbcon_prepare_logo函式裡面明明設定了rotate,但是好像沒有傳到fb_show_logo裡面,下週做進一步除錯:
在fbcon.c-> fbcon_prepare_logo裡面
新增ops->rotate=1;發現並不能起到作用
繼續往後追蹤程式碼發現,後面執行的fbcon_switch函式裡面又有將ops->rotate置值,於是將這段遮蔽掉,截圖如下
在這裡插入圖片描述

如果不在fbcon_prepare_logo裡面取設定rotate,直接在fbcon_switch裡面去設定rotate即可
在這裡插入圖片描述

5.現在圖片是旋轉過來了,問題是座標原點被從左上角改到右上角了,座標軸的方向也變了,現在來解決這個座標原點被改變了的問題,經過程式碼分析,發現不是座標原點的問題,而是在fb_rotate_logo函式裡面有
在這裡插入圖片描述
註釋掉最下面最兩句,就正常了

6.搞定了一張圖片的旋轉和位置放置,現在來除錯一張圖片的連續換位置:
fbmem.c的fb_show_logo_line函式修改如下
在這裡插入圖片描述
在這裡插入圖片描述
即可實現連續在不同位置顯示同一張圖片;這不是最終要的效果

7.現在來在一個位置顯示一張圖片後,擦除這張圖片,然後在另一個位置顯示蓋圖片:
在fbmem.c的fb_show_logo_line裡面
在這裡插入圖片描述
在這裡插入圖片描述
即可完成簡單動畫;
上述做的是一張圖片的核心動畫,由於核心動畫會用到的可能性不大,而且還會佔用開機時間,暫不研究多張圖片的組合動畫,需要的時候再去除錯