////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////实现“进程”切换///////////////////////////////////////////

 ///////////////////////////////////////////////////////////////////////////////////////////

没有使用Linux内核代码,而是从头实现了一个“操作系统”,由于没有切换到X86 CPU的保护模式,在实模式下甚至无法使用C语言,仅用汇编对“进程”切换做一个演示。

 

 

实验要求:

    • 完成一个简单的时间片轮转多道程序内核代码,代码见视频中或从mykernel找。

    • 详细分析该精简内核的源代码并给出实验截图,撰写一篇署名博客,并在博客文章中注明“真实姓名(与最后申请证书的姓名务必一致) + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”,博客内容的具体要求如下:

      • 题目自拟,内容围绕操作系统是如何工作的进行;

      • 博客中需要使用实验截图

      • 博客内容中需要仔细分析进程的启动和进程的切换机制

      • 总结部分需要阐明自己对“操作系统是如何工作的”理解。

    • 3)请提交博客文章URL到网易云课堂MOOC平台Linux内核分析MOOC课程,编辑成一个链接可以直接点击打开。

原文链接

 

  • 第一步,首先实现一个可以引导程序,从引导扇区启动系统
 1 org        07c00h            #bios从该地址开始启动操作系统
 2 entry:
 3     MOV        AX,    0
 4     MOV        SS,    AX
 5     MOV        SP,    0x7c00
 6     MOV        DS,    AX
 7     MOV        ES,    AX
 8     MOV        SI,    msg
 9 
10     MOV        AH,    0x00
11     MOV        AL,    0x03
12     INT        10H
13 
14 putloop:
15     MOV        AL,    [SI]
16     ADD        SI,    1
17     
18     CMP        AL,    0
19     JE        fin
20 
21     MOV        AH,    0x0e
22     MOV        BH,    15
23     INT        0x10
24     JMP        putloop
25 fin:
26     HLT
27     JMP        fin
28 msg:
29     DB        0x0a,0x0a
30     DB        "hello, world"
31     DB        0x0a
32     DB        0
33 
34     times    510-($-$$)    DB    0    # $指当前指令地址  $$指程序第一条指令地址  该语句表示:从当前指令到510字节填充0
35     dw        0xaa55            #引导程序最后两字节约定为 0xaa55

使用命令将汇编编译成二进制文件

将boot.bin制作成img磁盘镜像文件boot.img

虚拟机中启动运行结果

 启动过程,bios将上述程序读入内存0x7c00,并从此处开始执行,程序是很简单的Hello World。printf()等库函数当然无法使用。

  • 第二步,对进程切换进行演示编码
  1     BootLoaderStackPointer equ 0x8300
  2 org        07c00h
  3 entry:
  4     MOV        AX,    0
  5     MOV        SS,    AX
  6     MOV        SP,    BootLoaderStackPointer
  7     MOV     BP,    BootLoaderStackPointer
  8     MOV        DS,    AX
  9     MOV        ES,    AX
 10     MOV        SI,    msgA
 11     
 12     MOV        AH,    0x00
 13     MOV        AL,    0x03
 14     INT        10H
 15     
 16     call    ProcesA
 17     call     fin
 18 
 19 delay:
 20     PUSH    AX
 21     MOV     AX,    0x1000
 22     MOV     [0x8000],    AX
 23 
 24     loopX:
 25     MOV     AX,    0xA000
 26     MOV        [0x8002],    AX
 27     MOV        AX,    [0x8000]
 28     sub        AX,    1
 29     MOV        [0x8000],    AX
 30     CMP        AX,    0
 31     JE        endloop
 32     loopY:
 33     MOV     AX,    [0x8002]
 34     sub        AX,    1
 35     MOV        [0x8002],    AX
 36     CMP        AX,    0
 37     JE        loopX
 38     JMP        loopY
 39 endloop:
 40     POP     AX
 41     ret
 42     
 43     
 44 ;打印 SI 开始到 0 结束的字符串
 45 print:
 46     push     AX
 47     push    BX
 48     push    SI
 49 putloop:    
 50     MOV        AL,    [SI]
 51     ADD        SI,    1
 52     
 53     CMP        AL,    0
 54     JE        putloopret
 55 
 56     MOV        AH,    0x0e
 57     MOV        BH,    15
 58     INT        0x10
 59     JMP        putloop
 60 putloopret:
 61     pop        SI
 62     pop        BX
 63     pop        AX
 64     ret
 65 fin:
 66     HLT
 67     JMP        fin
 68 ProcesA:
 69     MOV        SI,    msgA
 70     call    print
 71     call     delay
 72     MOV        SI,    msgB
 73     call     SwitchProcess
 74     call    print
 75     call    delay
 76     call    fin
 77 ProcesB:
 78     MOV     SI,    msg
 79     call    print
 80     call    delay
 81     call    FinishProcess
 82 SwitchProcess:
 83     MOV        [0x8400],    AX        ;AX
 84     MOV        [0x8402],    SI        ;SI
 85     pop        AX
 86     MOV        [0x8404],    AX        ;IP
 87     MOV        AX,    ProcesB
 88     push    AX
 89     ret
 90 FinishProcess:
 91     MOV        SI,    [0x8402]        ;SI
 92     MOV        AX,    [0x8404]        ;IP
 93     push    AX
 94     MOV        AX,    [0x8400]        ;AX
 95     ret
 96 msg:
 97     DB        0x0a,0x0a
 98     DB        "Process  B----1"
 99     DB        0x0d,0x0a
100     DB        0
101 msgA:
102     DB         0x0a,0x0a
103     DB         "Process  A----1"
104     DB         0x0d,0x0a
105     DB        0
106 msgB:
107     DB        0x0a,0x0a
108     DB         "Process  A----2"
109     DB        0x0d,0x0a
110     DB        0
111     
112     times    510-($-$$)    DB    0
113     dw        0xaa55

虚拟机运行结果

 

代码解析:这段代码主要切换“进程”的代码是SwitchProcessFinishProcess段代码,SwitchProcess只对我们关心的SI寄存器进行了现场保护(内存0x8402),IP寄存器存入内存0x8404,并调用ProcessB进程,等待系统调度完成后,再通过FinishProcess恢复ProcessA进程现场。

这段代码当然不具备一般使用的意义

总结:

  题目要求总结部分需要阐明自己对“操作系统是如何工作的”理解。

  每种操作系统根据用途不同,工作方式也不相同,甚至工作都不相同,硬要总结的话,只能说为应用程序和硬件直接建立桥梁

     By:魏文鹏

参考

《自己动手写操作系统》ISBN 7-121-01577-3

《30天自制操作系统》 ISBN 978-7-115-28796-0