一、環境搭建
1. 直接在Ubuntu上運行Framebuffer
默認Ubuntu是直接進入X視窗,如果要使用Framebuffer,
需要修改內核引導參數:
$ sudo gedit /etc/default/grub
查找
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
把它改為
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash text vga=0x311"
這裡text表示進入文本模式,vga=0x311表示使用Framebuffer顯示驅動,
0x311是指示色深和分辨率的參數
|640x480 800x600 1024x768 1280x1024
----+-------------------------------------
256 | 0x301 0x303 0x305 0x307
32k | 0x310 0x313 0x316 0x319
64k | 0x311 0x314 0x317 0x31A
16M | 0x312 0x315 0x318 0x31B
如果使用vga=0x311參數,必須使用後面提到的vesafb模塊,並且取消黑名單,
否則無法進入系統,需要光盤啟動刪除vga參數以還原
$ sudo update-grub
寫入到/boot/grub/grub.cfg
$ sudo gedit /etc/initramfs-tools/modules
在其中加入:vesafb
$ sudo gedit /etc/modprobe.d/blacklist-framebuffer.conf
用#注釋以下行
# blacklist vesafb
$ sudo update-initramfs -u
(生成新的initrd)
然後重啟機器,即可進入Framebuffer
如果要切換回X11,可以輸入:
$ startx
有時候/boot/grub/grub.cfg的引導參數不正確導致系統無法引導,
可以用光盤引導系統,掛載硬盤後直接修改/boot/grub/grub.cfg文件
這樣就可以跳過update-grub這一步。然後還原原有的引導參數進入X Window
2. 使用qemu虛擬Linux
需要編譯Linux內核和busybox。
此外還需要libncurses-dev和qemu。
由於qemu可以直接加載內核和initrd,指定引導參數,
所以不需要修改grub配置。
(1)編譯內核和安裝qemu
$ tar xjf linux-2.6.39.2.tar.bz2
$ cd linux-2.6.39.2/
$ make help
$ make i386_defconf
$ sudo apt-get install libncurses-dev
$ make menuconfig
$ make
$ sudo apt-get install qemu
$ qemu --help
$ qemu -kernel arch/x86/boot/bzImage
$ qemu -kernel arch/x86/boot/bzImage -append "noapic"
有時候內核會這樣崩潰:
MP-BIOS BUG 8254 timer not connected
trying to set up timer as Virtual Wire IRQ
所以需要添加-append "noapic"參數
(2) 修改內核配置,然後重新編譯內核。
注意,不同內核版本的配置不一樣,
我的內核配置作如下改動(用空格切換為*,不要切換為M):
$ make menuconfig
Device Drivers --->
Graphics support --->
-*- Support for frame buffer devices --->
[*] VESA VGA graphics support
因為VESA支持彩色色深的顯示。
默認是不選的,只能是黑白控制台。
Input device support --->
[*] Provide legacy /dev/psaux device
有些庫如SDL在識別USB接口的鼠標時會尋找/dev/input/mice和/dev/psaux,
我發現我編譯的內核沒有前者,所以用這個選項制造出/dev/psaux設備。
File systems --->
[*] Miscellaneous filesystems --->
<*> Compressed ROM file system support (cramfs)
個人喜歡cramfs,不過不是必須的,可以用這個開關編譯cramfs驅動,
測試initramfs是否正常
General setup --->
[*] Support initial ramdisks compressed using gzip
[*] Embedded system
默認i86內核的配置不支持gzip壓縮的cpio格式initrd,所以需要手動打開它。
最後重新編譯內核:
$ make
(3) 編譯busybox
$ tar xjf busybox-1.18.5.tar.bz2
$ cd busybox-1.18.5/
$ make defconfig
$ make menuconfig
設置修改如下:
Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary (no shared libs)
$ make
$ make install
默認文件安裝在當前目錄的_install目錄下。
(4) 制作cpio封包gzip壓縮的initrd
$ cd ../busybox-1.18.5/_install/
$ mkdir proc sys dev etc etc/init.d tmp root usr lib
$ gedit etc/init.d/rcS
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s
$ chmod +x etc/init.d/rcS
$ cd ../../linux-2.6.39.2/
$ gedit prerun.sh
#!/bin/sh
cd ../busybox-1.18.5/_install
find . | cpio -o --format=newc > ../rootfs.img
cd ..
gzip -c rootfs.img > rootfs.img.gz
cd ../linux-2.6.39.2/
$ . prerun.sh
$ gedit run.sh
#!/bin/sh
qemu -kernel ./arch/i386/boot/bzImage -initrd ../busybox-1.18.5/rootfs.img.gz -append "root=/dev/ram rdinit=/sbin/init vga=0x312 noapic"
注意這裡用rdinit=,如果用init=就成了initramfs(內核會報告找不到合適的文件系統)
關於vga=的參數設置見前面(決定色深和分辨率)
$ . run.sh
編譯程序,然後用上面寫的prerun.sh打包進rootfs.img.gz,然後運行run.sh跑qemu即可。
如果程序是動態鏈接,需要特定的動態庫,
可以把依賴的動態庫復制到_install/lib目錄下,打包到rootfs.img.gz中。
(5) 進入qemu的效果如下: