发布新日志

  • Ubuntu 10.10 framebuffer

    2011-02-11 16:11:38

    从9.10版本开始, 就没有menu.list了,以前的这些文件都是通过/etc/default/grub 生成, 不需要手动修改grub.cfg, 自己修改也未尝不可,嘿嘿。
    首先:   
         sudo apt-get install v86d

    1. 编辑/etc/default/grub

    GRUB_CMDLINE_LINUX_DEFAULT="vga=0x0369"
    GRUB_GFXMODE=1024x768



    2. 编辑 /etc/initramfs-tools/modules
    uvesafb mtrr=3 scroll=ywrap


    sudo update-grub2
    sudo update-initramfs -u
    sudo reboot


  • /usr/lib/libgconf2-4/gconf-sanity-check-2的退出状态为256

    2010-05-07 09:51:17

    /usr/lib/libgconf2-4/gconf-sanity-check-2的退出状态为256

    My OS kernel

    Linux licaijun 2.6.31-17-generic #54-Ubuntu SMP Thu Dec 10 16:20:31 UTC 2009 i686 GNU/Linux

    If its a GDM relates error then execute this

    sudo dpkg-reconfigure gdm


  • Evolution不能收发邮件

    2009-12-14 09:25:24

    Evolution不能收发邮件的解决办法

    打开Evolution一看,发现Evolution的“发送/接收”按钮是灰色无效的……

    终于找到了问题所在
    菜单“文件”——>联机工作,搞定!
    原来是电脑网络断了之后Evolution变成脱机工作了(类似火狐)
    改成联机就可以了
  • Live CD

    2009-11-20 16:15:12

     

       sudo apt-get install remastersys


      

    各命令大意如下:

        Backup : 备份完整的系统并包括个人资料.
        Dist : 生成一个可以与朋友分享的备份文件,其形式是ISO 和CDFS
        Distcdfs : 只生成系统的备份文件,对只加程序进安装CD的一种好方法.
        DistIso : 只生成一个ISO文件,在之前需完成上一步.
        Modify : 根据用户要求而修改remastersys配制.
        Info : 有关remastersys的信息.
        Clean : 清除临时文件.
        Quit : 退出
  • llinux iveCD 制作

    2009-11-18 11:07:23

    http://www.cherrysave.com/linux/build-your-own-custom-ubuntu-live-cd/


    https://www.privacy-cd.org/en/tutorials/build-your-own-cd/29?start=2
  • final link failed: Bad value

    2009-10-13 14:11:05

    移植程序的时候,老是报错mipsel-linux-ld: final link failed: Bad value

    查看你的Makefile是否有-Bsymbolic -function  只要把-Bsymbolic -function 去掉即可
  • X--tag=CXX: command not found 问题解决

    2009-08-14 15:30:56

    在编译代码的时候,由于我的os是ubuntu 9.04 比较新,所以libtool就出现问题了,这由于版本不兼容引起的,

    ../libtool: line 832: X--tag=CXX: command not found
    ../libtool: line 865: libtool: ignoring unknown tag : command not found
    ../libtool: line 832: X--mode=compile: command not found
    ../libtool: line 999: *** Warning: inferring the mode of operation is deprecated.: command not found
    ../libtool: line 1000: *** Future versions of Libtool will require --mode=MODE be specified.: command not found
    ../libtool: line 1143: Xg++: command not found
    ../libtool: line 1143: X-DHAVE_CONFIG_H: command not found
    ../libtool: line 1143: X-I.: command not found
    ../libtool: line 1143: X-I/home/seaboat/Desktop/hello/src: No such file or directory
    ../libtool: line 1143: X-I..: command not found
    ../libtool: line 1143: X-O0: command not found
    ../libtool: line 1143: X-g3: command not found
    ../libtool: line 1143: X-MT: command not found
    ../libtool: line 1143: Xhello.lo: command not found
    ../libtool: line 1143: X-MD: command not found
    ../libtool: line 1143: X-MP: command not found
    ../libtool: line 1143: X-MF: command not found
    ../libtool: line 1143: X.deps/hello.Tpo: No such file or directory
    ../libtool: line 1143: X-c: command not found
    ../libtool: line 1195: Xhello.lo: command not found
    ../libtool: line 1200: libtool: compile: cannot determine name of library object from `': command not found
    解决办法:

    1。 进入libtool,把所有小写的$echo替换成$ECHO。
    2。 卸载libtool,安装底版本的libtool,大概是1。5版本,去查下就行了

  • am__fastdepCXX does not appear in AM_CONDITIONAL

    2009-08-14 15:03:33


    ERROR LOG:
    licaijun@licaijun:~/workspace/minigui-test/mgeff/libmgeff$ ./autogen.sh
    /usr/share/automake-1.10/am/depend2.am: am__fastdepCXX does not appear in AM_CONDITIONAL
    /usr/share/automake-1.10/am/depend2.am:   The usual way to define `am__fastdepCXX' is to add `AC_PROG_CXX'
    /usr/share/automake-1.10/am/depend2.am:   to `configure.in' and run `aclocal' and `autoconf' again.
    src/Makefile.am: C++ source seen but `CXX' is undefined
    src/Makefile.am:   The usual way to define `CXX' is to add `AC_PROG_CXX'
    src/Makefile.am:   to `configure.in' and run `autoconf' again.


    fix this problem:

    Before libtool 2.2, as soon as a project started using the support provided by this package, checks for C++ and Fortran compilers were added. These checks, lengthy, and pointless for C-only projects, often caused grief to the point that many different hacks, using M4 directives, were used and suggested between different guides.

    With the new release series, this problem has been solved, LT_INIT now only checks for the actual compilers as declared by the project itself. While this works for most projects, there are a few where this caused further problems, and further grief.

    The problem appears evident when building packages written in C++ (but Fortran is mostly the same) that don't check for the proper compiler, since the automake execution will start reporting problems that “am__fastdepCXX does not appear in AM_CONDITIONAL”:

    % automake --add-missing --copy --foreign
    /usr/share/automake-1.10/am/depend2.am: am__fastdepCXX does not appear in AM_CONDITIONAL
    /usr/share/automake-1.10/am/depend2.am: The usual way to define `am__fastdepCXX' is to add `AC_PROG_CXX'
    /usr/share/automake-1.10/am/depend2.am: to `configure.ac' and run `aclocal' and `autoconf' again.
    cjeca32/Makefile.am: C++ source seen but `CXX' is undefined
    cjeca32/Makefile.am: The usual way to define `CXX' is to add `AC_PROG_CXX'
    cjeca32/Makefile.am: to `configure.ac' and run `autoconf' again.

    The main problem here is that the error (divided in two parts) is actually meaningful only in the second part, for most people, since the first three lines sound like gibberish for the common users.

    The second part of the error actually tells you exactly what to do: adding AC_PROG_CXX to configure.ac; even better, before the initialisation call.

    Example 4.1.  Properly Fix missing C++ support with libtool 2.2

    dnl configure.ac
    AC_INIT
    AM_INIT_AUTOMAKE

    dnl add this
    AC_PROG_CXX

    AC_PROG_LIBTOOL

    Please note here, that the function AC_PROG_LIBTOOL in this snipped is the deprecated 1.5-compatible form. of LT_INIT. Since the error shown above happens during porting to libtool 2.2, it's unlikely that the new form. is found. See ???.


  • 使用udhcpc 工具自动分配IP

    2009-07-30 17:48:13

    在嵌入式行业中,我们能够接触各种各样的开发板,但是这些开发板有时候需要上网,用静态ip配置起来太烦,还是使用动态获取.
       下面是动态获取IP的方法:
        用的最多就是busybox这个工具,这个工具可以生成udhcpc,一般的开发板都有undhcpc编译好的二进制文件,如果没有就需要自己交叉编译,不过也不是太难,修改一下Makefile的工具链位置即可.
        最主要的就是配置文件,有的开发版本可能指定的路径不一样,所以配置文件放的也不一样,大家根据提示信息吧!
        通常是放在/usr/share/udhcpc/下.
    附件是配置文件,解压到这个目录即可
  • WebCore::CSSParser::lex() 解决办法

    2009-03-02 17:16:42

    在编译Webkit的时候,大家可以遇到这样的WebCore::CSSParser::lex() ,这样的错误,基本上,我们安装flex bison就可以解决该问题,其实,有时候,并不是这样的,是因为系统可能缺少libelf 这个包,
  • ubuntu 7.10 源

    2008-12-28 20:58:15

    ubuntu7.10大学源一览表

    ubuntu7.10大学源一览表#传说中的中国科技大学 5M/s
    deb http://debian.ustc.edu.cn/ubuntu/ gutsy main restricted universe multiverse
    deb http://debian.ustc.edu.cn/ubuntu/ gutsy-backports restricted universe multiverse
    deb http://debian.ustc.edu.cn/ubuntu/ gutsy-proposed main restricted universe multiverse
    deb http://debian.ustc.edu.cn/ubuntu/ gutsy-security main restricted universe multiverse
    deb http://debian.ustc.edu.cn/ubuntu/ gutsy-updates main restricted universe multiverse
    deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy main restricted universe multiverse
    deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy-backports main restricted universe multiverse
    deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy-proposed main restricted universe multiverse
    deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy-security main restricted universe multiverse
    deb-src http://debian.ustc.edu.cn/ubuntu/ gutsy-updates main restricted universe multiverse

    #传说中的北京交大 速度 2M/s
    deb http://mirror.bjtu.edu.cn/ubuntu/ gutsy main restricted universe multiverse
    deb http://mirror.bjtu.edu.cn/ubuntu/ gutsy-updates main restricted universe multiverse
    deb http://mirror.bjtu.edu.cn/ubuntu/ gutsy-security main restricted universe multiverse
    deb http://mirror.bjtu.edu.cn/ubuntu/ gutsy-backports main restricted universe multiverse

    #传说中的上海交通大学,最热门的源之一
    deb http://ftp.sjtu.edu.cn/ubuntu/ gutsy main multiverse restricted universe
    deb http://ftp.sjtu.edu.cn/ubuntu/ gutsy-backports main multiverse restricted universe
    deb http://ftp.sjtu.edu.cn/ubuntu/ gutsy-proposed main multiverse restricted universe
    deb http://ftp.sjtu.edu.cn/ubuntu/ gutsy-security main multiverse restricted universe
    deb http://ftp.sjtu.edu.cn/ubuntu/ gutsy-updates main multiverse restricted universe
    deb http://ftp.sjtu.edu.cn/ubuntu-cn/ gutsy main multiverse restricted universe
    deb-src http://ftp.sjtu.edu.cn/ubuntu/ gutsy main multiverse restricted universe
    deb-src http://ftp.sjtu.edu.cn/ubuntu/ gutsy-backports main multiverse restricted universe
    deb-src http://ftp.sjtu.edu.cn/ubuntu/ gutsy-proposed main multiverse restricted universe
    deb-src http://ftp.sjtu.edu.cn/ubuntu/ gutsy-security main multiverse restricted universe
    deb-src http://ftp.sjtu.edu.cn/ubuntu/ gutsy-updates main multiverse restricted universe

    #传说中的清华大学ubuntu源 300k/s
    deb ftp://ftp3.tsinghua.edu.cn/mirror/ubuntu/ubuntu/ gutsy main restricted universe multiverse
    deb ftp://ftp3.tsinghua.edu.cn/mirror/ubuntu/ubuntu/ gutsy-security main restricted universe multiverse
    deb ftp://ftp3.tsinghua.edu.cn/mirror/ubuntu/ubuntu/ gutsy-updates main restricted universe multiverse

    #传说中的兰州大学 260k/s
    deb ftp://mirror.lzu.edu.cn/ubuntu/ gutsy main multiverse restricted universe
    deb ftp://mirror.lzu.edu.cn/ubuntu/ gutsy-backports main multiverse restricted universe
    deb ftp://mirror.lzu.edu.cn/ubuntu/ gutsy-proposed main multiverse restricted universe
    deb ftp://mirror.lzu.edu.cn/ubuntu/ gutsy-security main multiverse restricted universe
    deb ftp://mirror.lzu.edu.cn/ubuntu/ gutsy-updates main multiverse restricted universe
    deb ftp://mirror.lzu.edu.cn/ubuntu-cn/ gutsy main multiverse restricted universe

    #传说中的台湾大学 中国电信adsl 150k/s
    deb http://ubuntu.csie.ntu.edu.tw/ubuntu/ gutsy main restricted universe multiverse
    deb-src http://ubuntu.csie.ntu.edu.tw/ubuntu/ gutsy main restricted universe multiverse
    deb http://ubuntu.csie.ntu.edu.tw/ubuntu/ gutsy-updates main restricted universe multiverse
    deb-src http://ubuntu.csie.ntu.edu.tw/ubuntu/ gutsy-updates main restricted universe multiverse
    deb http://ubuntu.csie.ntu.edu.tw/ubuntu/ gutsy-backports main restricted universe multiverse
    deb-src http://ubuntu.csie.ntu.edu.tw/ubuntu/ gutsy-backports main restricted universe multiverse
    deb http://ubuntu.csie.ntu.edu.tw/ubuntu/ gutsy-security main restricted universe multiverse
    deb-src http://ubuntu.csie.ntu.edu.tw/ubuntu/ gutsy-security main restricted universe multiverse
  • linux 修改MAC地址

    2008-12-08 20:14:34

    学校的帐号和MAC地址是关联的,为了上网只能修改mac地址了

    首先关闭网卡,sudo ifconfig  eth0 down

    现在就可以修改mac地址了,sudo ifconfig eth0 hw ether 00:11:2F:0F:8A:42

    重启网卡就行了:  sudo ifconfig eth0 up

  • 任务、进程和线程区别

    2008-11-07 14:19:36

    任务(task)是最抽象的,是一个一般性的术语,指由软件完成的一个活动。一个任务既可以是一个进程,也可以是一个线程。简而言之,它 指的是一系列共同达到某一目的的操作。例如,读取数据并将数据放入内存中。这个任务可以作为一个进程来实现,也可以作为一个线程(或作为一个中断任务)来 实现。

      进程(process)常常被定义为程序的执行。可以把一个进程看成是一个独立的程序,在内存中有其完备的数据空间和代码空间。一个进程所拥有的数据和变量只属于它自己。

       线程(tread)则是某一进程中一路单独运行的程序。也就是说,线程存在于进程之中。一个进程由一个或多个线程构成,各线程共享相同的代码和全局数 据,但各有其自己的堆栈。由于堆栈是每个线程一个,所以局部变量对每一线程来说是私有的。由于所有线程共享同样的代码和全局数据,它们比进程更紧密,比单 独的进程间更趋向于相互作用,线程间的相互作用更容易些,因为它们本身就有某些供通信用的共享内存:进程的全局数据。

      一个进程和一个线程最显著的区别是:线程有自己的全局数据。线程存在于进程中,因此一个进程的全局变量由所有的线程共享。由于线程共享同样的系统区域,操作系统分配给一个进程的资源对该进程的所有线程都是可用的,正如全局数据可供所有线程使用一样。

  • 我的vim配置

    2008-11-05 17:30:23

    set nu
    set hlsearch
    set tabstop=4
    set expandtab
    set hlsearch
    set incsearch
    set ignorecase smartcase
    set nowrapscan
    set ruler
    set shiftwidth=4
    set cindent
    syntax on
    colorscheme elflord
    set mouse=a    

    set tags+=/home/licaijun/Desktop/linux-2.6.27/tags
    set tags+=/home/licaijun/minigui-test/mgtestcase/tags
    set tags+=/home/licaijun/minigui-test/minigui-3.0.1/tags
    set tags+=/home/licaijun/minigui-test/minigui-3.0.0/tags
    set tags+=/home/licaijun/minigui-test/minigui-2.2.0/tags
    set tags+=/home/licaijun/minigui-test/minigui-2.2.1/minigui-2.2.1-r9940/tags
    set tags+=/home/licaijun/mdolphin/tags
    set tags+=/home/licaijun/minigui-test/minigui-2.2.1/minigui-2.2.1-r10009/tags
    set tags+=/home/licaijun/minigui-test/minigui-2.2.2/tags
    set tags+=/home/licaijun/minigui-test/minigui-1.3.3/libminigui-1.3.3/tags
    set tags+=/home/licaijun/minigui-test/minigui-install/test/libminigui-3.0.1/tags
    set path+=/home/licaijun/minigui/include
    set path+=/usr/local/include/
    set path+=/usr/include/

    if has("cscope")
        set csprg=/usr/bin/cscope
        set csto=0
        set cst
        set nocsverb
        " add any database in current directory
        cscope add /home/licaijun/minigui/trunk/cscope.out /home/licaijun/minigui/trunk
        if filereadable("cscope.out")
            cs add cscope.out
            " else add database pointed to by environment
        elseif $CSCOPE_DB != ""
            cs add $CSCOPE_DB
        endif
        set csverb
    endif

    nmap ts :cs find s <C-R>=expand("<cword>")<CR><CR>
    nmap tg :cs find g <C-R>=expand("<cword>")<CR><CR>
    nmap tc :cs find c <C-R>=expand("<cword>")<CR><CR>
    nmap tt :cs find t <C-R>=expand("<cword>")<CR><CR>
    nmap te :cs find e <C-R>=expand("<cword>")<CR><CR>
    nmap tf :cs find f <C-R>=expand("<cfile>")<CR><CR>
    "nmap ti :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
    nmap ti :cs find i <C-R>=expand("<cfile>")<CR><CR>
    nmap td :cs find d <C-R>=expand("<cword>")<CR><CR>
    nmap tb <C-t>
    nmap * /\C\<<C-R>=expand("<cword>")<CR>\><CR>


    imap {} {}<LEFT><CR><ESC>O
    imap [] []<LEFT>
    imap () ()<LEFT>
    imap <> <><LEFT>
    imap "" ""<LEFT>
    imap '' ''<LEFT>
    imap ?? /**/<left><left>

    set fileencodings=gb2312,gb18030,utf-8
  • FrameBuffer 原理、实现与应用

    2008-11-03 10:31:11

    FrameBuffer 原理、实现与应用

    一、FrameBuffer的原理
        FrameBuffer 是出现在 2.2.xx 内核当中的一种驱动程序接口。
        Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出 FrameBuffer这个设备来供用户态进程实现直接写屏。Framebuffer机制模仿显卡的功能,将显卡硬件结构抽象掉,可以通过 Framebuffer的读写直接对显存进行操作。用户可以将Framebuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接 进行读写操作,而写操作可以立即反应在屏幕上。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由 Framebuffer设备驱动来完成的。
        但Framebuffer本身不具备任何运算数据的能力,就只好比是一个暂时存放水的水池.CPU将运算后的结果放到这个水池,水池再将结果流到显示器. 中间不会对数据做处理. 应用程序也可以直接读写这个水池的内容.在这种机制下,尽管Framebuffer需要真正的显卡驱动的支持,但所有显示任务都有CPU完成,因此CPU 负担很重.
    framebuffer的设备文件一般是 /dev/fb0、/dev/fb1 等等。
    可以用命令: #dd if=/dev/zero ōf=/dev/fb 清空屏幕.
    如果显示模式是 1024x768-8 位色,用命令:$ dd if=/dev/zero ōf=/dev/fb0 bs=1024 count=768 清空屏幕;
    用命令: #dd if=/dev/fb ōf=fbfile  可以将fb中的内容保存下来;
    可以重新写回屏幕: #dd if=fbfile ōf=/dev/fb;
    在使用Framebuffer时,Linux是将显卡置于图形模式下的.

        在应用程序中,一般通过将 FrameBuffer 设备映射到进程地址空间的方式使用,比如下面的程序就打开 /dev/fb0 设备,并通过 mmap 系统调用进行地址映射,随后用 memset 将屏幕清空(这里假设显示模式是 1024x768-8 位色模式,线性内存模式):

    int fb;
    unsigned char* fb_mem;
    fb = open ("/dev/fb0", O_RDWR);
    fb_mem = mmap (NULL, 1024*768, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
    memset (fb_mem, 0, 1024*768);

        FrameBuffer 设备还提供了若干 ioctl 命令,通过这些命令,可以获得显示设备的一些固定信息(比如显示内存大小)、与显示模式相关的可变信息(比如分辨率、象素结构、每扫描线的字节宽度),以及伪彩色模式下的调色板信息等等。
        通过 FrameBuffer 设备,还可以获得当前内核所支持的加速显示卡的类型(通过固定信息得到),这种类型通常是和特定显示芯片相关的。比如目前最新的内核(2.4.9)中,就 包含有对 S3、Matrox、nVidia、3Dfx 等等流行显示芯片的加速支持。在获得了加速芯片类型之后,应用程序就可以将 PCI 设备的内存I/O(memio)映射到进程的地址空间。这些 memio 一般是用来控制显示卡的寄存器,通过对这些寄存器的操作,应用程序就可以控制特定显卡的加速功能。
        PCI 设备可以将自己的控制寄存器映射到物理内存空间,而后,对这些控制寄存器的访问,给变成了对物理内存的访问。因此,这些寄存器又被称为"memio"。一 旦被映射到物理内存,Linux 的普通进程就可以通过 mmap 将这些内存 I/O 映射到进程地址空间,这样就可以直接访问这些寄存器了。
        当然,因为不同的显示芯片具有不同的加速能力,对memio 的使用和定义也各自不同,这时,就需要针对加速芯片的不同类型来编写实现不同的加速功能。比如大多数芯片都提供了对矩形填充的硬件加速支持,但不同的芯片 实现方式不同,这时,就需要针对不同的芯片类型编写不同的用来完成填充矩形的函数。
        FrameBuffer 只是一个提供显示内存和显示芯片寄存器从物理内存映射到进程地址空间中的设备。所以,对于应用程序而言,如果希望在 FrameBuffer 之上进行图形编程,还需要自己动手完成其他许多工作。

    二、FrameBuffer在Linux中的实现和机制
    Framebuffer对应的源文件在linux/drivers/video/目录下。总的抽象设备文件为fbcon.c,在这个目录下还有与各种显卡驱动相关的源文件。

    (一)、分析Framebuffer设备驱动
        需要特别提出的是在INTEL平台上,老式的VESA 1.2 卡,如CGA/EGA卡,是不能支持Framebuffer的,因为Framebuffer要求显卡支持线性帧缓冲,即CPU可以访问显缓冲中的每一位, 但是VESA 1.2 卡只能允许CPU一次访问64K的地址空间。
    FrameBuffer设备驱动基于如下两个文件:
    1) linux/include/linux/fb.h
    2) linux/drivers/video/fbmem.c

    下面分析这两个文件。
    1、fb.h
       几乎主要的结构都是在这个中文件定义的。这些结构包括:
    1)fb_var_screeninfo
       这个结构描述了显示卡的特性:

    struct fb_var_screeninfo
    {
    __u32 xres; /* visible resolution */
    __u32 yres;
    __u32 xres_virtual; /* virtual resolution */
    __u32 yres_virtual;
    __u32 xoffset; /* offset from virtual to visible resolution */
    __u32 yoffset;

    __u32 bits_per_pixel; /* guess what */
    __u32 grayscale; /* != 0 Gray levels instead of colors */

    struct fb_bitfield red; /* bitfield in fb mem if true color, */
    struct fb_bitfield green; /* else only length is significant */
    struct fb_bitfield blue;
    struct fb_bitfield transp; /* transparency */

    __u32 nonstd; /* != 0 Non standard pixel format */

    __u32 activate; /* see FB_ACTIVATE_* */

    __u32 height; /* height of picture in mm */
    __u32 width; /* width of picture in mm */

    __u32 accel_flags; /* acceleration flags (hints) */

    /* Timing: All values in pixclocks, except pixclock (of course) */
    __u32 pixclock; /* pixel clock in ps (pico seconds) */
    __u32 left_margin; /* time from sync to picture */
    __u32 right_margin; /* time from picture to sync */
    __u32 upper_margin; /* time from sync to picture */
    __u32 lower_margin;
    __u32 hsync_len; /* length of horizontal sync */
    __u32 vsync_len; /* length of vertical sync */
    __u32 sync; /* see FB_SYNC_* */
    __u32 vmode; /* see FB_VMODE_* */
    __u32 reserved[6]; /* Reserved for future compatibility */
    };

    2) fb_fix_screeninfon
    这个结构在显卡被设定模式后创建,它描述显示卡的属性,并且系统运行时不能被修改;比如FrameBuffer内存的起始地址。它依赖于被设定的模式,当一个模式被设定后,内存信息由显示卡硬件给出,内存的位置等信息就不可以修改。

    struct fb_fix_screeninfo {
    char id[16]; /* identification string eg "TT Builtin" */
    unsigned long smem_start; /* Start of frame buffer mem */
    /* (physical address) */
    __u32 smem_len; /* Length of frame buffer mem */
    __u32 type; /* see FB_TYPE_* */
    __u32 type_aux; /* Interleave for interleaved Planes */
    __u32 visual; /* see FB_VISUAL_* */
    __u16 xpanstep; /* zero if no hardware panning */
    __u16 ypanstep; /* zero if no hardware panning */
    __u16 ywrapstep; /* zero if no hardware ywrap */
    __u32 line_length; /* length of a line in bytes */
    unsigned long mmio_start; /* Start of Memory Mapped I/O */
    /* (physical address) */
    __u32 mmio_len; /* Length of Memory Mapped I/O */
    __u32 accel; /* Type of acceleration available */
    __u16 reserved[3]; /* Reserved for future compatibility */
    };

    3) fb_cmap
    描述设备无关的颜色映射信息。可以通过FBIOGETCMAP 和 FBIOPUTCMAP 对应的ioctl操作设定或获取颜色映射信息.

    struct fb_cmap {
    __u32 start; /* First entry */
    __u32 len; /* Number of entries */
    __u16 *red; /* Red values */
    __u16 *green;
    __u16 *blue;
    __u16 *transp; /* transparency, can be NULL */
    };

    4) fb_info
    定义当显卡的当前状态;fb_info结构仅在内核中可见,在这个结构中有一个fb_ops指针, 指向驱动设备工作所需的函数集。

    struct fb_info {
    char modename[40]; /* default video mode */
    kdev_t node;
    int flags;
    int open; /* Has this been open already ? */
    #define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */
    struct fb_var_screeninfo var; /* Current var */
    struct fb_fix_screeninfo fix; /* Current fix */
    struct fb_monspecs monspecs; /* Current Monitor specs */
    struct fb_cmap cmap; /* Current cmap */
    struct fb_ops *fbops;
    char *screen_base; /* Virtual address */
    struct display *disp; /* initial display variable */
    struct vc_data *display_fg; /* Console visible on this display */
    char fontname[40]; /* default font name */
    devfs_handle_t devfs_handle; /* Devfs handle for new name */
    devfs_handle_t devfs_lhandle; /* Devfs handle for compat. symlink */
    int (*changevar)(int); /* tell console var has changed */
    int (*switch_con)(int, struct fb_info*);
    /* tell fb to switch consoles */
    int (*updatevar)(int, struct fb_info*);
    /* tell fb to update the vars */
    void (*blank)(int, struct fb_info*); /* tell fb to (un)blank the screen */
    /* arg = 0: unblank */
    /* arg > 0: VESA level (arg-1) */
    void *pseudo_palette; /* Fake palette of 16 colors and
    the cursor's color for non
    palette mode */
    /* From here on everything is device dependent */
    void *par;
    };

    5) struct fb_ops
    用户应用可以使用ioctl()系统调用来操作设备,这个结构就是用一支持ioctl()的这些操作的。

    struct fb_ops {
    /* open/release and usage marking */
    struct module *owner;
    int (*fb_open)(struct fb_info *info, int user);
    int (*fb_release)(struct fb_info *info, int user);
    /* get non settable parameters */
    int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con,
    struct fb_info *info);
    /* get settable parameters */
    int (*fb_get_var)(struct fb_var_screeninfo *var, int con,
    struct fb_info *info);
    /* set settable parameters */
    int (*fb_set_var)(struct fb_var_screeninfo *var, int con,
    struct fb_info *info);
    /* get colormap */
    int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,
    struct fb_info *info);
    /* set colormap */
    int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,
    struct fb_info *info);
    /* pan display (optional) */
    int (*fb_pan_display)(struct fb_var_screeninfo *var, int con,
    struct fb_info *info);
    /* perform fb specific ioctl (optional) */
    int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
    unsigned long arg, int con, struct fb_info *info);
    /* perform fb specific mmap */
    int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
    /* switch to/from raster image mode */
    int (*fb_rasterimg)(struct fb_info *info, int start);
    };

    6) structure map
    struct fb_info_gen | struct fb_info | fb_var_screeninfo
    | | fb_fix_screeninfo
    | | fb_cmap
    | | modename[40]
    | | fb_ops ---|--->ops on var
    | | ... | fb_open
    | | | fb_release
    | | | fb_ioctl
    | | | fb_mmap
    | struct fbgen_hwswitch -|-> detect
    | | encode_fix
    | | encode_var
    | | decode_fix
    | | decode_var
    | | get_var
    | | set_var
    | | getcolreg
    | | setcolreg
    | | pan_display
    | | blank
    | | set_disp

    [编排有点困难,第一行的第一条竖线和下面的第一列竖线对齐,第一行的第二条竖线和下面的第二列竖线对齐就可以了]
    这个结构 fbgen_hwswitch抽象了硬件的操作.虽然它不是必需的,但有时候很有用.

    2、 fbmem.c
    fbmem.c 处于Framebuffer设备驱动技术的中心位置.它为上层应用程序提供系统调用也为下一层的特定硬件驱动提供接口;那些底层硬件驱动需要用到这儿的接 口来向系统内核注册它们自己. fbmem.c 为所有支持FrameBuffer的设备驱动提供了通用的接口,避免重复工作.

    1) 全局变量

    struct fb_info *registered_fb[FB_MAX];
    int num_registered_fb;


    这两变量记录了所有fb_info 结构的实例,fb_info 结构描述显卡的当前状态,所有设备对应的fb_info 结构都保存在这个数组中,当一个FrameBuffer设备驱动向系统注册自己时,其对应的fb_info 结构就会添加到这个结构中,同时num_registered_fb 为自动加1.

    static struct {
    const char *name;
    int (*init)(void);
    int (*setup)(void);
    } fb_drivers[] __initdata= { ....};

    如果FrameBuffer设备被静态链接到内核,其对应的入口就会添加到这个表中;如果是动态加载的,即使用insmod/rmmod,就不需要关心这个表。

    static struct file_operations fb_ops ={
    owner: THIS_MODULE,
    read: fb_read,
    write: fb_write,
    ioctl: fb_ioctl,
    mmap: fb_mmap,
    open: fb_open,
    release: fb_release
    };
    这是一个提供给应用程序的接口.

    2)fbmem.c 实现了如下函数.

    register_framebuffer(struct fb_info *fb_info);
    unregister_framebuffer(struct fb_info *fb_info);

    这两个是提供给下层FrameBuffer设备驱动的接口,设备驱动通过这两函数向系统注册或注销自己。几乎底层设备驱动所要做的所有事情就是填充fb_info结构然后向系统注册或注销它。

    (二)一个LCD显示芯片的驱动实例
        以Skeleton LCD 控制器驱动为例,在LINUX中存有一个/fb/skeleton.c的skeleton的Framebuffer驱动程序,很简单,仅仅是填充了 fb_info结构,并且注册/注销自己。设备驱动是向用户程序提供系统调用接口,所以我们需要实现底层硬件操作并且定义file_operations 结构来向系统提供系统调用接口,从而实现更有效的LCD控制器驱动程序。

    1)在系统内存中分配显存
    在fbmem.c文件中可以看到, file_operations 结构中的open()和release()操作不需底层支持,但read()、write()和 mmap()操作需要函数fb_get_fix()的支持.因此需要重新实现函数fb_get_fix()。另外还需要在系统内存中分配显存空间,大多数 的LCD控制器都没有自己的显存空间,被分配的地址空间的起始地址与长度将会被填充到fb_fix_screeninfo 结构的smem_start 和smem_len 的两个变量中.被分配的空间必须是物理连续的。

    2)实现 fb_ops 中的函数
    用户应用程序通过ioctl()系统调用操作硬件,fb_ops 中的函数就用于支持这些操作。(注: fb_ops结构与file_operations 结构不同,fb_ops是底层操作的抽象,而file_operations是提供给上层系统调用的接口,可以直接调用.
      ioctl()系统调用在文件fbmem.c中实现,通过观察可以发现ioctl()命令与fb_ops’s 中函数的关系:
    FBIOGET_VSCREENINFO fb_get_var
    FBIOPUT_VSCREENINFO fb_set_var
    FBIOGET_FSCREENINFO fb_get_fix
    FBIOPUTCMAP fb_set_cmap
    FBIOGETCMAP fb_get_cmap
    FBIOPAN_DISPLAY fb_pan_display


    如果我们定义了fb_XXX_XXX 方法,用户程序就可以使用FBIOXXXX宏的ioctl()操作来操作硬件。

    文件linux/drivers/video/fbgen.c或者linux/drivers/video目录下的其它设备驱动是比较好的参考资 料。在所有的这些函数中fb_set_var()是最重要的,它用于设定显示卡的模式和其它属性,下面是函数fb_set_var()的执行步骤:

    1)检测是否必须设定模式
    2)设定模式

    3)设定颜色映射

    4) 根据以前的设定重新设置LCD控制器的各寄存器。

    第四步表明了底层操作到底放置在何处。在系统内存中分配显存后,显存的起始地址及长度将被设定到LCD控制器的各寄存器中(一般通过 fb_set_var() 函数),显存中的内容将自动被LCD控制器输出到屏幕上。另一方面,用户程序通过函数mmap()将显存映射到用户进程地址空间中,然后用户进程向映射空 间发送的所有数据都将会被显示到LCD显示器上。


    三、FrameBuffer的应用

    (一)、一个使用FrameBuffer的例子

    1. FrameBuffer主要是根据VESA标准的实现的,所以只能实现最简单的功能。
    2. 由于涉及内核的问题,FrameBuffer是不允许在系统起来后修改显示模式等一系列操作。(好象很多人都想要这样干,这是不被允许的,当然如果你自己写驱动的话,是可以实现的).
    3. 对FrameBuffer的操作,会直接影响到本机的所有控制台的输出,包括XWIN的图形界面。

    好,现在可以让我们开始实现直接写屏:

    1、打开一个FrameBuffer设备

    2、通过mmap调用把显卡的物理内存空间映射到用户空间

    3、直接写内存。

    /********************************
    File name : fbtools.h
    */

    #ifndef _FBTOOLS_H_
    #define _FBTOOLS_H_
    #include <linux/fb.h>
    //a framebuffer device structure;
    typedef struct fbdev{
           int fb;
           unsigned long fb_mem_offset;
           unsigned long fb_mem;
           struct fb_fix_screeninfo fb_fix;
           struct fb_var_screeninfo fb_var;
           char dev[20];
    } FBDEV, *PFBDEV;

    //open & init a frame buffer
    //to use this function,
    //you must set FBDEV.dev="/dev/fb0"
    //or "/dev/fbX"
    //it's your frame buffer.
    int fb_open(PFBDEV pFbdev);

    //close a frame buffer
    int fb_close(PFBDEV pFbdev);

    //get display depth
    int get_display_depth(PFBDEV pFbdev);

    //full screen clear
    void fb_memset(void *addr, int c, size_t len);

    #endif 

    /******************
    File name : fbtools.c
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/ioctl.h>
    #include <sys/mman.h>
    #include <asm/page.h>
    #include "fbtools.h"
    #define TRUE        1
    #define FALSE       0
    #define MAX(x,y)        ((x)>(y)?(x)y))
    #define MIN(x,y)        ((x)<(y)?(x)y))

    //open & init a frame buffer
    int fb_open(PFBDEV pFbdev)
    {
           pFbdev->fb = open(pFbdev->dev, O_RDWR);
           if(pFbdev->fb < 0)
           {
                  printf("Error opening %s: %m. Check kernel config\n", pFbdev->dev);
                  return FALSE;
           }

           if (-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var)))
           {
                  printf("ioctl FBIOGET_VSCREENINFO\n");
                  return FALSE;
           }

           if (-1 == ioctl(pFbdev->fb,FBIOGET_FSCREENINFO,&(pFbdev->fb_fix)))
           {
                  printf("ioctl FBIOGET_FSCREENINFO\n");
                  return FALSE;
           }

           //map physics address to virtual address
           pFbdev->fb_mem_offset = (unsigned long)(pFbdev->fb_fix.smem_start) & (~PAGE_MASK);
           pFbdev->fb_mem = (unsigned long int)mmap(NULL, pFbdev->fb_fix.smem_len + pFbdev->fb_mem_offset,              PROT_READ | PROT_WRITE, MAP_SHARED, pFbdev->fb, 0);

           if (-1L == (long) pFbdev->fb_mem)
           {
                  printf("mmap error! mem:%d offset:%d\n", pFbdev->fb_mem, pFbdev->fb_mem_offset);
                  return FALSE;
           }
           return TRUE;
    }

    //close frame buffer
    int fb_close(PFBDEV pFbdev)
    {
           close(pFbdev->fb);
           pFbdev->fb=-1;
    }

    //get display depth
    int get_display_depth(PFBDEV pFbdev);
    {
           if(pFbdev->fb<=0)
           {
                  printf("fb device not open, open it first\n");
                  return FALSE;
           }
           return pFbdev->fb_var.bits_per_pixel;
    }

    //full screen clear
    void fb_memset (void *addr, int c, size_t len)
    {
        memset(addr, c, len);
    }

    //use by test
    #define DEBUG
    #ifdef DEBUG
    main()
    {
           FBDEV fbdev;
           memset(&fbdev, 0, sizeof(FBDEV));
           strcpy(fbdev.dev, "/dev/fb0");
           if(fb_open(&fbdev)==FALSE)
           {
                  printf("open frame buffer error\n");
                  return;
           }
           fb_memset(fbdev.fb_mem + fbdev.fb_mem_offset, 0, fbdev.fb_fix.smem_len);
                  fb_close(&fbdev);
    }

    (二)基于Linux核心的汉字显示的尝试
    我们以一个简单的例子来说明字符显示的过程。我们假设是在虚拟终端1(/dev/tty1)下运行一个如下的简单程序。

    main ( )
    {
    puts("hello, world.\n");
    }

    puts 函数向缺省输出文件(/dev/tty1)发出写的系统调用write(2)。系统调用到linux核心里面对应的核心函数是console.c中的 con_write(),con_write()最终会调用do_con_write( )。在do_con_write( )中负责把"hello, world.\n"这个字符串放到tty1对应的缓冲区中去。
    do_con_write( )还负责处理控制字符和光标的位置。让我们来看一下do_con_write()这个函数的声明。
    static int do_con_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
        其中tty是指向tty_struct结构的指针,这个结构里面存放着关于这个tty的所有信息(请参照 linux/include/linux/tty.h)。Tty_struct结构中定义了通用(或高层)tty的属性(例如宽度和高度等)。在 do_con_write( )函数中用到了tty_struct结构中的driver_data变量。driver_data是一个vt_struct指针。在vt_struct结 构中包含这个tty的序列号(我们正使用tty1,所以这个序号为1)。Vt_struct结构中有一个vc结构的数组vc_cons,这个数组就是各虚 拟终端的私有数据。

    static int do_con_write(struct tty_struct * tty, int from_user,const unsigned char *buf, int count)
    {
    struct vt_struct *vt = (struct vt_struct *)tty->driver_data;//我们用到了driver_data变量
    . . . . .
    currcons = vt->vc_num; file://我们在这里的vc_nums就是1
    . . . . .
    }

        要访问虚拟终端的私有数据,需使用vc_cons〔currcons〕.d指针。这个指针指向的结构含有当前虚拟终端上光标的位置、缓冲区的起始地址、缓冲区大小等等。
        "hello, world.\n"中的每一个字符都要经过conv_uni_to_pc( )这个函数转换成8位的显示字符。这要做的主要目的是使不同语言的国家能把16位的UniCode码映射到8位的显示字符集上,目前还是主要针对欧洲国家 的语言,映射结果为8位,不包含对双字节(double byte)的范围。
        这种UNICODE到显示字符的映射关系可以由用户自行定义。在缺省的映射表上,会把中文的字符映射到其他的字符上,这是我们不希望看到也是不需要的。所以我们有两个选择∶

    1. 不进行conv_uni_to_pc( )的转换。
    2. 加载符合双字节处理的映射关系,即对非控制字符进行1对1的不变映射。我们自己定制的符合这种映射关系的UNICODE码表是direct.uni。要想查看/装载当前系统的unicode映射表,可使外部命令loadunimap。

    经过conv_uni_to_pc( )转换之后,"hello, world.\n"中的字符被一个一个地填写到tty1的缓冲区中。然后do_con_write( )调用下层的驱动,把缓冲区中的内容输出到显示器上(也就相当于把缓冲区的内容拷贝到VGA显存中去)。

    sw->con_putcs(vc_cons〔currcons〕.d, (u16 *)draw_from, (u16*)draw_to-(u16 *)draw_from, y, draw_x);

    之所以要调用底层驱动,是因为存在不同的显示设备,其对应VGA显存的存取方式也不一样。
    上面的Sw->con_putcs( )就会调用到fbcon.c中的fbcon_putcs()函数(con_putcs是一个函数的指针,在Framebuffer模式下指向 fbcon_putcs()函数)。也就是说在do_con_write( )函数中是直接调用了fbcon_putcs()函数来进行字符的绘制。比如说在256色模式下,真正负责输出的函数是void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,const unsigned short *s, int count, int yy, int xx)

    显示中文
        比如说我们试图输出一句中文∶putcs(你好\n );(你好的内码为0xc4,0xe3,0xba,0xc3)。这时候会怎么样呢,有一点可以肯定,"你好"肯定不会出现在屏幕上,国为核心中没有汉字字库,中文显示就是无米之炊了.
        1 在负责字符显示的void fbcon_cfb8_putcs( )函数中,原有操作如下∶对于每个要显示的字符,依次从虚拟终端缓冲区中以WORD为单位读取(低位字节是ASCII码,高8位是字符的属性),由于汉字 是双字节编码方式,所以这种操作是不可能显示出汉字的,只能显示出xxxx_putcs()是一个一个VGA字符.

    要解决的问题∶
    确保在do_con_write( )时uni□pc转换不会改变原有编码。一个很直接的实现方式就是加载一个我们自己定制的UNICODE映射表,loadunimapdirect.uni,或者直接把direct.uni置为核心的缺省映射表。

    针对如上问题,我们要做的第一个尝试方案是如下。
    首先需要在核心中加载汉字字库,然后修改fbcon_cfb8_putcs()函数,在 fbcon_cfb8_putcs( )中一次读两个WORD,检查这两个WORD的低位字节是否能拼成一个汉字,如果发现能拼成一个汉字,就算出这个汉字在汉字字库中的偏移,然后把它当成一 个16 x 16的VGA字符来显示。

    试验的结果表明∶

    1. 能够输出汉字,但仍有许多不理想的地方,比如说,输出以半个汉字开始的一串汉字,则这半个汉字后面的汉字都会是乱码。这是半个汉字的问题。
    2. 光标移动会破坏汉字的显示。表现为,光标移动过的汉字会变成乱码。这是因为光标的更新是通过xxxx_putc( )函数来完成的。

    xxxx_putc( )函数与xxxx_putcs( )函数实现的功能类似,但是xxxx_putc()函数只刷新一个字符而不是一个字符串,因而xxxx_putc()的输入参数是一个整数,而不是一个字 符串的地址。Xxxx_putc( )函数的声明如下∶void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)

        下一个尝试方案就是同时修改xxxx_putcs( )函数和xxxx_putc()函数。为了解决半个汉字的问题,每一次输出之前,都从屏幕当前行的起始位置开始扫描,以确定要输出的字符是否落在半个汉字 的位置上。如果是半个汉字的位置,则进行相应的调整,即从向前移动一个字节的位置开始输出。
        这个方案有一个困难,即xxxx_putc( )函数不用缓冲区的地址,而是用一个整数作为参数。所以xxxx_putc( )无法直接利用相邻的字符来判别该定符是否是汉字。
        解决方案是,利用xxxx_putc( )的光标位置参数(yy, xx),可以逆推出该字符在缓冲区中的位置。但仍有一些小麻烦,在Linux的虚拟终端下,用户可能会上卷该屏幕(shift + pageup),导致光标的y座标和相应字符在缓冲区的行数不一致。相应的解决方案是,在逆推的过程中,考虑卷屏的参量。
        这样一来,我们就又进了一步,得到了一个相对更好的版本。但仍有问题没有解决。敲入turbonetcfg,会发现菜单的边框字符也被当成汉字显示。这是 因为,这种边框字符是扩展字符,也使用了字符的第8位,因而被当作汉字来显示。例如,单线一的制表符内码为0xC4,当连成一条长线就是由一连串0xC4 组成,而0xC4C4正是汉字哪。于是水平的制表符被一连串的哪字替代了。要解决这个问题就非常不容易了,因为制表符的种类比较多,而且垂直制表符与其后 面字符的组合型式又多种多样,因而很难判断出相应位置的字符是不是制表符,从理论上说,无论采取什么样的排除算法,都必然存在误判的情况,因为总存在二义 性,没有充足的条件来推断出当前字符究竟是制表符还是汉字。
        我们一方面寻找更好的排除组合算法,一方面试图寻找其它的解决方案。要想从根本上解决定个问题,必须利用其它的辅助信息,仅仅从缓冲区的字符来判断是不够的。
        经过一番努力,我们发现,在UNIX中使用扩展字符时,都要先输出字符转义序列(Escape sequence)来切换当前字符集。字符转义序列是以控制字符Esc为首的控制命令,在UNIX的虚拟终端中完成终端控制命令,这种命令包括,移动光标 座标、卷屏、删除、切换字符集等等。也就是说在输出代表制表符的字符串之前,通常是要先输出特定的字符转义序列。在console.c里,有根据字符转义 序列命令来记录字符状态的变量。结合该变量提供的信息,就可以非常干净地把制表符与汉字区别开来。

        在如上思路的指引下,我们又产生了新的解决方案。经过改动得到了另一各版本.
        在这个新版本上,turbonetcfg在初次绘制的时候,制表符与汉字被清晰地区分开来,结果是非常正确的。但还有新的问题存在 ∶turbonetcfg 在重绘的时候(如切换虚拟终端或是移动鼠标光标的时候),制表符还是变成了汉字,因为重绘完全依赖于缓冲区,而这时用来记录字符集状态的变量并不反映当前 字符集状态。问题还是没有最终解决。我们又回到了起点。∶( 看来问题的最终解决手段必须是把字符集的状态伴随每一个字符存在缓冲区中。让我们来研究一下缓冲区的结构。每一个字符占用16bit的缓冲区,低8位是 ASCII值,完全被利用,高8位包含前景颜色和背景颜色的属性,也没有多余的空间可以利用。因而只能另外开辟新的缓冲区。为了保持一致性,我们决定在原 来的缓冲区后面添加相同大小的缓冲区,用来存放是否是汉字的信息。

        也许有读者会问,我们只需要为每个字符添加一bit的信息来标志是否是汉字就足够了,为什么还要开辟与原缓冲区大小相同的双倍缓冲区,是不是太浪费呢?我们先放下这个问题,稍后再作回答。
        其实,如果再添加一bit来标志是当前字符是汉字的左半边还是右半边的话,就会省去扫描屏幕上当前整行字符串的工作,这样一来,编程会更简单。但是有读者会问,即使是这样,使用8bit总够用了吧?为什么还要使用16bit呢?
        我们的作法是∶用低8位来存放汉字另外一半的内码,用高8位中的2 bit来存放上面所讲的辅助信息,高8位的剩余6位可以用来存放汉字或其它编码方式(如BIG5或日文、韩文)的信息,从而使我们可以实现同屏显示多种双 字节语言的字符而不会有相互干扰。另外,在编程时,双倍缓冲也比较容易计算。这样我们就回答了如上的两个问题。
        迄今为止,我们有了一套彻底解决汉字和制表符相互干扰、半个汉字的刷新、重绘等问题的方案。剩下的就是具体编程实现的问题了。
        但是,由于Framebuffer的驱动很多,修改每一个驱动的xxxx_putc()函数和xxxx_putcs( )函数会是一项不小的工作,而且,改动驱动程序后,每种驱动的测试也是很麻烦的,尤其是对于有硬件加速的显卡,修改和测试会更不容易。那么,存不存在一种 不需要修改显卡驱动程序的方法呢?
        经过努力,我们发现,可以在调用xxxx_putcs( )或xxxx_putc()函数输出汉字之前,修改vga字库的指针使其指向所需显示的汉字在汉字字库中的位置,即把一个汉字当成两个vga ASCII字符输出。也就是说,在内核中存在两个字库,一个是原有的vga字符字库,另一个是汉字字库,当我们需要输出汉字的时候,就把vga字库的指针 指向汉字字库的相应位置,汉字输出完之后,再把该指针指向vga字库的原有位置。
       这样一来,我们只需要修改fbcon.c和console.c,其中console.c负责维护双倍缓冲区,把每一个字符的信息存入附加的缓冲区;而 fbcon.c负责利用双倍缓冲区中附加的信息,调整vga字库的指针,调用底层的显示驱动程序。这里还有几个需要注意的地方∶

    1. 由于屏幕重绘等原因,调用底层驱动xxxx_putc( )和xxxx_putcs()的地方有多处。我们作了两个函数分别包装这两个调用,完成替换字库、调用xxxx_putcs( )或xxxx_putc( )、恢复字库等功能。
    2. 为了实现向上滚屏(shift + pageup)时也能看到汉字,我们需要作另外的修改。
          Linux 在设计虚拟终端的时候,提供了回顾被卷出屏幕以外的信息的功能,这就是用热键来向上滚屏(shift + pageup)。当前被使用的虚拟终端拥有一个公共的缓冲区(soft back),用来存放被滚出屏幕以外的信息。当切换虚拟终端的时候,公共缓冲区的内容会被清除而被新的虚拟终端使用。向上滚屏的时候,显示的是公共缓冲区 中的内容。因此,如果我们想在向上滚屏的时候看到汉字,公共缓冲区也必须加倍,以确保没有信息丢失。当滚出屏幕的信息向公共缓冲区填写的时候,必须把相应 的附加信息也填写进公共缓冲区的附加区域。这就要求fbcon.c必须懂得利用公共缓冲区的附加信息。
          当然,有另外一种偷懒的方法,那就是不允许用户向上滚屏,从而避免对公区缓冲区的处理。
    3. 把不同的编码方式(GB、BIG5、日文和韩文)写成不同的module,以实现动态加载,从而使得扩展新的编码方式不需要重新编译核心。

    测试

    本文实现的Kernel Patch文件(patch.kernel.chinese)可以从http://www.turbolinux.com.cn下载。Cd /usr/src/(该目录下应有Linux核心源程序所在的目录linux/) patch -p0 -b < patch.kernel.chinese make menuconfig 请选择Console drivers选项中的

    〔*〕 Double Byte Character Display Support(EXPERIMENTAL)
    〔*〕 Double Byte GB encode (module only)
    〔*〕 VESA VGA graphics console
    <*> Virtual Frame Buffer support (ONLY FOR TESTING!)
    <*> 8 bpp packed pixels support
    <*> 16 bpp packed pixels support
    <*> VGA characters/attributes support
    〔*〕 Select compiled-in fonts
    〔*〕VGA 8x8 font
    〔*〕VGA 8x16 font

    make dep
    make bzImage
    make modules
    make install
    make modules_install

    然后用新的核心启动。

    Insmod encode-gb.o 

    四、其它

    (一)   设置FrameBuffer
        FrameBuffer,可以译作"帧缓冲",有时简称为 fbdrv,基于fbdrv的console也被称之为fbcon。这是一种独立于硬件的抽象图形设备。FrameBuffer的优点在于其高度的可移植 性、易使用性、稳定性。使用Linux内核的 FrameBuffer驱动(vesafb),可以轻松支持到1024X768X32bpp以上的分辩率。而且目前可得到的绝大多数linux版本所发行 的内核中,已经预编译了FrameBuffer支持,通常不需要重新编译内核就可以使用。所以FrameBuffer也是zhcon推荐使用的驱动方式。

    进入FrameBuffer可以简单地在系统启动时向kernel传送vga=mode-number的参数来激活FrameBuffer设备,如:
    lilo:linux vga=305
    将会启动1024x768x8bpp模式。

               640x480    800x600    1024x768    1280x1024
      8 bpp      769          771       773        775
      16 bpp     785          788       791        794
      32 bpp     786          789       792        795

    (二)   要使linux缺省进入FrameBuffer,可以修改/etc/lilo.conf,加入一下语句:
    vga=0x303
    退出编辑,执行:
    lilo -v
    重新启动linux,可以使其进入800x600的256色模式。
    grub也是一样,在grub.conf中的kernel行后面写上vga=xxx就行了,也可以用vga=ask,让系统启动的时候询问你用多大的分辨率

    (三)我编译内核时,选择framebuffer模式,启动时屏幕上有一企鹅图片,不知这是如何造成的这个图片可以去掉或改动吗?
    可以将drivers/video/fbcon.c: fbcon_setup()中if (logo) { } 代码去掉。


  • 用Alien在Ubuntu中安装rpm包

    2008-10-27 14:28:19

    Alien这个软件可以把rpm包转换成Debin/Ubuntu的deb包并安装之

    Ubuntu中安装Alien
    sudo apt-get install alien

    转换一个rpm包为deb
    alien -d package-name.rpm

    转换一个rpm包为deb并安装生成的包
    alien -i package-name.rpm

    俺曾经试过用它转换并安装rpm包,有的很顺利,有的则不能转换

    Alien仍然是一个试验性的程序,有很多bug和限制,如果不能无损系统卸载一个包,则不要使用它的alien版本。

  • ubuntu 8.10 3D 桌面设置

    2008-10-22 12:00:49

    ubuntu 8.04,尤其在3d 桌面上化了很多时间,compiz fusion强大的功能华丽的效果实在让人心仪。

    1.启用3D 桌面

    启用3D 桌面的方法在之前的文章(安装ubuntu 8.04 后的一些设置)中介绍过。
    打开受限驱动程序
    系统–>系统管理–>硬件驱动在“已启用”选项上打勾,驱动将在重启后启用。
    重启后打开系统--首选项--外观--视觉效果 ,在这里可以选择“正常”和“扩展”来打开3D桌面了

    2.管理3D 桌面
    默认情况下只能在外观中选择系统给你定制好的3D 效果,如果想要自己控制使用何种特效需要自己装 compizconfig-settings-manager
    $ sudo apt-get install compizconfig-settings-manager
    然后系统–>首选项–>Advanced Desktop Effects Setting 运行compizconfig-settings-manager 管理自己的3D 特效。

    4.特效介绍(对特效还是没有全部吃透,而且很多特效太花哨,这里先说一下我开启的有助于提高工作效率的特效)

    一般--》General options 项:
    Desktop Size–> Horizontal Virtual Size 选4(其实就是选择虚拟桌面数具体个数看自己喜好了)
    Display Settings 中 Texure Filter 选 best, Refresh Rate 选 200,Lighting 打勾,其余不选。

    辅助功能里都不启用,个人感觉不好看也不华丽。

    桌面:
    只开启了 Desktop Cube,Rotate Cube。
    Desktop Cube –> Behaviour 中 Inside Cube 选中的话,桌面将放在立方体的内部,而不是我们常见的外部。
    Desktop Cube –>Transparent Cube 中的两个数值是调透明度的,自己调一下就明白了。

    Rotate Cube –> 一般中 Edge Flip Pointer, Edge Flip Move, Edge Flip DnD 全不选。Speed =500 ,Timestep=1.0000

    Rotate Cube –> Bindings–>Rotate cube :
    Initiate 设为 Button1 (同时按Control+alt+左键,然拖动鼠标就能旋转立方体了)
    Rotate left/Right 向左向右旋转立方体,可以设置鼠标,键盘快捷方式。
    举例:
    鼠标后的 Rotate left 设为 Button1
    鼠标后的 Rotate right 设为 Button1
    这样就能通过直接左键点击屏幕的左右边缘旋转立方体从而达到切换虚拟桌面的目的。

    Rotate left/Right with window 保持但前窗体旋转立方体,这样己可以把但前任务一起带到另一个虚拟桌面去,同样可以设置鼠标,键盘快捷方式。

    窗口管理:

    窗口管理里只启用 Scale

    Scale
    Scale–>Bindings 中Initiate Window Picker 设置键盘快捷Tab,这样按 win+tab 键所有展开的窗体都将平铺在桌面上,然后把光标移到你要的窗体上放开按键,就能选中该窗体。简单来说就是可以快速在各任务间切换。
    可以

    其实窗口管理中还有Application Switcher,Ring Switcher,Shift Switcher 可以完成窗体切换,但我感觉Scale 最快速。

    上面介绍的主要是在3D 桌面下快速切换虚拟桌面和任务窗体,能有效提高我们的工作效率。

    其他一些ubuntu 3D 特效的介绍

    火焰字:
    开启在屏幕上绘制火焰字后,按Shift+win+左键 就可在屏幕上书写火焰字了。另外要设一下clear 项以清楚屏幕上的火焰字。
    Cube Gears
    开启后在旋转立方体的时候会看到立方体里有一组齿轮在转动。
    Windows Preview
    鼠标移动到下边栏的时候会出现窗口预览效果.
    Video Playback
    据说会增强compiz的视频回放效果.
    动画(神灯)
    对所有事件施行随机动画,让你不断体验不同的特效哦。

    立方体倒映
    开启后在旋转立方体时显示立方体的倒影。

    Move window
    移动窗体是让窗体出现半透明等效果。

    Expo
    将所有虚拟桌面展示在同一窗体内,实现类似Mac os X的Expose特效。
  • sudo: unable to resolve host xxx 解决

    2008-10-08 17:47:56

    sudo: unable to resolve host xxx

    在使用sudo的时候,发现老是报sudo: unable to resolve host xxx ,查看hostname 里面的配置也是正确的,为什么还报这个错呢!
    后来在网上看了一下,发现linux os 在解析主机名的时候,是通过hosts 这个文件,修改该问题的办法:

    sudo vim /etc/hosts

    在127.0.1.1 后加上hostname就ok了

  • nm-ifupdown-connection.c.82-connection update not supported (read-only)

    2008-10-08 17:44:01

    昨天晚上升级到8.0.4后,今天早上上班,发现网络不能使用了,在配置网络的时候,只要点击保存按钮,就报

    Updating connection failed: nm-ifupdown-connection.c.82-connection update not supported (read-only)

    费了一上午的时间,(幸好老板不在.吼吼),终于解决该问题.
    首先你要确定你的安装包是network-manager_0.7~~svn20081004t225044-0ubuntu1_i386.deb.
    这时候,你还得安装network-manager-gnome_0.7~~svn20081005t082522-0ubuntu1_i386.deb
    这两个包,通过apt-get dist-upgrade升级的时候,这些包都会下载到/var/cache/apt/archives/目录下.

    你也可以加入源:sudo vim /etc/apt/sources.list/ 加入:

    deb http://ppa.launchpad.net/fta/ubuntu hardy main
    deb http://ppa.launchpad.net/network-manager/ubuntu hardy main
    deb-src http://ppa.launchpad.net/network-manager/ubuntu hardy main
    然后执行:sudo apt-get update ;sudo apt-get dist-upgrade;可以保证你的包是最新的

    上面都搞定了,再看看第二步:
    sudo vim /etc/NetworkManager/nm-system-settings.conf
    [main]
    plugins=ifupdown,keyfile

    [ifupdown]
    managed=true

    看看配置是否和上面一致.

    最后一步,sudo /etc/init.d/networking restart

    这样基本上就搞定了:



    有兴趣的可以看看 network manager 修改了哪些babug
    This bug was fixed in the package network-manager - 0.7~~svn20081004t225044-0ubuntu1

    ---------------
    network-manager (0.7~~svn20081004t225044-0ubuntu1) intrepid; urgency=low

      new upstream snapshot: Sat 2008-10-04 22:50:44 (bzrrev 3602) from
      lp:~vcs-imports/network-manager/main branch

      * merging final revision of main.eni branch which brings
        us back to parity with upstream branch. features temporarily lost from
        "upstream" code base due to this
        + graceful defaults for ifupdown ip4settings
        + wep-tx-keyidx support
        + pre-run intltoolize
      * we run intltoolize -f -c in pre-build:: target
        - update debian/rules
      * drop lp276253_fix_system_hostname.patch; upstream behaviour became more
        graceful and we will add ifupdown plugin support to read/write
        /etc/hostname
        - delete debian/patches/lp276253_fix_system_hostname.patch
        - update debian/patches/series
      * enable ifupdown system-config-interface implementation by default
        (LP: #256054)
        - update debian/nm-system-settings.conf
      * rewrite README.Debian; we document "managed" vs. "unmanaged" mode as well
        as "dial up configurations"
        - update debian/README.Debian
      * reflect the implicit default mode (unmanaged) in default
        nm-system-settings.conf shipped by ubuntu package in intrepid
        - update debian/nm-system-settings.conf
      * (disabled) add code that enforces -Os instead of -O2
        - update debian/rules

      Cherry-Picking upstream submitted patches:
      * debian/patches/000-FIXCRASH-in-add_default_dhcp_connection.loom.patch:
        - fix crash of nm-system-settings when replugging devices that get a
          default connection created (wired)
      * debian/patches/001-IFUPDOWN-wep-tx-keyidx.loom.patch:
        - add support for wep-tx-keyidx wpa setting to ifupdown plugin
      * debian/patches/002-IFUPDOWN-hostname.loom.patch:
        - implement read/write support for /etc/hostname in ifupdown system config
      * debian/patches/003-IFUPDOWN-remove-unused-callbacks.loom.patch:
        - remove some unused callbacks (cleanup)
      * debian/patches/004-IFUPDOWN-devtracking.loom.patch:
        - add device tracking infrastructure - prepare managed/unmanaged mode
      * debian/patches/005-IFUPDOWN-unmanaged-mode.loom.patch:
        - implement global unmanaged mode (LP: #256054)
      * debian/patches/006-IFUPDOWN-parse-system-settings.loom.patch:
        - implement system-settings boolean key ifupdown:managed - default: false
          (LP: #256054)
      * debian/patches/007-IFUPDOWN-managed-mode.loom.patch:
        - implement managed-mode: update mac address of nm-wired/wirless-settings
          (LP: #256054)
      * debian/patches/008-BACKEND-debian-fallback-to-generic-loopback.loom.patch:
        - use ifconfig (instead of ifup) to bring up loopback. If ifconfig is not
          available we fallback to the generic (libnl based) implementation
          shipped by NetworkManager


  • framebuffer 配置

    2008-09-27 10:51:21

    默认屏蔽了framebuffer模开,所以无法在gurb参数上加vga=xxx来启用frame buffer.
    解决解决方法:
    首先,编辑你的 /etc/initramfs-tools/modules 文件
    加入如下三行内容
    fbcon
    vesafb
    vga16fb

    最重要的一步,要把文件/etc/modprobe.d/blacklist-framebuffer里面的vesafb和vga16fb这两行给注释掉。

    这样你就可以在内核后面加入vga=xxx这样的启动参数了。

    最好用hwinfo --framebuffer先看一下显卡支持的vga数值
    sudo hwinfo --framebuffer
    引用:
    02: None 00.0: 11001 VESA Framebuffer
    [Created at bios.447]
    Unique ID: rdCR.il6towt04X5
    Hardware Class: framebuffer
    Model: "Intel(r) 82945GM Chipset Family Graphics Chip Accelerated VGA BIOS Intel(r) 82945GM Chipset Family Graphics Controller"
    Vendor: "Intel Corporation"
    Device: "Intel(r) 82945GM Chipset Family Graphics Controller"
    SubVendor: "Intel(r) 82945GM Chipset Family Graphics Chip Accelerated VGA BIOS"
    SubDevice:
    Revision: "Hardware Version 0.0"
    Memory Size: 7 MB + 704 kB
    Memory Range: 0xd0000000-0xd07affff (rw)
    Mode 0x0305: 1024x768 (+1024), 8 bits
    Mode 0x0317: 1024x768 (+2048), 16 bits
    Mode 0x0318: 1024x768 (+4096), 24 bits
    Mode 0x0312: 640x480 (+2560), 24 bits
    Mode 0x0314: 800x600 (+1600), 16 bits
    Mode 0x0315: 800x600 (+3200), 24 bits
    Mode 0x0301: 640x480 (+640), 8 bits
    Mode 0x0303: 800x600 (+832), 8 bits
    Mode 0x0311: 640x480 (+1280), 16 bits
    Config Status: cfg=new, avail=yes, need=no, active=unknown

    在内核后面加入了vga=0x031b,是1280x1024的位色。

    最后刷新一下
    代码:
    sudo update-initramfs -u
    重启,搞定
Open Toolbar