美文网首页
操作系统起点-从汇编出发,开发bios引导扇区执行代码

操作系统起点-从汇编出发,开发bios引导扇区执行代码

作者: jhon_11 | 来源:发表于2021-12-18 12:37 被阅读0次

    简介

    相信计算机专业的人都学过操作系统相关的知识,也有很多人安装过操作系统,那么我们在学习相关理论知识的时候,有没有真正动手实践过怎么让机器启动就加载我们的代码并将cpu指令进入内核呢。小子不才,根据网上资料踩坑之后成功运行了操作系统版hello world,下面是一篇踩坑指南

    环境介绍
    macbook pro m1芯片的机器(该配置无视)
    parallels desktop (虚拟机软件)破解(https://qiujunya.com/article/2020/9/9/103.html
    安装 ubuntu 20.04.2 ARM64虚拟机 (内置安装)
    安装bochs(一款模拟操作系统硬件,cpu的软件)免费

    sudo apt update
    sudo apt install build-essential libx11-dev xorg-dev libgtk2.0-dev
    wget https://sourceforge.net/projects/bochs/files/bochs/2.7/bochs-2.7.tar.gz
    tar zxvf bochs-2.7.tar.gz
    cd bochs-2.7/
    ./configure --with-x11 --with-wx --enable-debugger --enable-disasm --enable-all-optimizations --enable-readline --enable-long-phy-address --enable-ltdl-install --enable-idle-hack --enable-plugins --enable-a20-pin --enable-x86-64 --enable-smp --enable-cpu-level=6 --enable-large-ramfile --enable-repeat-speedups --enable-fast-function-calls --enable-large-ramfile --enable-handlers-chaining --enable-trace-linking --enable-configurable-msrs --enable-show-ips --enable-cpp --enable-debugger-gui --enable-iodebug --enable-logging --enable-assert-checks --enable-fpu --enable-vmx=2 --enable-svm --enable-3dnow --enable-alignment-check --enable-monitor-mwait --enable-avx --enable-evex --enable-x86-debugger --enable-pci --enable-usb --enable-voodoo #如果这些参数有报错,可以去掉一些,然后使用make clean && make uninstall重装
    
    make 
    sudo make install
    #./configure后面的参数便是打开调试功能的开关
    

    安装nasm汇编编译器

    apt install nasm
    nasm -v #查看是否安装成功
    

    操作系统启动过程

    BIOS阶段

    计算机在按下开机键后,首先运行的是BIOS程序,BIOS首先进行加电自检,完成对系统的全面检查。确保核心组件如CPU、主板、内存、串并口、磁盘等正常运行。这一检测经常被称为post或power on selftest。
    完成加电自检后,BIOS所做的第二项工作就是设备初始化。
    然后,BIOS将根据用户所指定的引导次序,按照顺序选择引导设备。在选择了合适的引导设备后,BIOS会把引导设备第一个数据块载入内存,并把执行权移交给它。

    引导程序加载阶段

    第一个数据块所记载的是主引导记录(MBR),共512个字节。包括:引导加载程序(Boot Loader)(前446个字节,如GRUB等)、磁盘分区表(DPT,Disk Partition Table)、分区有效性标志(55AA)。引导加载程序负责加载启动硬盘分区中的操作系统。

    Linux系统中的引导程序有以下3个作用:

    • 编写合适的内核命令行
    • 装载合适的初始虚拟磁盘(简称initrd)
    • 装载合适的linux内核并移交控制权给它。

    引导程序在设计上通常包括两个阶段:
    第一阶段,第一阶段的引导程序通常很小,适合存放在MBR中(因为只有446个字节)。第一阶段引导程序的任务是:定位、装载并把控制权传递给第二个阶段的引导程序,这个程序在文件系统中是看不到的;
    第二阶段,第二阶段的引导程序通常就是引导程序自身,它在启动时就运行了某种形式的应用程序,能够读取有关默认设置的配置信息。第二阶段引导程序通常是文件系统中可以识别的二进制文件。

    内核运行阶段

    Linux内核文件都是以压缩格式存放的,在上一步骤成功完成后,Linux内核被加载至内存中,内核文件首先完成自解压,并在ramdisk文件的帮助下,内核拥有了访问磁盘及文件系统等基本设备的驱动程序。随后内核在完成探测可识别的硬件设备并加载相应驱动,以只读方式加载根文件系统等操作后,内核就可以启动位于磁盘上的第一个应用程序init,进而完成系统的初始化。

    编写boot loader汇编程序

    BIOS由Bochs虚拟机提供,我们接下来写的就是这个512字节的引导扇区(MBR)的汇编代码。目前它并不用加载操作系统,我们只让它在屏幕上打印出经典的“hello world”即可。

    汇编代码

        org 0x07c00
        mov ax,cs
        mov ds,ax
        mov es,ax
        mov ax,Message
        mov bp,ax
        mov cx, 13
        mov ax,0x1301
        mov bx,0x0002
        mov dh,0
        mov dl,0
        int 0x10
        jmp $
    Message: 
        db "Hello, world!"
        times 510-($-$$) db 0
        dw  0xaa55
    

    代码和数据是按汇编程序的编写顺序依次连续存放到内存的,即上面的程序在0x7c00处开始存放的是org 0x07c00的机器指令,在512字节最后放的是0xaa55数据。

    BIOS程序在把引导程序加载到内存时,同时还创建了中断系统,在物理内存的前1KB空间初始化中断向量表,在物理内存最后256KB物理地址空间内保存中断处理程序。cpu运行完BIOS后,物理内存的布局如下:


    image.png

    .
    具体代码的含义可以自学汇编语法,此处我也是刚入门

    制作虚拟硬盘

    # 新建bochs项目目录,随意取名
    mkdir bochs_project
    # 将上面的代码保存到 bochs_project目录 HelloWorld.asm
    # 使用汇编编译器nasm将该代码编译为可执行文件
    nasm boot.asm -o boot.bin
    # 然后在本层目录中创建一个大小为1MB的硬盘镜像文件b.img的命令如下:
    dd if=/dev/zero of=b.img bs=512 count=2048
    #dd是文件拷贝命令,其中:
    #if=/dev/zero:表示拷贝的源文件的路径,"/dev/zero"是一个特殊的文件,可以提供n个0(n的值等于bs和count参数的积)
    #of=b.img:表示拷贝的目标文件路径。若不存在,则创建该文件bs=512:表示大小,单位为B
    #count=2048:表示拷贝的文件的块的数量。
    # 由bs和count参数可知,硬盘镜像文件的大小为:2048*512B=1MB,硬盘镜像文件制作好后,将可执行文件boot.bin拷贝到硬盘镜像文件b.img(硬盘)的引导扇区的命令如下:
    dd if=boot.bin of=b.img bs=512 seek=0 conv=notrunc
    #其中:
    #seek=0:表示把可执行文件boot.bin拷贝到硬盘镜像文件b.img的引导扇区(扇区号为0)。
    #conv=notrunc:表示不改变目标文件的大小,若没有该选项,则硬盘镜像文件b.img的大小会由1MB变为可执行文件boot.bin的大小512B。
    
    

    这样一个写入了引导程序的“硬盘”就制作好了。

    bochs使用

    "硬盘”制作好后,要想启动bochs还需要一个配置文件——bochsrc.bxrc。为什么需要配置文件呢?因为你需要告诉bochs你希望的虚拟机是什么样的,比如,内存多大,使用哪个硬盘启动等等。在下载bochs的源码包中有一个.bochsrc,就是官方提供的配置文件示例,我们可以根据这个更改。

    cp ../bochs-2.7/.bochsrc bochsrc.bxrc
    # 拷贝过来后,编辑这个文件 找到以下的参数进行修改
    romimage: file=/usr/local/share/bochs/BIOS-bochs-latest 
    vgaromimage: file=/usr/local/share/bochs/VGABIOS-lgpl-latest 
    ata0-master: type-disk, path="b.img"
    megs: 16
    cpu: count=1
    boot: disk
    

    其中:

    • romimage:指定bochs运行过程中使用的ROM-BIOS的路径。
    • vgaromimage:指定bochs运行过程中使用的VGA的ROM-BIOS的路径。
    • ata0-master:指定硬盘镜像文件b.img的路径。
    • megs:指定物理内存的大小,单位为MB。
    • cpu:指定cpu的个数,1个。这个参数我们只需要count,其他的都可以删掉
    • boot:指定启动方式,从硬盘启动。

    改完这些还是会报错Bochs is not compiled with lowlevel sound support.
    找到 sound配置,将那个配置删除,一般在900多行
    编辑完成后保存

    现在一切准备就绪,启动bochs的命令如下:

    bochs -q -f bochsrc.bxrc
    #其中:
    #-q: 跳过bochs启动后的配置界面。
    #-f : bochsrc.bxrc:指定配置文件的路径。
    #如果不指定路径,那么Bochs将按照如下顺序在当前目录中寻找配置文件:
    
    

    运行bochs后会在终端出现bochs调试命令行,等待我们输入调试命令,这里输入c继续执行


    image.png

    可以看到在虚拟机中我们的引导程序已成功运行,在屏幕上打印出了hello world。


    image.png

    相关文章

      网友评论

          本文标题:操作系统起点-从汇编出发,开发bios引导扇区执行代码

          本文链接:https://www.haomeiwen.com/subject/ftqgfrtx.html