Norlit OS —— 自制操作系统 第4章 C与汇编

本文介绍了在开发操作系统过程中,如何在C语言和汇编之间切换,以及如何加载内核。通过使用C语言编写简单的内核功能,并在汇编中传递控制权,展示了从实模式到保护模式的转变。同时,文章讨论了内存管理,包括显示内存分布和初始化全局描述表(GDT)的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4  C与汇编

4.1         谢天谢地C来了

我们都知道一个系统要么是32位,要么是64位的。没错,不然这个系统就太大了。但是,我们不可能分开编写两个操作系统,所以,我们要使用宏来区分开32位和64位。

这个已经和我们的操作系统开发没有关系了,所以读者可以自行在chapter4/a中看源代码。

接下来的任务就是加载内核了。我们之前写过一个DiskRead函数,所以我们可以利用一下这个函数。我们在进入保护模式之前(为了使用BIOS)把KERNEL(还不存在)读入内核:

#78     call   DiskReset  ; Reset Device 0

#79

#80    mov    ax,KERNELFILE_SEGMENT   ; Target Address for INT 13h

#81    mov    es, ax               ;Argument for DiskRead::ES

#82

#83    mov    ax, KERNEL_FILE_LBA      ;Argument for DiskRead::LBA Address

#84    mov    cl,KERNEL_SIZE_SECT ; Argument for DiskRead::Size

#85

#86    mov    bx, KERNELFILE_OFFSET ;Argument for DiskRead::BX

#87    call    DiskRead

代码 4.1.1 读入内核(chapter4/a/boot/loader.asm)

不多说,这些宏都被定义在loader.inc里面。

我们然后进入保护模式,用memcpy把内核拷贝至0x100000的位置。这些都很简单,我也就不多说了,看代码即可。接下来我们得弄一个内核出来。内核应该是32位的了,所以我们可以使用C语言。当然,在那之前,我们先用汇编将控制权交给C

这段代码写起来非常容易。完全没有技术含量。

%include "boot/include/loader.inc"

 

[section .text]   ; 代码在此

 

global _start ; 导出 _start

 

extern cstart

 

_start:

    call cstart

   

    cli

    hlt

代码 4.1.2 战斗力只有5的代码(chapter4/a/kernel/entry.asm)

重头戏在start.c里面。目前的start.c只提供了一个显示文字的功能。

char* dispPos=(char*)0xB8000;

 

void puts(char* str){

    unsigned charc;

    while((c=*(str++))!=0){

       if(c==13){

           dispPos-=((unsigned int)dispPos)%160-64;

              /* Notice: "-64" because 0xB8000 % 160 = 64 */

       }else if(c==10){

           dispPos+=160;

       }else{

           *(dispPos++)=c;

           *(dispPos++)=0x0F;

       }

    }

}

 

void cstart(){

puts("\nKernel is ready!");

}

代码 4.1.3 渣渣(chapter4/a/kernel/start.c)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值