LinuxのSimpleFBをクリスマスカラーにした(かった)
これはクリスマスワンナイトハッカソンの作品紹介記事です。
先に宣言しておきます。
間に合いませんでした!!!!!!!!
(というより、正常に動きませんでした)
やりたかったことを書いておきます。
概要
Linuxで(たぶん)もっとも単純な画面表示ドライバは、simplefbと呼ばれるものです。これはフレームバッファと呼ばれる、直接画面へ表示される画像データが格納されているメモリ領域に直接画像を書き込むことで画面を表示するものです。GPU専用のドライバがなくても動作するので何かと便利です。
改造も比較的簡単そうだったので、このsimplefbで表示される黒以外のピクセルを赤と緑にして、コンソールをクリスマスカラーにしてやろうと考えたわけです。
結果これが
...どうしてこうなった? 寝ぼけてて単純なミスをしているのかもしれませんが、パッチはこんな感じです。
diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c
index a2bb276a8b24..7aa9c07b2a21 100644
--- a/drivers/video/fbdev/core/cfbimgblt.c
+++ b/drivers/video/fbdev/core/cfbimgblt.c
@@ -269,6 +269,7 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
u32 width = image->width;
u32 dx = image->dx, dy = image->dy;
u8 __iomem *dst1;
+ u64 x, y;
if (p->state != FBINFO_STATE_RUNNING)
return;
@@ -294,13 +295,21 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
bgcolor = image->bg_color;
}
- if (32 % bpp == 0 && !start_index && !pitch_index &&
- ((width & (32/bpp-1)) == 0) &&
- bpp >= 8 && bpp <= 32)
- fast_imageblit(image, p, dst1, fgcolor, bgcolor);
- else
- slow_imageblit(image, p, dst1, fgcolor, bgcolor,
- start_index, pitch_index);
+ for (y = 0; y < (u64)(image->height); y++) {
+ for (x = 0; x < (u64)(image->width); x++) {
+ u32 c_color = (((image->dx + x) / 40) % 2 == 0) ? 0x00ff0000 : 0x0000ff00;
+
+ u64 index = y * image->width + x;
+ u32 color = image->data[index] == 0 ? bgcolor : c_color;
+
+ u64 ptr = (u64)(p->screen_base);
+ ptr += (u64)(p->fix.line_length) * (u64)((u64)(image->dy) + y);
+ ptr += (bpp/8) * (u64)((u64)(image->dx) + x);
+
+ *((u32 *)(ptr)) = color;
+ FB_WRITEL(color, (u32 *)ptr);
+ }
+ }
} else
color_imageblit(image, p, dst1, start_index, pitch_index);
}
しつこいぐらいキャストしてたり、タブ文字インデントをスペースインデントにしちゃってたり、コードがクッソ汚いのは許してください...。あとVirtualBox上で動作させることしか考えてなかったので、これは実は環境によって挙動が変わるコードです() どなたかバグの原因がわかる方がいたら教えてください。
気が向いたら再挑戦しようと思います。ハッカソンお疲れ様でした。
これをやるためにLinuxカーネルのフルビルドを2回、差分ビルドを30回はやったので、だいぶSSDの寿命が縮んだような気がします。

