关于《30自制操作系统》第四章条纹图案的另一种实现

bootasm.asm使用了nasm格式代码,作用是切换到vga显示模式,开启A20地址线,设置GDT,进入保护模式,跳入32位汇编代码段,调用C语言编写的函数。

代码如下:

extern bootmain

[bits 16]
global start

start:
    ; 切换显示模式,320*200*8位彩色模式
    ; 来自于《30天自制操作系统》
    mov al, 0x13
    mov ah, 0x00
    int 0x10

    ; 下面代码来自于XV6
    cli
    
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    
; 个人感觉这段开启A20的代码比网上的使用CALL的代码清晰、易懂
seta20.1:
    in al, 0x64
    test al, 0x2
    jnz seta20.1
    
    mov al, 0xd1
    out 0x64, al
    
seta20.2:
    in al, 0x64
    test al, 0x2
    jnz seta20.2
    
    mov al, 0xdf
    out 0x60, al
    
; 加载GDT
    lgdt [gdtdesc]
; 开启保护模式
    mov eax, cr0
    or eax, 1
    mov cr0, eax
; 进入保护模式
    jmp dword 8:start32
    
[bits 32]
start32:
; 初始化非代码段寄存器
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov ax, 0
    mov fs, ax
    mov gs, ax
    
; 设置栈顶
    mov esp, start
; 调用C语言中的函数
    call bootmain
    
spin:
    jmp spin
    
gdt:
    dw 0x0000, 0x0000, 0x0000, 0x0000
    dw 0xffff, 0x0000, 0x9a00, 0x00cf    ; 代码段 
    dw 0xffff, 0x0000, 0x9200, 0x00cf    ; 数据段
    
gdtdesc:
    dw (gdtdesc - gdt - 1)
    dd gdt

来至于《30天自制操作系统》第四章的生成条纹图案的代码如下:

void bootmain(void) {
    int i;
    char *p;
    
    p = (char *) 0xa0000;
    
    for (i = 0; i <= 0xffff; i++) {
        *(p + i) = i & 0x0f;
    }
}

环境是:

ubuntu 14.04 32位版,64位的生成32位的代码比较麻烦,其他工具都是apt-get安装的。

编译连接方法如下:

nasm -f elf bootasm.asm -o bootasm.o
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pic -O -nostdinc -I. -c bootmain.c
ld -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o
objcopy -S -O binary -j .text bootblock.o bootblock
./sign.pl bootblock ; 这个使用了XV6的一个脚本,截取文件开始的512个字节,并将截取后文件的最后两个字节设置成0xAA55。
dd if=bootblock of=a.img bs=512 count=1 conv=notrunc ; 参照于渊老师的《Orange's 一个操作系统的实现》第一章。


你可能感兴趣的:(汇编,操作系统,C语言)