安装C语言编译环境。
$ sudo apt-get install build-essential
安装nasm编译器
$ sudo apt-get install nasm
安装完之后就可以用nasm进行编译了,像在Windows里用法一样。
安装bochs虚拟机及映像制作软件。
$ sudo apt-get install bochs bximage
将在Windows环境里的Bochs安装目录下的文件拷过来用
主要是包含以下几个文件或文件夹:
|BIOS-bochs-latest
|VGABIOS-lgpl-latest
|-Tinix
|bochsrc.bxrc
|floppya.img
修改bochsrc.bxrc这个配置文件,如下
###############################################################
# bochsrc.txt file for Tinix (wenwu)
###############################################################
# how much memory the emulated machine will have
megs: 32
# filename of ROM images
romimage: file=../BIOS-bochs-latest, address=0xf0000
vgaromimage: file=../VGABIOS-lgpl-latest
# what disk images will be used
floppya: 1_44=a.img, status=inserted
#floppyb: 1_44=floppyb.img, status=inserted
# hard disk
#ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
#ata0-master: type=disk, path="hd10meg.img", cylinders=306, heads=4, spt=17
# choose the boot disk.
boot: a
# default config interface is textconfig.
#config_interface: textconfig
#config_interface: wx
#display_library: x
# other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term svga
# where do we send log messages?
log: bochsout.txt
# disable the mouse, since DLX is text only
mouse: enabled=0
# enable key mapping, using US layout as default.
#
# NOTE: In Bochs 1.4, keyboard mapping is only 100% implemented on X windows.
# However, the key mapping tables are used in the paste function, so
# in the DLX Linux example I'm enabling keyboard_mapping so that paste
# will work. Cut&Paste is currently implemented on win32 and X windows only.
#keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-us.map
#keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-fr.map
#keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-de.map
#keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-es.map
上面这个配置文件需要改动的地方与在Windows里面的方法是一样的。
megs: 32 是说内存是32M
floppya: 1_44=a.img, status=inserted 指定了软盘映像文件
boot: a 是说从A盘启动,也就是从软盘启动。
这个配置文件写好了,就可以用来做实验了。
在Tinix目录下可以先写了个最简单的启动文件。如下所示:
;==============================================================
;boot.asm
org 07c00h
LABEL_START:
mov ax, cs
mov ds, ax
mov es, ax
mov ax, 0b800h
mov gs, ax
mov ah, 0ch
mov al, 'T'
mov [gs:0],ax
jmp $
;===============================================================
$ nasm boot.asm -o boot.bin
这个时候会在当前目录下生成boot.bin这个文件 。将这个文件写到软盘0面0磁道1扇区。即相对0扇区。
下面先用bximage创建一个软盘映像文件。过程如下所示:
$ bximage
========================================================================
bximage
Disk Image Creation Tool for Bochs
$Id: bximage.c,v 1.32 2006/06/16 07:29:33 vruppert Exp $
========================================================================
Do you want to create a floppy disk image or a hard disk image?
Please type hd or fd. [hd] fd
Choose the size of floppy disk image to create, in megabytes.
Please type 0.16, 0.18, 0.32, 0.36, 0.72, 1.2, 1.44, 1.68, 1.72, or 2.88.
[1.44]
I will create a floppy image with
cyl=80
heads=2
sectors per track=18
total sectors=2880
total bytes=1474560
What should I name the image?
[a.img]
Writing: [] Done.
I wrote 1474560 bytes to a.img.
The following line should appear in your bochsrc:
floppya: image="a.img", status=inserted
创建了映像文件后,需要将生成的二进制文件写入软盘的绝对扇区。我们看一下dd这个小工具的用法。
$ dd --help
用法:dd [操作数] ...
或:dd 选项
复制文件,并根据以下的操作数将数据转换并格式化。
bs=字节 强迫 ibs=<字节> 及 obs=<字节>
cbs=字节 每次转换指定的<字节>
conv=关键字 根据以逗号分隔的关键字表示的方式来转换文件
count=块数目 只复制指定量<块数目>的输入数据
ibs=字节 每次读取指定的<字节>
if=文件 读取<文件>内容而非标准输入的数据
iflag=标记 以指定标记取代逗号作为读入符号列表的分隔符
obs=字节 每次写入指定的<字节>
of=文件 将数据写入<文件>而不在标准输出显示
oflag=标记 以指定标记取代逗号作为写出符号列表的分隔符
seek=块数目 先略过以 obs 为单位的指定<块数目>的输出数据
skip=块数目 先略过以 ibs 为单位的指定<块数目>的输入数据
status=noxfer 不显示数据传输状态
<块数目>和<字节>可以加上以下的单位:
xM=M、c=1、w=2、b=512、kB=1000、K=1024、MB=1000*1000、M=1024*1024、
GB=1000*1000*1000、G=1024*1024*1024,还有 T、P、E、Z、Y 如此类推。
每个<关键字>可以是:
ascii 由 EBCDIC 码转换至 ASCII 码
ebcdic 由 ASCII 码转换至 EBCDIC 码
ibm 由 ASCII 码转换至替换的 EBCDIC 码
block 将结束字符块里的换行替换成等长的空格
unblock 会将 cbs 大小的块中尾部的空格替换为一个换行符
lcase 将大写字符转换为小写
nocreat 不创建输出文件
excl 如果输出文件已存在则操作失败
notrunc 不截断输出文件
ucase 将小写字符转换为大写
swab 交换每一对输入数据字节
noerror 读取数据发生错误后仍然继续
sync 将每个输入数据块以 NUL 字符填满至 ibs 的大小;当配合 block
或 unblock 时,会以空格代替 NUL 字符进行填充
fdatasync 在操作完成前切实写入输出文件
fsync 和上者类似,但同时也写入元数据
每个<标记>符号可以是:
append 追加模式 (只对输出操作有意义)
direct 使用 Direct I/O 存取模式
dsync 对数据采用 I/O 同步
sync 和上者类似,但同时也对元数据生效
nonblock 使用无阻塞 I/O
nofollow 不跟随链接文件
noctty 不根据文件指派控制终端
对运行中的“dd”进程发送一个 USR1 信号会使得
I/O 的统计信息被打印到标准错误设备然后恢复复制操作。
$ dd if=/dev/zero of=/dev/null& pid=$!
$ kill -USR1 $pid; sleep 1; kill $pid
18335302+0 records in
18335302+0 records out
9387674624 bytes (9.4 GB) copied, 34.6279 seconds, 271 MB/s
可用选项有:
--help 显示此帮助信息并离开
--version 显示版本信息并离开
请向 <bug-coreutils@gnu.org> 报告错误。
我们用如下命令写入软盘绝对扇区。
$ dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc
记录了 1+0 的读入
记录了 1+0 的写出
512 字节 (512 B) 已复制,0.000112553 秒,4.5 MB/秒
好了,现在终于可以看执行效果了。在终端输入
$ bochs -q -f bochsrc.bxrc
虚拟机运行效果显示如图所示:那个红色的T清晰可见。虽然我们并没有做清屏的工作。
在Linux调试大概就是这样吧。写个Makefile用来处理一系列的任务应该是个不错的选择。
不过在windows里面的时候我记得是写一个批处理文件 ,想进行模拟的时候只要双击那个批处理文件就可以了。在Linux里面可不可以呢,答案是肯定的。我们可以写一个shell脚本本执行。和Windows里的那个批处理文件一样,也是只用两行代码就行:
#!/bin/sh
bochs -q -f bochsrc.bxrc
写完后保存了任意文件名,然后,为这个文件名加可执行权限 。比如我的(文件名为run):
$ sudo chmod +x run
然后想进行模拟时只要在终端里输入
$ sudo ./run
就可以看到bochs运行了。
如果调试带有文件 系统的软盘映像文件 怎么办。别着急,下面几条命令也可以搞定。
首先在/mnt目录下建一个文件 夹,将来我们的映像文件就被 mount到这里。
$ cd /mnt/
$ sudo mkdir floppy
然后回到我们的操作系统开发目录,将软盘映像文件挂载到上面刚刚建 好的目录下面。假设我的软盘映像文件 为:floppya.img
那么我用下面的命令持载:
$ sudo mount ./floppya.img /mnt/floppy/ -o loop
其中-o loop的意思就是将映像文件看作一个块设备(回环设备)。
然后我们就可以很方便的往这个目录里面写文件了。
写完文件后别忘了卸载掉刚刚挂上去的软盘映像。
然后用bochs 进行模拟,效果如下所示: