操作系统入门(五) - 混合C和汇编的kernel

来源:互联网 发布:软件测试简历怎么写 编辑:程序博客网 时间:2024/04/20 08:34

需要配合的汇编部分

;; =================
;; 文件: 
;;   k_.asm
;; 作用: 
;;   在0x90000处启动
;;   调用c的k_main
;;   显示一串信息
;; 创建日期:
;;   2006/04/26 flyback
;; 
http://blog.csdn.net/flyback
;; mailto:fly-back@163.com
;;      =================
[BITS 32]

[global start]
[extern _k_main] ; this is in the c file

start:
 cli
 lgdt[cs:gdtrs]

 mov eax, cr0
 or eax,1
 mov cr0, eax

 mov ax, datasels
 mov ds, ax
 mov es, ax
 mov ss, ax
 mov gs, ax
 mov fs, ax
 mov esp, 0x90000
 call _k_main

 jmp $ ; crash

gdtrs :
dw gdtends - gdts - 1 ; gdt的长度
dd gdts ; gdt的物理地址
gdts:
 gdt0s:
 dw 0,0,0,0  ; 据说是一定要为0否则会有错
codesel_gdts:
 dw 0xffff  ; 界限Limit值 = 0x100000 * 0x1000 = 4GB
 dw 0   ; 基地址 = 0
 dw  0x9A00  ; 表示代码段 可读可执行
 dw 0x00CF  ; 粒度(不知道是什么意思)
 datasel_gdts:
 dw 0xffff ; 4GB
 dw 0x0  ; 基地址
 dw  0x9200 ; 数据段 可读可写
 dw  0x00CF ; 粒度
gdtends:

codesels equ codesel_gdts - gdts
datasels equ datasel_gdts - gdts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

c的部分

// main.c
#define WHITE_TXT 0x0e // 黑底白字
void k_clear_screen();
unsigned int k_printf(char *message, unsigned int line);
void update_cursor(int row, int col);

int k_main() // 象在一般c程序里的main一样
{
k_clear_screen();
k_printf("Hi!/nHow's this for a starter OS?", 0);
};

void k_clear_screen() // 清除全部的文本屏幕
{
char *vidmem = (char *) 0xb8000;
unsigned int i=0;
while(i < (80*25*2))
{
vidmem[i]=' ';
i++;
vidmem[i]=WHITE_TXT;
i++;
};
};

unsigned int k_printf(char *message, unsigned int line) // the message and then the line #
{
char *vidmem = (char *) 0xb8000;
unsigned int i=0;
i=(line*80*2);
while(*message!=0)
{
if(*message=='/n') // check for a new line
{
line++;
i=(line*80*2);
*message++;
} else {
vidmem[i]=*message;
*message++;
i++;
vidmem[i]=WHITE_TXT;
i++;
};
};
return(1);
};

还有一个ld要用到的文件
kernel.ld

OUTPUT_FORMAT("binary")
ENTRY(_start)
SECTIONS
{
  .text  0x90000 : {
    *(.text)
  }
  .data  : {
    *(.data)
  }
  .bss  :
  {      
    *(.bss)
  }
}

还有一个批处理,先不用makefil
build.bat

gcc -c c/main.c -o obj/k_.o
nasm -f aout asm/k_.asm -o obj/k_a.o
ld -T kernel.ld -s -e start -o img/KERNEL.img obj/k_a.o obj/k_.o

目录结构:
.
..
[c]
[obj]
[asm]
[img]
kernel.ld
build.bat

main.c在c里面 k_.asm在asm里面

执行build.bat,把kernel.img放在fatboot.img里面然后用bochs看看

原创粉丝点击