千家信息网

ubuntu下如何安装bochs并且运行linux0.00

发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,ubuntu下如何安装bochs并且运行linux0.00,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。ubuntu下安装bochs
千家信息网最后更新 2024年11月19日ubuntu下如何安装bochs并且运行linux0.00

ubuntu下如何安装bochs并且运行linux0.00,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

ubuntu下安装bochs

安装gcc编译环境

sudo apt-get install build-essential

sudo apt-get install xorg-dev
sudo apt-get install fort77
sudo apt-get install libgtk2.0-dev
sudo apt-get install libwxgtk3.0-dev

下载bochs最新版本
http://bochs.sourceforge.net/

wget https://nchc.dl.sourceforge.net/project/bochs/bochs/2.6.9/bochs-2.6.9.tar.gz

安装命令
清理:
sudo rm -rf /opt/local/bin/*
sudo rm -rf /opt/local/share/bochs

$tar vxzf bochs-2.6.9.tar.gz
$cd bochs-2.6.9
$./configure --enable-debugger --enable-disasm
$ ./configure --with-x11 --with-wx --enable-debugger --enable-disasm --enable-all-optimizations --enable-readline --enable-long-phy-address --enable-debugger-gui --prefix=/opt/local

修改Makefile(新版不需要)
LIBS =
-lz -lrt -lm -lpthread

$make
$cp bochs bochsdbg
$sudo make install

安装nasm
sudo apt-get install nasm


编译boot.asm
nasm boot.asm -o boot.bin

此处的boot.asm是一段汇编代码,在屏幕上打印出hello, OS world!

代码如下:

org 07c00h ; 告诉编译器程序加载到7c00处mov ax, csmov ds, axmov es, axcall DispStr ; 调用显示字符串例程jmp $ ; 无限循环DispStr:mov ax, BootMessagemov bp, ax ; ES:BP = 串地址mov cx, 16 ; CX = 串长度mov ax, 01301h ; AH = 13,  AL = 01hmov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)mov dl, 0int 10h ; 10h 号中断retBootMessage: db "Hello, OS world!"times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节dw 0xaa55 ; 结束标志

用bximage命令来创建img文件

$ bximage========================================================================                                bximage  Disk Image Creation / Conversion / Resize and Commit Tool for Bochs         $Id: bximage.cc 13069 2017-02-12 16:51:52Z vruppert $========================================================================1. Create new floppy or hard disk image2. Convert hard disk image to other format (mode)3. Resize hard disk image4. Commit 'undoable' redolog to base image5. Disk image info0. QuitPlease choose one [0] 1Create imageDo you want to create a floppy disk image or a hard disk image?Please type hd or fd. [hd] fdChoose the size of floppy disk image to create.Please type 160k, 180k, 320k, 360k, 720k, 1.2M, 1.44M, 1.68M, 1.72M, or 2.88M. [1.44M] What should be the name of the image?[a.img] Creating floppy image 'a.img' with 2880 sectorsThe following line should appear in your bochsrc:  floppya: image="a.img", status=inserted

使用dd命令将它写进刚刚创建的软盘映像a.img的第一个扇区
dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc

此时还需要配置bochs的配置文件bochsrc,标准的配置文件格式为

################################################################ Configuration file for Bochs################################################################ how much memory the emulated machine will have megs: 32# filename of ROM images romimage: file=/opt/local/share/bochs/BIOS-bochs-latest #/opt/share/bochs/BIOS-bochs-latest vgaromimage: file=/opt/local/share/bochs/VGABIOS-lgpl-latest #/usr/share/vgabios/vgabios.bin# what disk images will be used floppya: 1_44=a.img, status=inserted# choose the boot disk. boot: floppy# where do we send log messages?# log: bochsout.txt# disable the mouse mouse: enabled=0# enable key mapping, using US layout as default.# keyboard_mapping: enabled=1, map=/opt/local/share/bochs/keymaps/x11-pc-us.map  keyboard: keymap=/opt/local/share/bochs/keymaps/x11-pc-us.map

接着便可以执行

bochs -f bochsrc
来运行bochsrc虚拟机。

nasm汇编直接生成可启动的软盘镜像(根据30天自制操作系统)

; hello-os; TAB=4                DB              0xeb, 0x4e, 0x90                DB              "HELLOIPL"            ;                DW              512                             ;                DB              1                               ;                DW              1                               ;                DB              2                               ;                DW              224                             ;                DW              2880                    ;                DB              0xf0                    ;                DW              9                               ;                DW              18                              ;                DW              2                               ;                DD              0                               ;                DD              2880                    ;                DB              0,0,0x29                ;                DD              0xffffffff              ;                DB              "HELLO-OS   "  ;                DB              "FAT12   "             ;                times   18 db 0                       ;;                DB              0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c                DB              0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a                DB              0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09                DB              0xb4, 0x0e, 0xbb, 0x0f, 0x00, 0xcd, 0x10, 0xeb                DB              0xee, 0xf4, 0xeb, 0xfd;                DB              0x0a, 0x0a         ;                DB              "hello, world"                DB              0x0a                    ;                DB              0                times 510-($-$$) db 0                DB              0x55, 0xaa;                DB              0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00                                times   4600 db 0                     ;                DB              0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00                times   1469432 db 0                  ;

nasm -o helloos.img helloos.asm

生成的img大小和1.4M软盘一致。可以直接启动

; hello-os; TAB=4                ORG             0x7c00                  ;;                JMP SHORT entry                DB              0x90                DB              "HELLOIPL"            ;                DW              512                             ;                DB              1                               ;                DW              1                               ;                DB              2                               ;                DW              224                             ;                DW              2880                    ;                DB              0xf0                    ;                DW              9                               ;                DW              18                              ;                DW              2                               ;                DD              0                               ;                DD              2880                    ;                DB              0,0,0x29                ;                DD              0xffffffff              ;                DB              "HELLO-OS   "  ;                DB              "FAT12   "             ;;entry:                MOV             AX,0                    ;                MOV             SS,AX                MOV             SP,0x7c00                MOV             DS,AX                MOV             ES,AX                MOV             SI,msgputloop:                MOV             AL,[SI]                ADD             SI,1                    ;                CMP             AL,0                JE              fin                MOV             AH,0x0e                 ;                MOV             BX,15                   ;                INT             0x10                    ;                JMP             putloopfin:                HLT                                             ;                JMP             fin                             ;msg:                DB              0x0a, 0x0a         ;                DB              "hello,myworld"                DB              0x0a                    ;                DB              0                times 510-($-$$) db 0                DB              0x55, 0xaa;                DB              0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00                times   4600 db 0                     ;                DB              0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00                times   1469432 db 0                  ;

===========================================================

运行linux0.00

克隆项目到本地硬盘

git clone https://github.com/voidccc/linux0.00.git

cd linux0.00

生成软盘映像a.img(bximage)

修改Makefile如下

# Makefile for linux 0.00all: diskdisk: boot head        dd bs=32 if=boot of=a.img skip=1        dd bs=512 if=head of=a.img skip=8 seek=1boot: boot.s        as86 -0 -a -o boot.o boot.s        ld86 -0 -s -o boot boot.ohead: head.s        as --32 -o head.o head.s        ld -m elf_i386 -Ttext 0 -e startup_32 -o head head.oclean:        rm -f core boot *.o head

主要改变:as改了as --32,否则在64位系统中不能汇编,另外在原项目中直接写到映像文件Image,的到的文件大小6k多虽然也能在bochs中启动,但不是标准的软盘映像,这里用a.img代替

修改.bochsrc(根据bochs安装位置)

################################################################ Configuration file for Bochs################################################################ how much memory the emulated machine will have megs: 32# filename of ROM images romimage: file=/opt/local/share/bochs/BIOS-bochs-latest #/opt/share/bochs/BIOS-bochs-latest vgaromimage: file=/opt/local/share/bochs/VGABIOS-lgpl-latest #/usr/share/vgabios/vgabios.bin# what disk images will be usedfloppya: 1_44=a.img, status=inserted#ata0-master: type=disk, path="hdc.img", mode=flat, cylinders=410, heads=16, spt=38# choose the boot disk. boot: a# where do we send log messages?# log: bochsout.txt# disable the mouse mouse: enabled=0# enable key mapping, using US layout as default.# keyboard_mapping: enabled=1, map=/opt/local/share/bochs/keymaps/x11-pc-us.map  keyboard: keymap=/opt/local/share/bochs/keymaps/x11-pc-us.map

$ cat boot.s

! voidccc created 20120913! 本文件编译方法! as86 -0 -a -o boot.o boot.s! ld86 -0 -s -o boot boot.o! 说明! 这是512K的引导扇区,做了如下的工作:! 1 使用BIOS的0x13中断,读取真正内核到内存! 2 将内核移动到内存开始位置! 3 设置保护模式下的初始GDT/IDT! 4 切换到保护模式! 5 跳转到内核开始位置执行!mov cx,#0x2000 here need modifyBOOTSEG = 0x07c0 SYSSEG = 0x1000         !内核先被加载到的位置SYSLEN = 17             !内核占用的磁盘扇区数,在使用int 13读取内核时用到entry start             !入口点start:    jmpi go,#BOOTSEG    !段间跳转到!BIOS已经将本程序加载到0x07c0的位置,目前是在实模式下,启动时段寄存器的缺省值是00,所以这句实际还是跳转到go,0的位置,同时段间跳转会修改CS和IP的值,这句执行完后,CS被设置为0x07c0,IP被设置为gogo:    mov ax,cs           !让DS和SS都指向0x07c0段,因为段寄存器只能接受寄存器的    mov ds,ax    mov ss,ax    mov sp,#0x400!使用BIOS中断调用加载内核代码到0x10000处,BIOS的0x13中断具体使用方式此处不做深究。!只要知道实模式下初始的中断向量表是在跳转到0x07c0之前,已经由BIOS设置好就行。load_system:    mov dx,#0x0000    mov cx,#0x0002    mov ax,#SYSSEG    mov es,ax    xor bx,bx           ! 清空bx,ES:BX(0x10000:0x0000)是读入缓冲区位置    mov ax,#0x200+SYSLEN    int 0x13    jnc ok_load         !若没有发生错误则跳转继续运行,否则死循环die: jmp dieok_load:    cli                 !关闭中断,之所以要关闭中断,是因为此时已经将内核加载完毕,而加载内核是需要使用BIOS提供的0x13中断的,所以在加载完内核前不能关闭中断。而后续要转入保护模式并且使用多任务,在内核完全准备好后续操作前,要将中断关闭。否则中断会破坏内核的初始化。后续再开启多任务时,会再次开启中断。    mov ax,#SYSSEG      !为rep指令做准备,把要内核要开始移动的位置,放入DS:SI,目的地位置放入ES:DI,移动次数放入cx,cx是移动次数4096(0x1000转换为10进制)次    mov ds,ax    xor ax,ax    mov es,ax    mov cx,#0x2000    sub si,si    sub di,di    rep    movw                !每次移动一个字!加载IDT和GDT基地址寄存器IDTR和GDTR!因为刚使用了ds,现在要先回复ds    mov ax,#BOOTSEG    mov ds,ax    lidt idt_48         !加载idt,给保护模式用的,48位    lgdt gdt_48         !加载gdt,给保护模式用的,48位!设置CR0中的PE位,进入保护模式    mov ax,#0x0001    lmsw ax             !将ax放入CR0!虽然执行LMSW指令以后切换到了保护模式,但该指令规定其后必须紧随一条段间跳转指令以!刷新CPU的指令缓冲队列。因此在LMSW指令后,CPU还是继续执行下一条指令!此处0,8已经是保护模式的地址,8是选择符,0是偏移地址!跳转到段选择符是8,偏移0的地址处,段选择符8转化为16位2进制为!0000000000001        0          00!|--描述符索引--|--GDT/LDT--|--特权级--|!其中0为GDT 1为LDT!其中00为特权级0 11为特权级3!其中描述符索引1是CS段选择符,可详见下面gdt的定义!jmpi 有副作用,会设置CS的值    jmpi 0,8   !下面是GDT的内容,3个段描述符,!第一个不用,第2个是代码段,第三个是数据段  gdt:!段描述符0,不用    .word 0,0,0,0!段描述符1,!0x07FF十进制是2047,段限长,!0x0000 段基地址,!0x9A00 代码段,可读可执行!0x00c0 段属性颗粒度4k          .word 0x07FF,0x0000,0x9A00,0x00c0!段描述符2,!0x07FF十进制是2047,段限长,!0x0000 段基地址,!0x9200 数据段,可读可写!0x00c0 段属性颗粒度4k    .word 0x07FF,0x0000,0x9200,0x00c0!??!下面的数据用于存放到IDTR和GDTR里!IDTR |---32位表基地址---|--16位表长度--|!GDTR |---32位表基地址---|--16位表长度--|!word. 16位长度,32位基地址idt_48:    .word 0,0,0gdt_48:    .word 0x7ff,0x7c00+gdt,0!引导扇区的标志.org 510    .word 0xAA55

$ cat head.s

#  head.s contains the 32-bit startup code.#  Two L3 task multitasking. The code of tasks are in kernel area, #  just like the Linux. The kernel code is located at 0x10000.##  voidccc 20120921#  编译方法#  as --32 -o head.o head.s#  这是一个运行在保护模式下的AT&T汇编写的多任务内核#  代码包括#  1 初始化设置代码#  2 时钟中断代码#  3 系统调用中断代码 #  4 任务a和任务b的代码#  在初始化完成之后程序移动到任务0开始执行,并在时钟中断控制下进行任务0和任务1之间的切换#  书上代码需要修改的地方#  movl scr_loc, %bx => movlscr_loc, %ebx#  movl $65, %al => movb $65, %al#  movl $66, %al => movb $66, %al#  align 2 => align 4#  align 3 => align 8SCRN_SEL = 0x18TSS0_SEL = 0x20LDT0_SEL = 0x28TSS1_SEL = 0x30LDT1_SEL = 0x38                              #定时器初始值,即每隔10毫秒发送一次中断请求。由于8254芯片的时钟输入频率为1193180 Hz,所以芯片每隔1193190/100次计数,就会发出一个时钟中断请求信号,也就是每隔10毫秒左右(1秒的1/100)LATCH = 11930.text                              # startup_32是特殊的标号,表示保护程序的开始位置startup_32:                              #首先加载DS SS ESP,所有段的线性基地址都是0,                              #作为三个段之一的CS此处不用重新设置,完全是因为本次执行是从boot用长跳转jmpi指令过来的,这个指令有副作用,会设置CS寄存器的值为长跳转的段寄存器    movl $0x10, %eax    mov %ax, %ds    lss init_stack, %esp                              #重新设置IDT和GDT表    call setup_idt            #设置IDT,先把256个中断门都填默认处理过程的描述符    call setup_gdt            #设置GDT    movl $0x10, %eax          #在改变了GDT之后重新加载所有段寄存器    mov %ax,%ds    mov %ax,%es    mov %ax,%fs    mov %ax,%gs    lss init_stack, %esp                              #设置8253定时芯片。把计数器通道0设置成每隔10毫秒想中断控制器发送一个中断请求信号    movb $0x36, %al           #控制字:设置通道0工作方式在3,计数初值采用二进制。    movl $0x43, %edx          #8253芯片控制字寄存器写端口    outb %al, %dx                 movl $LATCH, %eax         #初始计数值设置为LATCH, 100HZ    movl $0x40, %edx          #通道0的端口    outb %al, %dx             #分两次把初始计数值写入通道0    movb %ah, %al    outb %al, %dx                              #在IDT表第8和第128(0x80)项处分别设置定制中断门描述符和系统调用陷阱门描述符    movl $0x00080000, %eax    #中断程序属内核,即eax高字是内核代码段选择符0x0008    movw $timer_interrupt, %ax#设置定时中断门描述符取定时中断处理程序地址    movw $0x8E00, %dx          #中断门类型是14(屏蔽中断)    movl $0x08, %ecx          #开机时BIOS设置的时钟中断向量号8,这里直接使用    lea idt(,%ecx,8),%esi     #把IDT描述符0x80地址放入ESI    movl %eax, (%esi)    movl %edx,4(%esi)    movw $system_interrupt, %ax    movw $0xef00, %dx    movl $0x80, %ecx    lea idt(,%ecx,8),%esi    movl %eax,(%esi)    movl %edx,4(%esi)                              #为人工移动到任务0准备堆栈    pushfl                    #复位标志寄存器    andl $0xffffbfff, (%esp)    popfl    movl $TSS0_SEL, %eax      #把任务0的TSS段选择符加载到任务寄存器TR    ltr %ax    movl $LDT0_SEL, %eax      #把任务0的LDT段选择符加载到局部描述符表寄存器LDTR    lldt %ax                  #TR和DTR只需要人工加载一次,以后CPU会自动处理    movl $0, current          #把当前任务号0保存在current变量中    sti                       #现在开启中断,并在栈中营造中断返回时的场景    pushl $0x17               #把任务0当前局部控件数据段(堆栈段)选择符入栈    pushl $init_stack         #把堆栈指针入栈    pushfl                    #把标志寄存器值入栈    pushl $0x0f               #把当前局部控件代码段选择符入栈    pushl $task0              #把代码指针入栈    iret                      #执行中断返回指令,从而切换到特权级3的任务0中执行                              #以下是设置GDT和IDT中描述符的子程序setup_gdt:    lgdt lgdt_opcode          #使用6字节操作数lgdt_opcode设置GDT表位置和长度    ret                              #这段代码暂时设置IDT表中所有256个中断门描述符都为同一个默认值,均使用默认的中断处理过程ignore_int,设置的具体方法是:首先在eax和edx寄存器对中分别设置好默认中断门描述符的0-3字节和4-7字节的内容,然后利用寄存器对循环往IDT表中填充默认中断门描述符内容。setup_idt:    lea ignore_int, %edx     movl $0x00080000, %eax    #选择符为0x0008    movw %dx, %ax    movw $0x8E00, %dx         #中断门类型,特权级为0    lea idt, %edi    mov $256, %ecx            #循环设置所有256个门描述符rp_idt:    movl %eax, (%edi)    movl %edx, 4(%edi)    addl $8, %edi    dec %ecx    jne rp_idt    lidt lidt_opcode          #最后用6字节操作数加载IDTR寄存器    ret                              #显示字符子程序write_char:    push %gs    pushl %ebx    mov $SCRN_SEL, %ebx    mov %bx, %gs    movl scr_loc, %ebx    shl $1, %ebx    movb %al, %gs:(%ebx)    shr $1, %ebx    incl %ebx    cmpl $2000, %ebx    jb 1f # ??    movl $0, %ebx1:    movl %ebx, scr_loc    popl %ebx    pop %gs    ret                              # 以下是3个中断处理程序:默认中断,定时中断,系统调用中断。                              # ignore_int是默认的中断处理程序,若系统产生了其他中断,则会在屏幕上显示一个字符'C'.align 4ignore_int:    push %ds    pushl %eax    movl $0x10, %eax    mov %ax, %ds    movl $67, %eax    call write_char    popl %eax    pop %ds    iret                              #这是定时中断处理程序,其中主要执行任务切换操作。.align 4timer_interrupt:    push %ds    pushl %eax    movl $0x10, %eax    mov %ax, %ds    movb $0x20, %al    outb %al, $0x20    movl $1, %eax    cmpl %eax, current    je 1f    movl %eax, current    ljmp $TSS1_SEL, $0    jmp 2f1:    movl $0, current    ljmp $TSS0_SEL, $02:    popl %eax    pop %ds    iret                              #系统调用中断 int0x80 处理程序,该示例只有一个显示字符功能.align 4system_interrupt:    push %ds    pushl %edx    pushl %ecx    pushl %ebx    pushl %eax    movl $0x10, %edx    mov %dx, %ds    call write_char    popl %eax    popl %ebx    popl %ecx    popl %edx    pop %ds    iret                              /*******************************************/                              #数据区。没有专门定义,是和代码区混合编写的。current:    .long 0                   #当前的任务号(0或者1)scr_loc:    .long 0                   #屏幕当前显示位置,从左上到右下顺序.align 4                      #书上是 .align 2lidt_opcode:    .word 256*8-1             #16位表长,没法通过减法获得长度,是通过调用fill填充的    .long idt                 #32位基地址lgdt_opcode:    .word (end_gdt-gdt)-1     #16位表长,可以通过减法获得长度。    .long gdt                 #32位基地址.align 8                      #书上是 .align 3idt:    .fill 256,8,0             # 256个门描述符,每个8字节,共占用2KBgdt:                              #段描述符,可结合段描述符具体格式看    .quad 0x0000000000000000  #第1描述符,不用,quad是4字节宽度    .quad 0x00c09a00000007ff  #第2描述符,内核代码段,基地址0 段限长7ff,2047字节,选择符0x08 = 1:0:00                              #   |    |                                #   +----+  高地址   方便查表的格式                              #   | 00 |           | 00 c0 9a 00 |                                 #   +----+           | 00 00 07 ff |                              #   | c0 |                              #   +----+                                #   | 9a |                              #   +----+                                #   | 00 |                              #   +----+                                #   | 00 |                              #   +----+                                #   | 00 |                              #   +----+                                #   | 07 |                              #   +----+  低地址                              #   | ff |                                #   +----+                                #   |    |      .quad 0x00c09200000007ff  #第3描述符,内核数据段,基地址0 只有TYPE段类型与第2描述符不一样, 选择符0x08 = 10:0:00    .quad 0x00c0920b80000002  #第4描述符    .word 0x0068,tss0,0xe900,0x0#第5描述符,TSS0段的描述符,基地址tss0,段限长104(0x68)                              #   |        |                                #   +--------+  高地址   方便查表的格式                              #   | 0x0000 |           | 00 00 e9 00 |                                    #   +--------+           | tss0  00 68 |                              #   | 0xe900 |                              #   +--------+                                #   | tss0   |                              #   +--------+                                #   | 0x0068 |                                #   +--------+  低地址                              #   |        |      .word 0x0040,ldt0,0xe200,0x0#第6描述符,LDT0段的描述符,基地址ldt0,段限长0x40    .word 0x0068,tss1,0xe900,0x0#第7描述符,TSS1段的描述符,基地址tss1,段限长0x68    .word 0x0040,ldt1,0xe200,0x0#第8描述符,LDT1段的描述符,基地址ldt1,段限长0x40end_gdt:                      #用来计算gdt表的长度    .fill 128,4,0             #初始内核堆栈空间,后续给任务0当做内核数据段init_stack:                   #刚进入保护模式时用于加载SS:ESP堆栈指针    .long init_stack          #堆栈段偏移位置    .word 0x10                #堆栈段起始地址,同数据段                              #下面是任务0的LDT表段中的局部段描述符.align 8                      #书上是 .align 3ldt0:    .quad 0x0000000000000000  #第1个描述符,不用    .quad 0x00c0fa00000003ff  #第2个描述符,局部代码段描述符,基地址是0,段限长3ff    .quad 0x00c0f200000003ff  #第3个描述符,局部数据段描述符,基地址是0,段限长3ff                              #下面是任务0的TSS段的内容tss0:    .long 0    .long krn_stk0, 0x10      #    .long 0,0,0,0,0           # esp1, ssl1, esp2, ss2, cr3    .long 0,0,0,0,0           # eip, eflags, eax, ecx, edx      .long 0,0,0,0,0           # ebx, esp, ebp, esi, edi    .long 0,0,0,0,0,0         # es, cs, ss, ds, fs, gs    .long LDT0_SEL, 0x8000000 #    .fill 128,4,0             #krn_stk0:                              #下面是任务1的LDT表段内容和TSS段内容.align 8                      #书上是 .align 3ldt1:    .quad 0x0000000000000000  # 第1个描述符    .quad 0x00c0fa00000003ff  # 第2个描述符    .quad 0x00c0f200000003ff  # 第3个描述符tss1:    .long 0                   #同tss0    .long krn_stk1, 0x10    .long 0,0,0,0,0    .long task1, 0x200        # eip eflags    .long 0,0,0,0    .long usr_stk1,0,0,0    .long 0x17,0x0f,0x17,0x17,0x17,0x17    .long LDT1_SEL, 0x8000000    .fill 128,4,0             #任务1的内核栈空间krn_stk1:                              #下面是任务0和任务1的程序task0:    movl $0x17, %eax          #首先让DS指向任务的局部数据段    movw %ax, %ds                 movb $65, %al             #把需要显示的字符A放入AL寄存器中                              #书上写的是 movl $65 %al    int $0x80                 #执行系统调用    movl $0xfff, %ecx         #执行循环,起延时作用1:  loop 1b    jmp task0task1:    movl $0x17, %eax    movw %ax, %ds    movb $66, %al             #把需要显示的字符B放入AL寄存器中                              #书上写的是 movl $66 %al    int $0x80                 #系统调用    movl $0xfff, %ecx         #延时一段时间,并跳转到开始出继续循环显示1:  loop 1b    jmp task1    .fill 128,4,0             #任务1的用户栈空间usr_stk1:

启动

关于ubuntu下如何安装bochs并且运行linux0.00问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

0