操作系统实现----多进程(无特权级转移)
2013-12-18 19:47
309 查看
在上一篇的基础之上,写一个多进程程序:程序切换原理:在定时中断的时候将当前进程的现场保存在当前进程的堆栈中(中断时并自动压入eflag,cs,eip,因为没有特权级的转变,所以也没有堆栈的切换),然后将栈设为目标进程的堆栈,并弹出该进程现场,中断最后的iret指令会将程序接着目标进程的eip运行。
kernel.s因为将所有的段偏移设为0,所以编程时地址的处理非常容易。
boot.s
%define KERNEL_SEG 0x1000 ;内核开始运行的段位置
%define KERNEL_LEN 20 ;内核扇区所占数目
org 0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ax,msg
mov bp,ax
mov ax,0x1301
mov bx,0x000c
mov cx,msgLen
mov dx,0x0000
int 10h;
load:
mov ax,KERNEL_SEG
mov es,ax
mov ah,02
mov al,KERNEL_LEN
xor bx,bx
mov ch,0
mov cl,2
mov dh,0
mov dl,0
int 13h
movKernel:
mov ax,KERNEL_SEG
mov ds,ax
xor ax,ax
mov es,ax
xor si,si
xor di,di
mov cx,KERNEL_LEN * 512
cli
copy:
mov al,[ds:si]
mov [es:di],al
inc si
inc di
loop copy
jmp 0:0
msg: db "Loading kernel"
msgLen equ $-msg
times 510-($-$$) db 0
dw 0xaa55
kernel.s:
kernel.s因为将所有的段偏移设为0,所以编程时地址的处理非常容易。
boot.s
%define KERNEL_SEG 0x1000 ;内核开始运行的段位置
%define KERNEL_LEN 20 ;内核扇区所占数目
org 0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ax,msg
mov bp,ax
mov ax,0x1301
mov bx,0x000c
mov cx,msgLen
mov dx,0x0000
int 10h;
load:
mov ax,KERNEL_SEG
mov es,ax
mov ah,02
mov al,KERNEL_LEN
xor bx,bx
mov ch,0
mov cl,2
mov dh,0
mov dl,0
int 13h
movKernel:
mov ax,KERNEL_SEG
mov ds,ax
xor ax,ax
mov es,ax
xor si,si
xor di,di
mov cx,KERNEL_LEN * 512
cli
copy:
mov al,[ds:si]
mov [es:di],al
inc si
inc di
loop copy
jmp 0:0
msg: db "Loading kernel"
msgLen equ $-msg
times 510-($-$$) db 0
dw 0xaa55
kernel.s:
%define STACK_LEN 1024 ;内核栈空间、进程栈空间大小 jmp start ;gdt gdt: db 0,0,0,0,0,0,0,0 gdt_cs: db 0xff,0x7,0,0,0,0x9a,0xc0,0 gdt_ds: db 0xff,0x7,0,0,0,0x92,0xc0,0 gdt_gs: db 0x02,0,0,0x80,0x0b,0x92,0xc0,0 gdtLen equ $-gdt selector_cs equ gdt_cs - gdt selector_ds equ gdt_ds - gdt selector_gs equ gdt_gs - gdt gdtPtr: dw gdtLen - 1 dd gdt idt: %rep 8 dw intHandler ;offset dw selector_cs ;selector dw 0x8e00 ;property dw 0 ;offset %endrep dw timeInt ;offset dw selector_cs ;selector dw 0x8e00 ;property dw 0 ;offset %rep 256-9 dw intHandler ;offset dw selector_cs ;selector dw 0x8e00 ;property dw 0 ;offset %endrep idtLen equ $ - idt idtPtr: dw idtLen - 1 dd idt start: mov ax,cs mov ds,ax mov es,ax lgdt [gdtPtr] cli lidt [idtPtr] in al,0x92 or al,00000010b out 0x92,al mov eax,cr0 or eax,1 mov cr0,eax jmp selector_cs:start_32 [bits 32] start_32: mov ax,selector_ds mov ds,ax ;数据段初始化 mov ss,ax ;堆栈段初始化 mov esp,stack_top ;堆栈栈底 mov ah,0x0c mov al,'P' call dis_str int 0x80 int 0x80 mov al,0x36 ;控制字:通道0工作方式3、计数初值采用二进制 out 0x43,al mov ax,11930 ;频率为100hz out 0x40,al ;低位 mov al,ah out 0x40,al ;高位 sti ;初始化两个进程,主要是进程对应的堆栈区,事先要压入现场信息 ;初始化进程1的堆栈 mov ax,selector_ds mov ss,ax ;堆栈段初始化 mov esp,stack_top_1 ;堆栈栈底 pushf push dword selector_cs ;push cs push dword task_1 ;push eip push ds push es push fs push gs pushad mov [stack_1],esp ;保存进程1现在的栈指针 ;初始化进程0的堆栈 mov ax,selector_ds mov ss,ax ;堆栈段初始化 mov esp,stack_top_0 ;堆栈栈底 mov [stack_0],esp ;进程0的堆栈指针 pushf push dword selector_cs ;push cs push dword task_0 ;push eip iret ;启动进程0 jmp $ ;等待时钟中断去切换执行两个任务 ; dis_str: push ebx mov bx,selector_gs mov gs,bx mov bx,selector_ds mov ds,bx mov ebx,[cursor_i] shl ebx,1 mov [gs:ebx],ax shr ebx,1 inc ebx cmp ebx,80*25 jne .1 mov ebx,0 .1: mov [cursor_i],ebx pop ebx ret intHandler: iret mov ah,0x0c mov al,'I' call dis_str mov al,'n' call dis_str mov al,'t' call dis_str ; mov al,0x20 ;发送EOI ;为什么这些中断不需要写这句话? ; out 0x20,al ;中断处理结束,要是没有这一句的话,只能响应中断一次 iret timeInt: push ds push es push fs push gs pushad ;由于已经保存了现场,这些寄存器可以使用了 ;切换到内核空间 mov ax,selector_ds mov ds,ax mov al,[process_now] cmp al,0 jne j1 ;如果是进程0 mov [stack_0],esp ;保存进程0的堆栈指针 mov al,1 mov [process_now],al mov ax,selector_ds mov ss,ax ;切换到进程1的堆栈 mov esp,[stack_1] ; jmp j2 j1: ;如果是进程1 mov [stack_1],esp mov al,0 mov [process_now],al mov ax,selector_ds mov ss,ax ; mov esp,[stack_0] ;切换到进程0的堆栈, j2: mov al,0x20 ;发送EOI out 0x20,al ;中断处理结束,要是没有这一句的话,只能响应中断一次 ;将目标进程的现场回复 popad ;popad 将通用寄存器弹出(除了esp) pop gs pop fs pop es pop ds iret task_0: loo: mov ah,0x0c mov al,'A' call dis_str mov ecx,0xfffff ;delay loop $ jmp loo task_1: loo2: mov ah,0x0b mov al,'B' call dis_str mov ecx,0xfffff ;delay loop $ jmp loo2 data_label: cursor_i dd 80 ;显示屏幕位置 process_now db 0 ;当前运行进程 stack_0 dd 0 ;0进程的栈指针 stack_1 dd 0 ;1进程的栈指针 times STACK_LEN db 0 stack_top: ;内核栈底 times STACK_LEN db 0 stack_top_0: ;进程0使用的堆栈 times STACK_LEN db 0 stack_top_1: ;进程1使用的堆栈 times (512*20 - ($-$$)) db 0
相关文章推荐
- 《Orange's 一个操作系统的实现》学习笔记--特权级代码段之间的转移(五)
- 《Orange’s 一个操作系统的实现》3.保护模式6-特权级转移(门描述符概述)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-实践篇)
- 《Orange’s 一个操作系统的实现》3.保护模式6-特权级转移(门描述符概述)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)
- 一个操作系统的实现----不同特权级之间的转移
- 《Orange's 一个操作系统的实现》学习笔记--特权级代码段之间的转移(一)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-进入ring3)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-进入ring3-b)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-理论)
- 《Orange's 一个操作系统的实现》学习笔记--特权级代码段之间的转移(二)
- 《Orange's 一个操作系统的实现》学习笔记--特权级代码段之间的转移(四)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-进入ring3)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-理论)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-进入ring3-b)
- 操作系统实现---多进程(有特权级转移)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-实践篇)
- 《Orange's 一个操作系统的实现》学习笔记--特权级代码段之间的转移(三)
- 操作系统开发系列—5.特权级及特权级的转移