Mr Dk.'s BlogMr Dk.'s Blog
  • 🦆 About Me
  • ⛏️ Technology Stack
  • 🔗 Links
  • 🗒️ About Blog
  • Algorithm
  • C++
  • Compiler
  • Cryptography
  • DevOps
  • Docker
  • Git
  • Java
  • Linux
  • MS Office
  • MySQL
  • Network
  • Operating System
  • Performance
  • PostgreSQL
  • Productivity
  • Solidity
  • Vue.js
  • Web
  • Wireless
  • 🐧 How Linux Works (notes)
  • 🐧 Linux Kernel Comments (notes)
  • 🐧 Linux Kernel Development (notes)
  • 🐤 μc/OS-II Source Code (notes)
  • ☕ Understanding the JVM (notes)
  • ⛸️ Redis Implementation (notes)
  • 🗜️ Understanding Nginx (notes)
  • ⚙️ Netty in Action (notes)
  • ☁️ Spring Microservices (notes)
  • ⚒️ The Annotated STL Sources (notes)
  • ☕ Java Development Kit 8
GitHub
  • 🦆 About Me
  • ⛏️ Technology Stack
  • 🔗 Links
  • 🗒️ About Blog
  • Algorithm
  • C++
  • Compiler
  • Cryptography
  • DevOps
  • Docker
  • Git
  • Java
  • Linux
  • MS Office
  • MySQL
  • Network
  • Operating System
  • Performance
  • PostgreSQL
  • Productivity
  • Solidity
  • Vue.js
  • Web
  • Wireless
  • 🐧 How Linux Works (notes)
  • 🐧 Linux Kernel Comments (notes)
  • 🐧 Linux Kernel Development (notes)
  • 🐤 μc/OS-II Source Code (notes)
  • ☕ Understanding the JVM (notes)
  • ⛸️ Redis Implementation (notes)
  • 🗜️ Understanding Nginx (notes)
  • ⚙️ Netty in Action (notes)
  • ☁️ Spring Microservices (notes)
  • ⚒️ The Annotated STL Sources (notes)
  • ☕ Java Development Kit 8
GitHub
  • 🐧 Linux Kernel Comments
    • Chapter 2 - 微型计算机组成结构

      • Chapter 2 - 微型计算机组成结构
    • Chapter 3 - 内核编程语言和环境

      • Chapter 3 - 内核编程语言和环境
    • Chapter 4 - 80X86 保护模式及其编程

      • Chapter 4.1-4.2 - 80X86 系统寄存器和系统指令 & 保护模式内存管理
      • Chapter 4.3 - 分段机制
      • Chapter 4.4 - 分页机制
      • Chapter 4.5 - 保护
      • Chapter 4.6 - 中断和异常处理
      • Chapter 4.7 - 任务管理
      • Chapter 4.8 - 保护模式编程初始化
      • Chapter 4.9 - 一个简单的多任务内核实例
    • Chapter 5 - Linux 内核体系结构

      • Chapter 5.1-5.2 - Linux 内核模式 & 体系结构
      • Chapter 5.3 - Linux 内核对内存的管理和使用
      • Chapter 5.4-5.6 - 中断机制 & 系统调用 & 系统时间和定时
      • Chapter 5.7-5.9 - Linux 进程控制 & 堆栈使用 & 文件系统
    • Chapter 6 - 引导启动程序 (boot)

      • Chapter 6 - 引导启动程序 (boot)
    • Chapter 7 - 初始化程序 (init)

      • Chapter 7 - 初始化程序 (init)
    • Chapter 8 - 内核代码

      • Chapter 8.1 - 内核代码总体功能
      • Chapter 8.2 - asm.s 程序
      • Chapter 8.3 - traps.c 程序
      • Chapter 8.4 - sys_call.s 程序
      • Chapter 8.5 - mktime.c 程序
      • Chapter 8.6 - sched.c 程序
      • Chapter 8.7 - signal.c 程序
      • Chapter 8.8 - exit.c 程序
      • Chapter 8.9 - fork.c 程序
      • Chapter 8.10 - sys.c 程序
    • Chapter 9 - 块设备驱动程序

      • Chapter 9.1 - 块设备驱动程序 总体功能
      • Chapter 9.2 - blk.h 文件
      • Chapter 9.3 - hd.c 程序
      • Chapter 9.4 - ll_rw_blk.c 程序
      • Chapter 9.5 - ramdisk.c 程序
    • Chapter 10 - 字符设备驱动程序

      • Chapter 10.1 - 字符设备驱动程序 总体功能
      • Chapter 10.2 - keyboard.S 程序
      • Chapter 10.3 - console.c 程序
      • Chapter 10.4 - serial.c 程序
      • Chapter 10.5 - rs_io.s 程序
      • Chapter 10.6 - tty_io.c 程序
      • Chapter 10.7 - tty_ioctl.c 程序
    • Chapter 12 - 文件系统

      • Chapter 12.1 - 文件系统 总体功能
      • Chapter 12.2 - buffer.c 程序
      • Chapter 12.3 - bitmap.c 程序
      • Chapter 12.4 - truncate.c 程序
      • Chapter 12.5 - inode.c 程序
      • Chapter 12.6 - super.c 程序
      • Chapter 12.7 - namei.c 程序
      • Chapter 12.9 - block_dev.c 程序
      • Chapter 12.10 - file_dev.c 程序
      • Chapter 12.11 - pipe.c 程序
      • Chapter 12.12 - char_dev.c 程序
      • Chapter 12.13 - read_write.c 程序
      • Chapter 12.14 - open.c 程序
      • Chapter 12.15 - exec.c 程序
      • Chapter 12.16 - stat.c 程序
      • Chapter 12.17 - fcntl.c 程序
      • Chapter 12.18 - ioctl.c 程序
      • Chapter 12.19 - select.c 程序

Chapter 4.9 - 一个简单的多任务内核实例

Created by : Mr Dk.

2019 / 08 / 01 21:54

Nanjing, Jiangsu, China


4.9 一个简单的多任务内核实例

4.9.1 多任务程序结构和工作原理

内核实例由两个程序构成:

  • 引导启动程序 boot.s:系统上电时,从启动盘上把内核代码加载到内存中
  • 内核程序 head.s
    • 两个在特权级 3 上运行的任务
    • 在屏幕上显示字符的系统调用

boot.s 编译出的代码共 512B,存盘在软盘映像文件的第一个扇区中。ROM BIOS 会将启动盘第一扇区加载到物理内存 0x7c00 处,把执行权转移到此处,开始运行 boot 程序代码。

boot 程序的主要功能:

  • 利用 ROM BIOS 中断 int 0x13 将 head 代码读入内存 0x10000 (64KB) 处

  • 将这段代码移动到内存 0 处

    不能直接将 head 代码读到内存 0 处,因为加载操作需要用到 ROM BIOS 的中断,而中断向量表正好位于内存 0 处,且内存 1KB 开始处是 BIOS 程序使用的数据区。

  • 设置好临时 GDT 表,设置 CR0 PE 进入保护模式

  • 跳转到内存 0 处开始执行 head 代码

head 程序运行在 32-bit 保护模式下,包含:

  • 初始化代码
    • 重新设置 GDT
    • 设置系统定时器芯片
    • 重新设置 IDT 表,并设置时钟和系统调用的中断门
    • 跳转到任务 A 中
  • 时钟中断 int 0x08 的处理程序
  • 系统调用中断 int 0x80 的处理程序
  • 任务 A 和任务 B 的代码数据

虚拟地址空间分配:

4-41

最终的映像文件组织方式:

4-42

在初始化结束后,利用 IRET 指令来启动运行第一个任务。因为控制权不能从特权级 0 的代码直接转移到特权级 3 的代码中。在初始堆栈中人工设置一个返回环境

  • 将任务 0 的 TSS 段选择符加载到 TR,LDT 段选择符加载到 LDTR 中
  • 将任务 0 的用户栈指针、代码指针、EFLAGS 压入栈中
  • 执行 IRET
  • 弹出堆栈上的堆栈指针作为任务 0 的用户栈指针
  • 恢复任务 0 的 EFLAGS
  • 弹出 CS:EIP 从而开始执行任务 0 的代码

为了每隔 10ms 切换正在运行的任务:

  • 将 8253 的通道 0 设置为每经过 10ms 向 8259 发送时钟中断信号
  • ROM BIOS 开机时已经在 8259 中将时钟中断请求号设置为 8
  • 在中断 8 的处理函数中执行任务切换操作
  • 查看 current 变量中的任务号,如果是 0,就利用任务 1 的 TSS 选择符远跳转到任务 1;反之亦然
  • 每个任务中,将字符的 ASCII 放入寄存器 AL,调用系统调用中断 int 0x80
  • 中断处理程序调用一个字符写屏子程序,将 AL 中的字符显示在屏幕上,同时记录字符显示的下一个位置
  • 使用循环语句延迟一段时间,继续循环执行,直到 10ms 时间片用尽

任务 0 的字符始终为 A,任务 1 的字符始终为 B


4.9.2 引导启动程序 boot.s

4.9.3 多任务内核程序 head.s

Edit this page on GitHub
Prev
Chapter 4.8 - 保护模式编程初始化