续1个人开发操作系统之初篇
本文任务是读取软盘18个Sector,编写video.s显示8bit,320*200黑屏,并进入32bit保护模式,编写func.s 和bootpack.c显示白屏,并用编写Makefile编译源文件。
1. boot.s读入18个sector
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 ;读完正面18个Sector后,读反面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-0x0026ffff:IDT
0x00270000-0x0027ffff:GDT
0x00280000-0x002ffffff:bootpack.img
0x00300000-0x003fffff:Stack以及其他
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以上的内存。60h和64h端口是向Keyboard和mouse发送和接收指令。
lgdt [GDTR0] ; init GDTR
初始化GDTR,为了使用32Bit模式,并防止多任务处理时内存访问冲突,提出Segmentation,就是将内存分割为块,每块称为Segment,其初始地址都为0,这样一来,程序就不再需要ORG指令,来指定运行程序的内存初始位置了。
每个Segment需要以下信息:
l Segment大小
l Segment地址
l Segment属性(禁止写,禁止执行,或者系统专用等)
本程序初始化2个Segment,第一个为只读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的程序。
4.bootpack.c和func.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();
}
//0xa0000到0xaffff是显卡内存地址。15代表白色。函数write_mem8功能是将0xa0000到0xaffff地址间的内存赋赋值为15,即白色。
for(i=0xa0000;i<=0xaffff;i++){
write_mem8(i,15);
}
for(;;)
io_hlt();
为死循环
在func.s内实现write_mem8和io_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语言实现的学生个人消费管理系统是一个典型的结构化编程实践,它涵盖了数据结构、文件操作、函数调用、用户交互和错误处理等多个关键知识点。通过实际的项目开发,不仅可以巩固C语言的基础,还能提升...
而C语言的跨平台性也意味着这个理财系统可以在多种操作系统上运行,增加了其适用范围。 总的来说,C语言实现的个人理财系统充分利用了C语言的特性,提供了用户友好的界面和实用的功能,帮助用户进行有效的财务规划...
本系统是一个基于C语言开发的个人财务管理系统,旨在解决个人财务管理中的问题,提供了一个综合的财务管理平台。下面我们将从系统设计、实现、测试和评价等方面对系统进行详细的分析和介绍。 一、系统设计思想 本...
总的来说,"C语言课程设计之个人财务管理系统"涵盖了C语言的基础语法、数据结构、文件操作、控制流程、函数编程等多个重要知识点,对于初学者来说是一个很好的实践项目,能提升编程能力和问题解决技巧。
通过实践这个个人日常财务管理系统,学习者不仅可以掌握C语言的基本语法,还能深入理解数组、指针以及文件操作等高级主题,这对于进一步学习操作系统、数据结构及算法等进阶内容非常有帮助。同时,这样的项目也有助...
作为C语言开发的个人资料,这个压缩包很可能是包含了一系列的学习资源,如教程、代码示例、练习题等,旨在帮助学习者掌握C语言的基础和进阶技巧。 1. **C语言基础**: - 变量和数据类型:C语言提供了基本的数据...
《教材管理系统(C语言)》是一款基于C语言编程的软件应用,专为教育机构或个人提供教材管理服务。在本文中,我们将深入探讨该系统的核心功能、C语言的应用以及开发环境VC6.0的相关知识。 首先,教材管理系统的核心...
总的来说,这个C语言实现的个人账簿管理系统是学习和实践数据结构、算法、文件操作以及用户交互的好案例。通过这个项目,开发者可以深入理解C语言的基础知识,同时提升问题解决和软件设计能力。
在IT领域,Linux操作系统与C语言的结合是程序员必须掌握的基础技能之一。"Linux操作系统下C语言编程入门"这个主题涵盖了两个重要的知识点:Linux操作系统的基本使用和C语言的编程实践。 首先,Linux操作系统是一个...
《大学生综合测评系统C语言版解析》 在信息技术飞速发展的今天,高校的教育管理也逐渐走向数字化。本文将深入探讨一个基于C语言编写的大学生综合测评系统,它旨在为高校提供一种高效、准确的评价学生学业成绩和综合...
【个人通讯录管理系统(C语言程序)】 个人通讯录管理系统是一种常见的软件应用,它允许用户存储、管理和查找联系人的个人信息,如姓名、电话号码、电子邮件地址等。在本项目中,我们采用C语言来实现这样一个系统,...
C语言以其高效和灵活性著称,是操作系统和嵌入式系统的首选语言,而蓝牙开发通常涉及到这些领域。在这个主题中,我们可能会看到如何使用C语言与蓝牙硬件接口,创建连接,发送和接收数据,以及管理蓝牙设备的连接状态...
在IT领域,尤其是软件开发中,Linux操作系统与C语言结合,成为了一种极为重要的技能组合。本文旨在深入解析Linux环境下C语言编程的关键知识点,涵盖从基础概念到高级技巧的全面内容,帮助初学者及进阶者构建坚实的...
在编程领域,C语言以其高效、灵活的特点被广泛应用于各种系统开发,包括个人理财系统。本篇文章将详细解析一个基于C语言编写的个人理财系统,涵盖登录模块、收支记录以及年份和月份的收支统计功能。 一、登录模块 ...
【通讯录系统(C语言开发)】是一种基于C语言编程实现的电话簿管理软件,它旨在简化个人或组织对联系人信息的存储和管理。在C语言课程设计中,这样的项目是一个很好的实践平台,帮助学生深入理解C语言的底层机制和...
1. Linux操作系统概述 Linux是一种自由和开放源代码的类Unix操作系统,它被广泛用于服务器、超级计算机和个人计算机等。Linux操作系统以其稳定性、安全性、可伸缩性和开源的特性而闻名。 2. C语言编程基础 C语言是...
C语言个人消费管理系统主要涵盖了C语言编程、数据结构、文件操作和控制台界面设计等方面的知识。下面根据提供的文件内容进行详细解析。 首先,标题"C语言--个人消费管理系统.pdf"和描述"C语言--个人消费管理系统....
《C语言开发的运动会计分系统》 C语言是一种强大的、通用的编程语言,尤其适合进行底层系统开发和小型应用程序的构建。在这个“运动会计分系统”中,开发者利用C语言的优势,创建了一个功能完善的计分系统,可以...
在IT领域,Linux操作系统和C语言是两个至关重要的概念,它们相互结合,为开发者提供了强大的工具和平台。本文将深入探讨Linux操作系统的基础以及C语言在Linux环境中的应用,旨在帮助初学者快速入门。 Linux是一种...