05.加载并执行其它扇区代码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Zllvincent/article/details/83540564

简介

上一博文实现了把其它扇区的数据加载进内存并显示出来,同理如果其它扇区的是执行代码,在内核加载器加载完其它扇区代码后并指定CS:IP指向加载进来的内存地址,其它扇区的代码将会被指向。

目标

使用汇编实现其他扇区代码功能,内核加载器加载该扇区代码并跳转到指定内存执行写入虚拟磁盘其他扇区的代码。

1.修改内核加载器文件boot.s

;能用于操作内存的寄存器只能是bx、bp、si、di
;0x7c00--0x7dff 这512字节用于启动区
;对内存的访问都必须指定段寄存器,没有显示指定时将使用ds作为段寄存器


    org 0x7c00

    LOAD_ADDR EQU 0x8000   ;内核加载偏移地址

    mov ax,0
    mov ss,ax
    mov ds,ax
    mov es,ax 

    mov bx,LOAD_ADDR
   
    mov ch,1        ;柱面号
    mov dh,0        ;磁头号
    mov cl,2        ;扇区号
    mov ah,0x02     ;0x02表示读盘操作
    mov al,1        ;表示连续读取扇区数
    mov dl,0        ;驱动器号,早期有多个软驱,一般只有一个写死0
    int 0x13        ;调用BIOS实现磁盘读取
    jc error        ;读盘操作失败,flag标志寄存器cf 标志位被置1 
    jmp bx          ;跳转到加载的内存地址开始执行代码


fin:
    hlt
    jmp fin


putloop:
    mov al,[si]
    inc si
    cmp al,0
    je fin
    mov ah,0x0e     ;中断调用参数
    mov bx,15       ;字符颜色
    int 0x10        ;中断调用号
    jmp putloop


error:
    mov si,errMsg
    jmp putloop
   

errMsg:
    db 'error'
    db 0

2.编写内核文件kernel.s

    org 0x8000  

    mov ax,0
    mov ss,ax
    mov ds,ax
    mov es,ax

    mov si,msg 


putloop:
    mov al,[si]
    inc si
    cmp al,0
    je fin
    mov ah,0x0e     ;中断调用参数
    mov bx,15       ;字符颜色
    int 0x10        ;中断调用号
    jmp putloop

fin:
    hlt
    jmp fin


msg:
    db 'hello world from kernel'
    db 0

终端运行nasm 编译汇编文件
nasm boot.s -o boot.bat
nasm kernel.s -o kernel.bat

3.制作虚拟软盘main.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#include "floppy.h"


int main(int argc,char **argv){
    FILE *fp = initFloppy("floppy.img");
    if(fp == NULL) {
        printf("初始化磁盘失败");
        exit(0);
    }
    
    FILE *src = fopen("boot.bat", "r");
    if(src == NULL) {
        printf("文件打开失败");
        exit(0);
    }
    char buf[512];
    memset(buf, 0, 512);
    fread(buf, 512, 1, src);
    buf[510] = 0x55;
    buf[511] = 0xaa;
    writeFloppy(0, 0, 1, fp, buf);
    fclose(src);
    
    memset(buf, 0, 512);
    src = fopen("kernel.bat", "r");
    if(src == NULL) {
        printf("文件打开失败");
        exit(0);
    }
    fread(buf, 512, 1, src);
    writeFloppy(1, 0, 2, fp, buf);
    fclose(src);
    
    fclose(fp);
    return 1;
}

4.验证
编译运行main.c 文件生成虚拟软盘文件,虚拟机加载该软盘文件显示如下:
在这里插入图片描述

至此,写入其它扇区的代码被成功加载进内存并执行成功!

猜你喜欢

转载自blog.csdn.net/Zllvincent/article/details/83540564