-1

私は最近、NetBSD 5.1.2(VESAフレームバッファ実装を使用)で使用しようとしwsconsましwsdisplayたが、少し問題が発生しました。

カラーマップを正常に設定でき、正しく表示されますが、カラーマップを取得すると、誤ったデータが返されるようです。たとえば、プログラムの終了後に元のカラーマップを復元しようとすると、すべての色が正しくありません。

Vim、プログラムのソースを奇妙なカラーマップで表示

root問題の原因となっている縮小プログラムを次に示します( 2番目の仮想端末(/dev/ttyE1)にログインしたユーザーとして、またはログインしたユーザーとして実行する必要があることに注意してください)。

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <dev/wscons/wsconsio.h>

int main(int argc, char **argv) {
    (void)argc, (void)argv;
    int tty = open("/dev/ttyE1", O_RDWR | O_EXCL);
    if(tty == -1) {
        perror("error opening tty");
        return EXIT_FAILURE;
    }
    struct wsdisplay_fbinfo fbinfo;
    if(ioctl(tty, WSDISPLAYIO_GINFO, &fbinfo) == -1) {
        perror("error retrieving framebuffer info");
        close(tty);
        return EXIT_FAILURE;
    }
    uint8_t *cmap_data = malloc(fbinfo.cmsize * 3);
    if(cmap_data == NULL) {
        perror("error allocating memory for color map data");
        close(tty);
        return EXIT_FAILURE;
    }
    struct wsdisplay_cmap cmap;
    cmap.index = 0;
    cmap.count = fbinfo.cmsize;
    cmap.red   = &cmap_data[fbinfo.cmsize * 0];
    cmap.green = &cmap_data[fbinfo.cmsize * 1];
    cmap.blue  = &cmap_data[fbinfo.cmsize * 2];
    if(ioctl(tty, WSDISPLAYIO_GETCMAP, &cmap) == -1) {
        perror("error getting color map");
        close(tty), free(cmap_data);
        return EXIT_FAILURE;
    }
    if(ioctl(tty, WSDISPLAYIO_PUTCMAP, &cmap) == -1) {
        perror("error putting color map");
        close(tty), free(cmap_data);
        return EXIT_FAILURE;
    }
    free(cmap_data);
    close(tty);
    return EXIT_SUCCESS;
}

何が間違っているのでしょうか。また、カラーマップを正しく取得して復元するにはどうすればよいですか。

4

1 に答える 1

0

原因

問題を詳しく調べたところ、一部のカーネルメモリが初期化されていないか、破損しているようです。具体的にsc_cmap_redは、、、sc_cmap_greenおよびsc_cmap_blueof struct vesafb_softcvesafbvar.h89行目から91行目)に誤ったデータが含まれています。vesafb.cこれは、初期化の719行目から722行目で、やや意外です。

/* Fill in the softc colourmap arrays */
sc->sc_cmap_red[i / 3] = rasops_cmap[i + 0];
sc->sc_cmap_green[i / 3] = rasops_cmap[i + 1];
sc->sc_cmap_blue[i / 3] = rasops_cmap[i + 2];

含まれているステートメントからデータを移動しても、誤ったデータが含まれているifため、初期化されていないのではなく、破損している可能性があります。

ただし、ドライバーカラーマップを正しく取得および設定できます。最初のものを正しく取得することはできないようですstruct vesafb_softc

回避策

簡単な解決策は、プログラムにデフォルトのカラーマップをリセットさせることです。上記のスニペットが示しているように、最初の色はから取得することになっrasops_cmapています。これは、次の行55〜122で定義されていますrasops.c

/* ANSI colormap (R,G,B). Upper 8 are high-intensity */
const u_char rasops_cmap[256*3] = {
    /* ... */
};

これらの色を使用して、それを現在のカラーマップとして設定するプログラムを作成できます。カーソルが消えないようにいくつかの変更を加える必要がありましたが、ほとんど機能しました。

より良い解決策

詳細を探していたところ、このブログ投稿を見つけました。genfb(4)ではなくカーネルを再コンパイルすると、カーネルがvesafb(4)起動時にハングしました。これは、私が使用していたブートローダーが、必要なパラメーターをカーネルに渡すのに十分なほど新しくなかったためであることがわかりました。

私はたまたまNetBSD6.0の変更ログを見て、このエントリに気づきました。

  • amd64i386
    ブートローダーは、VESABIOS拡張機能を使用するフレームバッファーコンソールをサポートするように拡張されました。これらの変更により、x86ポートがgenfb(4)ドライバーと連携できるようになり、i386のみのvesafb(4)ドライバーが廃止されます。[jmcneill 20090216]

NetBSD 6.0_BETAをダウンロードし、次のように起動プロンプトから起動しました。

> vesa 640x480x8
> boot netbsd

...そしてすべてがうまくいきました。

つまり、新しいバージョンのNetBSDを使用し、捨てるvesafb(4)ことで問題が解決します。

于 2012-04-01T00:25:22.040 に答える