`
touchinsert
  • 浏览: 1329127 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

1个人开发操作系统之C语言的开始

阅读更多

1个人开发操作系统之初篇

本文任务是读取软盘18Sector,编写video.s显示8bit320*200黑屏,并进入32bit保护模式,编写func.s bootpack.c显示白屏,并用编写Makefile编译源文件。

1. boot.s读入18sector

reading:

mov ax,0x0820

mov es,ax ;0x0820(es) * 16=0x8200 ;第二个Sector的数据读入到内存的0x8200地址。

mov ch,0 ;track/cylinder number

mov dh,0 ;head number

mov cl,2 ;sector number

readloop:

mov si,0 ; count failure times

retry:

;http://en.wikipedia.org/wiki/BIOS_interrupt_call#INT_13h_AH.3D02h:_Read_Sectors_From_Drive

mov ah,0x02 ;status of reading disk sector

mov al,1 ;number of sectors read

mov bx,0 ;0x0820(es) * 16 + 0(bx)=0x8200, 0x7e00~0x9fbff之间

mov dl,0x00 ;A drive

int 0x13 ;Read

jnc next ;no error goto next

add si,1 ;si +1

cmp si,5 ;compare 5

jae error ;goto error

mov ah,0x00 ;

mov dl,0x00 ; a drive

int 0x13 ; drive reset

jmp retry

next:

mov ax,es ; add 0x200(512)

add ax,0x20

mov es,ax

add cl,1 ;cl+1

cmp cl,18 ;compare 18,18 sectors

jbe readloop ;<18,continue

mov cl,1

add dh,1

cmp dh,2 ;读完正面18Sector后,读反面18

jb readloop ;dh<2 goto readloop

mov dh,0

add ch,1

cmp ch,CYLS

jb readloop ;ch<CYLS goto readloop

2. 调到video.s

;读完所有数据后,调到0x8200位置

fin:

mov [0x0ff0],ch ;remember the position of cylinder

JMP 0x8200 ;jump to video.s

hlt ;cpu停止

jmp fin

3. video.s

Colimas Simple OS的内存分布:

0x00000000-0x000fffff:启动时使用

0x00100000-0x00267fff:软盘数据备份

0x00268000-0x<chmetcnv w:st="on" unitname="F" sourcevalue="26" hasspace="False" negative="False" numbertype="1" tcsc="0">0026f</chmetcnv>7ff:空

0x<chmetcnv w:st="on" unitname="F" sourcevalue="26" hasspace="False" negative="False" numbertype="1" tcsc="0">0026f</chmetcnv>800-0x0026ffffIDT

0x00270000-0x0027ffffGDT

0x00280000-0x002ffffffbootpack.img

0x00300000-0x003fffffStack以及其他

0x00400000- :空

;video.s

;Colimas Simple OS

BOTPAK EQU 0x00280000 ; the address of bootpack

DSKCAC EQU 0x00100000 ; Disk Cache Address of 32 mode address

DSKCAC0 EQU 0x00008000 ; Disk Cache of Real mode address

;Save the BOOT INFO to 0x0ff0

CYLS EQU 0x0ff0 ;save the boot info

LEDS EQU 0x0ff1

VMODE EQU 0x0ff2 ;color info

SCRNX EQU 0x0ff4 ;pixel x

SCRNY EQU 0x0ff6 ;pixel y

VRAM EQU 0x0ff8 ;graphic buffer

org 0x8200

;http://en.wikipedia.org/wiki/BIOS_interrupt_call

mov al,0x13 ;video bios int, vga graphics,320*200*8bit color

mov ah,0x00

int 0x10 ;黑屏

mov BYTE [VMODE],8 ; save screen mode

mov WORD [SCRNX],320

mov WORD [SCRNY],200 ;8bit 320*200

mov DWORD [VRAM],0xa0000

;the led status of keybroad

mov ah,0x02

int 0x16 ; keybroad BIOS:Read Keyboard Shift Status

mov [LEDS],al

;block PIC

mov al,0xff

out 0x21,al

nop

out 0xa1,al

cli ;block cpu interrupt

;use >1mb memory set a20gate

call waitkbdout

mov al,0xd1

out 0x64,al ;write out port

call waitkbdout

mov al,0xdf ;enable a20

out 0x60,al

call waitkbdout

;enter protected mode

lgdt [GDTR0] ; init GDTR

mov eax,CR0

and eax,0x7fffffff ;set bit31 to 0( block paging

or eax,0x00000001 ;set bit1 to 1( enable protect mode

mov cr0,EAX

jmp pipelineflash

pipelineflash:

mov ax,1*8 ; reinit all the register from 0x0000 to 0x0008

mov ds,ax

mov es,ax

mov fs,ax

mov gs,ax

mov ss,ax

; mov bootpack

mov esi,bootpack ; source

mov edi,BOTPAK ; destination

mov ecx,512*1024/4

call memcpy

;move boot sector

mov esi,0x<chmetcnv w:st="on" unitname="C" sourcevalue="7" hasspace="False" negative="False" numbertype="1" tcsc="0">7c</chmetcnv>00 ; source

mov edi,DSKCAC ; destination

mov ecx,512/4

call memcpy

;move others

mov esi,DSKCAC0+512 ;source

mov edi,DSKCAC+512 ;destination

mov ecx,0

mov cl,BYTE [CYLS]

imul ecx,512*18*2/4

sub ecx,512/4

call memcpy

;start bootpack

skip:

MOV ESP,0x00300000 ; init stack pointer

JMP DWORD 2*8:0x00

waitkbdout:

in al,0x64

and al,0x02

in al,0x60

jnz waitkbdout ; if result of and is not 0 goto waitkbdout

ret

memcpy:

mov eax,[esi]

add esi,4

mov [edi],eax

add edi,4

sub ecx,1

jnz memcpy

ret

alignb 16

GDT0: ;init gdtr

RESB 8 ; null sector

DW 0xffff,0x0000,0x9200,0x00cf ;

DW 0xffff,0x0000,0x<chmetcnv w:st="on" unitname="a" sourcevalue="9" hasspace="False" negative="False" numbertype="1" tcsc="0">9a</chmetcnv>28,0x0047 ;for bootpack

DW 0

GDTR0:

DW 8*3-1

DD GDT0

alignb 16

bootpack:

其中:

;use >1mb memory set a20gate

call waitkbdout

mov al,0xd1

out 0x64,al ;write out port

call waitkbdout

mov al,0xdf ;enable a20

out 0x60,al

call waitkbdout

代码的目的是屏蔽键盘和鼠标,并使CPU使用1MB以上的内存。60h64h端口是向Keyboardmouse发送和接收指令。

lgdt [GDTR0] ; init GDTR

初始化GDTR,为了使用32Bit模式,并防止多任务处理时内存访问冲突,提出Segmentation,就是将内存分割为块,每块称为Segment,其初始地址都为0,这样一来,程序就不再需要ORG指令,来指定运行程序的内存初始位置了。

每个Segment需要以下信息:

l Segment大小

l Segment地址

l Segment属性(禁止写,禁止执行,或者系统专用等)

本程序初始化2Segment,第一个为只读Segment,地址为0x000000,

第二个为可执行Segment,用来执行bootpack.c程序,地址为0x280000

DW 0xffff,0x0000,0x9200,0x00cf ;

DW 0xffff,0x0000,0x<chmetcnv w:st="on" unitname="a" sourcevalue="9" hasspace="False" negative="False" numbertype="1" tcsc="0">9a</chmetcnv>28,0x0047 ;for bootpack

mov eax,CR0

and eax,0x7fffffff ;set bit31 to 0( block paging

or eax,0x00000001 ;set bit1 to 1( enable protect mode

mov cr0,EAX

设置CR0寄存器,进入保护模式。

mov ax,1*8 ; reinit all the register from 0x0000 to 0x0008

mov ds,ax

mov es,ax

mov fs,ax

mov gs,ax

mov ss,ax

是将所有寄存器都进入第二个Segement

下面程序之前的代码都是将软盘的数据都保存到内存中。

;start bootpack

skip:

MOV ESP,0x00300000 ; init stack pointer

JMP DWORD 2*8:0x00

程序调到0x280000位置执行bootpack.c的程序。

4bootpack.cfunc.s,进入C语言

/*Colimas Simple OS*/

void io_hlt(void);

void write_mem8(int addr, int data);

//entry

void ColimasMain(void)

{

int i;

for(i=0xa0000;i<=0xaffff;i++){

write_mem8(i,15);

}

for(;;)

io_hlt();

}

//0xa00000xaffff是显卡内存地址。15代表白色。函数write_mem8功能是将0xa00000xaffff地址间的内存赋赋值为15,即白色。

for(i=0xa0000;i<=0xaffff;i++){

write_mem8(i,15);

}

for(;;)

io_hlt();

为死循环

func.s内实现write_mem8io_hlt函数。

;func.s

;Colimas Simple OS

[BITS 32]

segment .text

GLOBAL _io_hlt,_write_mem8

_io_hlt:

hlt

ret

_write_mem8: ;void write_mem8(int addr,int data);

mov ecx,[esp+4] ;addr

mov al,[esp+8] ;data

mov [ecx],al

RET

5. Makefile

MAKE = make -r

NASM = nasm

COPY = cp

LINK = olink

LD = ld

CAT = cat

<state w:st="on"><place w:st="on"><span lang="EN-US" style="mso-fareast-font-family: SimSun; mso-fareast-language: ZH-CN">DEL</span></place></state> = rm

CC = gcc

OBJCOPY = objcopy

default :

$(MAKE) img

bin : boot.s Makefile

$(NASM) boot.s -o boot.bin

sys : video.s objcopy Makefile

$(NASM) video.s -o video.sys

$(CAT) video.sys bootpack.img > video.img

bootpack : bootpack.c Makefile

$(CC) -c bootpack.c

func :func.s Makefile

$(NASM) -f coff func.s -l func.lst

objcopy : bootpack func Makefile

$(LD) bootpack.o func.o -o bootpack.bin

$(OBJCOPY) bootpack.bin -O binary bootpack.img

img : bin sys Makefile

$(LINK) -m boot.bin video.img -o boot.img

compile :

$(MAKE) img

run :

$(MAKE) compile

$(COPY) boot.img ../qemu/

clean :

-$(<state w:st="on"><place w:st="on">DEL</place></state>) *.bin

-$(<state w:st="on"><place w:st="on">DEL</place></state>) *.sys

-$(<state w:st="on"><place w:st="on">DEL</place></state>) *.img

-$(<state w:st="on"><place w:st="on">DEL</place></state>) *.o

汇编编译器Nasm

C语言编译器为GCC

连接器为ld

纯二进制转换器为objcopy

运行make命令后,编译生成boot.img, </

分享到:
评论

相关推荐

    C语言实现的学生个人消费管理系统.zip

    总结来说,这个C语言实现的学生个人消费管理系统是一个典型的结构化编程实践,它涵盖了数据结构、文件操作、函数调用、用户交互和错误处理等多个关键知识点。通过实际的项目开发,不仅可以巩固C语言的基础,还能提升...

    个人理财系统 c语言

    而C语言的跨平台性也意味着这个理财系统可以在多种操作系统上运行,增加了其适用范围。 总的来说,C语言实现的个人理财系统充分利用了C语言的特性,提供了用户友好的界面和实用的功能,帮助用户进行有效的财务规划...

    c语言个人财务管理系统

    本系统是一个基于C语言开发的个人财务管理系统,旨在解决个人财务管理中的问题,提供了一个综合的财务管理平台。下面我们将从系统设计、实现、测试和评价等方面对系统进行详细的分析和介绍。 一、系统设计思想 本...

    C语言课程设计之个人财务管理系统

    总的来说,"C语言课程设计之个人财务管理系统"涵盖了C语言的基础语法、数据结构、文件操作、控制流程、函数编程等多个重要知识点,对于初学者来说是一个很好的实践项目,能提升编程能力和问题解决技巧。

    个人日常财务管理系统(C语言)

    通过实践这个个人日常财务管理系统,学习者不仅可以掌握C语言的基本语法,还能深入理解数组、指针以及文件操作等高级主题,这对于进一步学习操作系统、数据结构及算法等进阶内容非常有帮助。同时,这样的项目也有助...

    c语言开发个人资料

    作为C语言开发的个人资料,这个压缩包很可能是包含了一系列的学习资源,如教程、代码示例、练习题等,旨在帮助学习者掌握C语言的基础和进阶技巧。 1. **C语言基础**: - 变量和数据类型:C语言提供了基本的数据...

    教材管理系统(C语言)

    《教材管理系统(C语言)》是一款基于C语言编程的软件应用,专为教育机构或个人提供教材管理服务。在本文中,我们将深入探讨该系统的核心功能、C语言的应用以及开发环境VC6.0的相关知识。 首先,教材管理系统的核心...

    个人账簿管理系统(C语言)

    总的来说,这个C语言实现的个人账簿管理系统是学习和实践数据结构、算法、文件操作以及用户交互的好案例。通过这个项目,开发者可以深入理解C语言的基础知识,同时提升问题解决和软件设计能力。

    Linux操作系统下C语言编程入门.rar

    在IT领域,Linux操作系统与C语言的结合是程序员必须掌握的基础技能之一。"Linux操作系统下C语言编程入门"这个主题涵盖了两个重要的知识点:Linux操作系统的基本使用和C语言的编程实践。 首先,Linux操作系统是一个...

    大学生综合测评系统(C语言版)

    《大学生综合测评系统C语言版解析》 在信息技术飞速发展的今天,高校的教育管理也逐渐走向数字化。本文将深入探讨一个基于C语言编写的大学生综合测评系统,它旨在为高校提供一种高效、准确的评价学生学业成绩和综合...

    个人通讯录管理系统(C语言程序)

    【个人通讯录管理系统(C语言程序)】 个人通讯录管理系统是一种常见的软件应用,它允许用户存储、管理和查找联系人的个人信息,如姓名、电话号码、电子邮件地址等。在本项目中,我们采用C语言来实现这样一个系统,...

    蓝牙开发代码(c语言)

    C语言以其高效和灵活性著称,是操作系统和嵌入式系统的首选语言,而蓝牙开发通常涉及到这些领域。在这个主题中,我们可能会看到如何使用C语言与蓝牙硬件接口,创建连接,发送和接收数据,以及管理蓝牙设备的连接状态...

    linux操作系统下c语言编程入门,经典总结

    在IT领域,尤其是软件开发中,Linux操作系统与C语言结合,成为了一种极为重要的技能组合。本文旨在深入解析Linux环境下C语言编程的关键知识点,涵盖从基础概念到高级技巧的全面内容,帮助初学者及进阶者构建坚实的...

    C语言个人理财系统

    在编程领域,C语言以其高效、灵活的特点被广泛应用于各种系统开发,包括个人理财系统。本篇文章将详细解析一个基于C语言编写的个人理财系统,涵盖登录模块、收支记录以及年份和月份的收支统计功能。 一、登录模块 ...

    通讯录系统(C语言开发)

    【通讯录系统(C语言开发)】是一种基于C语言编程实现的电话簿管理软件,它旨在简化个人或组织对联系人信息的存储和管理。在C语言课程设计中,这样的项目是一个很好的实践平台,帮助学生深入理解C语言的底层机制和...

    Linux操作系统下C语言编程入门

    1. Linux操作系统概述 Linux是一种自由和开放源代码的类Unix操作系统,它被广泛用于服务器、超级计算机和个人计算机等。Linux操作系统以其稳定性、安全性、可伸缩性和开源的特性而闻名。 2. C语言编程基础 C语言是...

    c语言--个人消费管理系统.pdf

    C语言个人消费管理系统主要涵盖了C语言编程、数据结构、文件操作和控制台界面设计等方面的知识。下面根据提供的文件内容进行详细解析。 首先,标题"C语言--个人消费管理系统.pdf"和描述"C语言--个人消费管理系统....

    C语言开发的运动会计分系统

    《C语言开发的运动会计分系统》 C语言是一种强大的、通用的编程语言,尤其适合进行底层系统开发和小型应用程序的构建。在这个“运动会计分系统”中,开发者利用C语言的优势,创建了一个功能完善的计分系统,可以...

    linux操作系统C语言

    在IT领域,Linux操作系统和C语言是两个至关重要的概念,它们相互结合,为开发者提供了强大的工具和平台。本文将深入探讨Linux操作系统的基础以及C语言在Linux环境中的应用,旨在帮助初学者快速入门。 Linux是一种...

Global site tag (gtag.js) - Google Analytics