博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自制操作系统, 构建自己的内核——利用C语言绘制操作系统图像界面
阅读量:3958 次
发布时间:2019-05-24

本文共 4119 字,大约阅读时间需要 13 分钟。

1.创建boot.asm内核引导程序

注意,所有创建的文件均放在同一目录下(.c文件的反汇编最好在linux环境下进行)

创建boot.asm文件,内容:

;内核引导程序org  0x7c00;LOAD_ADDR  EQU  0X9000jmp  entryentry:    mov  ax, 0    mov  ss, ax    mov  ds, ax    mov  es, ax    mov  si, axreadFloppy:    mov          CH, 0        ;CH 用来存储柱面号    mov          DH, 0        ;DH 用来存储磁头号    mov          CL, 2        ;CL 用来存储扇区号    mov          BX, LOAD_ADDR       ; ES:BX 数据存储缓冲区    mov          AH, 0x02      ;  AH = 02 表示要做的是读盘操作    mov          AL,  2        ; AL 表示要练习读取几个扇区    mov          DL, 0         ;驱动器编号,一般我们只有一个软盘驱动器,所以写死                                  ;为0    INT          0x13          ;调用BIOS中断实现磁盘读取功能       JC           fin    jmp          LOAD_ADDRfin:    HLTjmp  fintimes	510-$+$$ db 0times	512 db 0times	512 db 0

需要修改的部分(默认就行):

LOAD_ADDR的值,表示内核加载进内存的位置由kernel.asm里面org确定

readFloppy内mov          CH, 0 中的1的修改,表示内核存储的磁道数

readFloppy内mov          CL, 2 中的2的修改,表示内核存储的扇区数

readFloppy内mov          AL,  2中的2的修改,表示内核的跨越扇区的数量

运行

nasm -o system.img boot.asm

产生系统镜像文件

2.创建内核代码

    2.1创建内核中的c语言代码(最好在linux环境进行)

    创建文件write_vga.c文件,内容

  

//一个对屏幕像素设置颜色的程序void CMain(void) {    int i;    char*p = 0;    for (i = 0xa0000; i <= 0xaffff; i++) {        p = i;        *p = i & 0x0f;     }    for(;;) {        io_hlt();    }}

先编译成.o文件

使用

gcc -m32 -fno-asynchronous-unwind-tables -s -c -fno-pie -o write_vga.o write_vga.c

命令

再反汇编成.asm文件

使用

objconv -fnasm write_vga.o write_vga.asm

命令(提示:记得用git安装objconv 反汇编工具,然后切换到objconv 目录下面)

然后删除无用的信息,如下划线的内容删除

2.2创建全局描述符结构

创建文件pm.inc,内容:

%macro Descriptor 3	dw %2 & 0ffffh	dw %1 & 0ffffh	db (%1>>16) & 0ffh	dw ((%2>>8) & 0f00h) | (%3 & 0f0ffh)	db (%1>>24) & 0ffh%endmacroDA_32    EQU 4000h ;32位段DA_C     EQU 98h ;存在的只执行代码段属性DA_DRW	 EQU 92h ;存在的可读写数据段属性值

2.3创建内核主体代码

创建文件kernel.asm,内容:

%include "pm.inc"org   0x9000  ;这是内核在加载进入内存的时候的地址jmp   LABEL_BEGIN[SECTION .gdt] ;                                  段基址          段界限                属性LABEL_GDT:          Descriptor        0,            0,                   0  LABEL_DESC_CODE32:  Descriptor        0,      SegCode32Len - 1,       DA_C + DA_32LABEL_DESC_VIDEO:   Descriptor        0B8000h,         0ffffh,            DA_DRWLABEL_DESC_VRAM:    Descriptor        0,         0ffffffffh,            DA_DRWLABEL_DESC_STACK:   Descriptor        0,             TopOfStack,        DA_DRW+DA_32GdtLen     equ    $ - LABEL_GDTGdtPtr     dw     GdtLen - 1           dd     0SelectorCode32    equ   LABEL_DESC_CODE32 -  LABEL_GDTSelectorVideo     equ   LABEL_DESC_VIDEO  -  LABEL_GDTSelectorStack     equ   LABEL_DESC_STACK  -  LABEL_GDTSelectorVram      equ   LABEL_DESC_VRAM   -  LABEL_GDT[SECTION  .s16][BITS  16]LABEL_BEGIN:     mov   ax, cs     mov   ds, ax     mov   es, ax     mov   ss, ax     mov   sp, 0100h     mov   al, 0x13     mov   ah, 0     int   0x10     xor   eax, eax     mov   ax,  cs     shl   eax, 4     add   eax, LABEL_SEG_CODE32     mov   word [LABEL_DESC_CODE32 + 2], ax     shr   eax, 16     mov   byte [LABEL_DESC_CODE32 + 4], al     mov   byte [LABEL_DESC_CODE32 + 7], ah     ;set stack for C language     xor   eax, eax     mov   ax,  cs     shl   eax, 4     add   eax, LABEL_STACK     mov   word [LABEL_DESC_STACK + 2], ax     shr   eax, 16     mov   byte [LABEL_DESC_STACK + 4], al     mov   byte [LABEL_DESC_STACK + 7], ah     xor   eax, eax     mov   ax, ds     shl   eax, 4     add   eax,  LABEL_GDT     mov   dword  [GdtPtr + 2], eax     lgdt  [GdtPtr]     cli   ;关中断     in    al,  92h     or    al,  00000010b     out   92h, al     mov   eax, cr0     or    eax , 1     mov   cr0, eax     jmp   dword  SelectorCode32: 0     [SECTION .s32]     [BITS  32]     LABEL_SEG_CODE32:     ;initialize stack for c code     mov  ax, SelectorStack     mov  ss, ax     mov  esp, TopOfStack     mov  ax, SelectorVram     mov  ds,  axC_CODE_ENTRY:     %include "write_vga.asm"     io_hlt:  ;void io_hlt(void);      HLT      RETSegCode32Len   equ  $ - LABEL_SEG_CODE32[SECTION .gs]ALIGN 32[BITS 32]LABEL_STACK:times 512  db 0TopOfStack  equ  $ - LABEL_STACK

生成内核的二进制文件

使用

nasm kernel.asm -o kernel.bat

命令

最后手动链接system.img和kernel.bat二进制文件

将kernel.bat和system.img文件用二进制编辑器打开,并将kernel.bat的内容复制到system.img的55aa数据的后面并保存

使用visualbox运行system.img文件。

结果:

转载地址:http://byozi.baihongyu.com/

你可能感兴趣的文章
P9-c++对象和类-02构造函数和析构函数总结
查看>>
P10-c++对象和类-03this指针详细介绍,详细的例子演示
查看>>
bat备份数据库
查看>>
linux数据库导出结果集且比对 && grep -v ---无法过滤的问题
查看>>
shell函数与自带变量
查看>>
linux下shell获取不到PID
查看>>
sort详解
查看>>
linux,shell中if else if的写法,if elif
查看>>
shell中单引号、双引号、反引号的区别
查看>>
shell脚本死循环方法
查看>>
shell中$*和$@的区别
查看>>
log4cxx 的编译安装过程和使用
查看>>
简单邮件系统程序
查看>>
STL里的multimap使用详解
查看>>
STL 库其中的 std::string用法总结
查看>>
模态对话框的销毁过程与非模态对话的几种销毁方法
查看>>
C++实现http下载 && 24点计算编码风格
查看>>
memcached了解使用和常用命令详解
查看>>
GDB调试各功能总结
查看>>
"undefined reference to" 多种可能出现的问题解决方法
查看>>