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

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)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值