热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

操作系统——底层结构与设计原理知识汇总

 JOS源文件安排:inc/  这个文件夹是一些include文件,即各种类型的头文件。       env.h      

 


JOS源文件安排:

inc/     这个文件夹是一些include文件,即各种类型的头文件。

            env.h       Public definitions for user-mode environments

            trap.h      Public definitions for trap handling

            syscall.h   Public definitions for system calls from user environments to the kernel

            lib.h       Public definitions for the user-mode support library

kern/   env.h       Kernel-private definitions for user-mode environments

            env.c       Kernel code implementing user-mode environments

            trap.h      Kernel-private trap handling definitions

            trap.c      Trap handling code

            trapentry.S Assembly-language trap handler entry-points

            syscall.h   Kernel-private definitions for system call handling

            syscall.c   System call implementation code

lib/       Makefrag    Makefile fragment to build user-mode library, obj/lib/libjos.a

            entry.S     Assembly-language entry-point for user environments

            libmain.c   User-mode library setup code called from entry.S

            syscall.c   User-mode system call stub functions

            console.c   User-mode implementations of putchar and getchar, providing console I/O

            exit.c      User-mode implementation of exit

            panic.c     User-mode implementation of panic

user/   *           Various test programs to check kernel lab 3 code


8086与80386寄存器对比:

 8086寄存器80386寄存器
通用寄存器

ax(accumulator), bx(base), cx(count), dx(data), 

bp(base pointer), sp(stack pointer), di(des index), si(src index)

eax, ebx, ecx, edx,

ebp, esp, edi, esi

段寄存器cs(code seg), ds(data seg), ss(stack seg), es(extra seg)cs, ds, ss, es, fs, gs
段描述符寄存器对程序员不可见
状态和控制寄存器flags, ip

eflags, eip,

cr0, cr1, cr2, cr3

系统地址寄存器gdtr, idtr, tr, ldtr
调试寄存器dr0-dr7
测试寄存器tr0-tr7

“访存”指令中给定地址值(16位),CPU将其送往地址线(20位)。在8086时代,在把地址送往地址线之前,CPU会把它与某个段寄存器中的值相加:实际物理地址 = (段寄存器 <<4) + 偏移地址——从而实现了从16位内存地址到20位实际地址的映射。

到80286时代,引入了一个全新理念:“保护模式”,它的引入给寻址方式、中断管理都带来了变化。从此,我们把之前的段式管理方法称为“实模式”。

1)实模式下段的管理

实模式下一共有8种寻址方式:

立即数寻址 
寄存器寻址 
直接寻址 
寄存器间接寻址 
基址寻址 
变址寻址 
基址加变址 
带位移的基址加变址寻址 

本质上实模式下的寻址方式都是段基址左移4位加上偏移。

2)保护模式下段的管理

在保护模式下,利用一个段选择子(本质上是在一组段描述符数组中的下标或者说索引)到全局描述符表(一组段描述符构成的数组)中找到所需的段描述符(本质上是个结构体,它有三个成员变量:段物理首地址、段界限、段属性),而这个段描述符中就存放着真正的段的物理首地址,然后再加上偏移量得到最后的物理地址。

实际物理地址 = selector + offset,其中selector是16位的用于在GDT中索引,offset是32位的。

当发生内存寻址与定位时,处理器通过GDTR寄存器找到GDT,并通过selector找到对应的描述符,今儿得到该段的起始地址,最后加上偏移得到实际地址。 

 

kern/init.c:
入口:
void i386_init(void){
cons_init(); //命令台初始化
kern/console.c:
{
cga_init();
kbd_init();
serial_init();
}

mem_init(); //内存管理初始化
kern/pmap.c:
{
i386_detect_memory();
kern_pgdir = boot_alloc();
pages = boot_alloc();
envs = boot_alloc();
page_init();
boot_map_region( .pages. );
boot_map_region( .envs. );
boot_map_region( .bootstack. );
boot_map_region( .0. );
lcr3(PADDR(kern_pgdir));
}
env_init(); //进程管理初始化
kern/env.c:
{
... //建立envs数组
env_init_percpu(); //载入GDT和段描述符
}
trap_init(); //进程管理初始化:中断处理
kern/trap.c:
{
SETGATE(); //建立中断描述符表
trap_init_percpu();
}
//创建进程,等同于env_create(_binary_obj_user_hello_start, ENV_TYPE_USER);
//这里的符号名‘_binary_obj_user_hello_start’是链接器在链接内核镜像时自动生成的
ENV_CREATE(user_hello, ENV_TYPE_USER);
kern/env.c:
{
env_alloc();
{
env_setup_vm(e); //为进程分配并建立页目录
... //生成env_id
... //设置基本状态变量
... //设置段寄存器初值
}
load_icode();
{
lcr3(PADDR(e->env_pgdir));
region_alloc(); //分配一定字节物理内存并映射到进程地址空间的某虚地址
{
page_alloc();
page_insert();
}
memmove();
memset();
lcr3(PADDR(kern_pgdir));
region_alloc();
}
}
env_run(&envs[0]); //运行进程,此函数不会返回,将不断循环直到销毁进程并退出
{
... //设置(需要时切换)当前curenv
lcr3(PADDR(curenv->env_pgdir));
env_pop_tf(); //这是进入用户模式前的最后一个函数
}
while(1) //陷入内核监控器
monitor(NULL);
}

env_pop_tf()函数的作用就是按Trapframe的结构将其从栈中恢复到各寄存器中去,最后执行iret指令,从而从内核退出并开始执行用户进程代码。

执行完 iret 后进入用户模式,跳往lib/entry.S中定义的 _start: 处,执行完一些准备工作后执行 call libmain。  

libmain()定义在lib/libmain.c中,在其中调用用户主程序:umain(),执行完用户程序后exit()。

umain()定义在user/hello.c中,在其中可能执行一些如cprintf()之类的库函数,这些函数本质上最终都会执行系统调用。

上述调用过程发生在用户态下,调用过程如下:

kern/env.c:
void env_pop_tf()
{
... //从栈中弹出Trapframe,恢复寄存器的值
iret //退出内核态,进入用户程序
}
--------------------内核态用户态分界线-------------------
lib/entry.S:
.text
.global _start
_start:
...
args_exist:
call libmain //调用库函数libmain
...
lib/libmain.c:
void libmain()
{
...
umain(); //调用用户主函数umain
exit();
}
user/hello.c:
void umain()
{
cprintf("hello world\n");
}

 


推荐阅读
  • 在Ubuntu系统中,由于预装了MySQL,因此无需额外安装。通过命令行登录MySQL时,可使用 `mysql -u root -p` 命令,并按提示输入密码。常见问题包括:1. 错误 1045 (28000):访问被拒绝,这通常是由于用户名或密码错误导致。为确保顺利连接,建议检查MySQL服务是否已启动,并确认用户名和密码的正确性。此外,还可以通过配置文件调整权限设置,以增强安全性。 ... [详细]
  • 在进行网络编程时,准确获取本地主机的IP地址是一项基本但重要的任务。Winsock作为20世纪90年代初由Microsoft与多家公司共同制定的Windows平台网络编程接口,为开发者提供了一套高效且易用的工具。通过Winsock,开发者可以轻松实现网络通信功能,并准确获取本地主机的IP地址,从而确保应用程序在网络环境中的稳定运行。此外,了解Winsock的工作原理及其API函数的使用方法,有助于提高开发效率和代码质量。 ... [详细]
  • Spring Batch 异常处理与任务限制优化策略 ... [详细]
  • PHP中元素的计量单位是什么? ... [详细]
  • 计算 n 叉树中各节点子树的叶节点数量分析 ... [详细]
  • BZOJ4240 Gym 102082G:贪心算法与树状数组的综合应用
    BZOJ4240 Gym 102082G 题目 "有趣的家庭菜园" 结合了贪心算法和树状数组的应用,旨在解决在有限时间和内存限制下高效处理复杂数据结构的问题。通过巧妙地运用贪心策略和树状数组,该题目能够在 10 秒的时间限制和 256MB 的内存限制内,有效处理大量输入数据,实现高性能的解决方案。提交次数为 756 次,成功解决次数为 349 次,体现了该题目的挑战性和实际应用价值。 ... [详细]
  • 本文作为“实现简易版Spring系列”的第五篇,继前文深入探讨了Spring框架的核心技术之一——控制反转(IoC)之后,将重点转向另一个关键技术——面向切面编程(AOP)。对于使用Spring框架进行开发的开发者来说,AOP是一个不可或缺的概念。了解AOP的背景及其基本原理,对于掌握这一技术至关重要。本文将通过具体示例,详细解析AOP的实现机制,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本项目在Java Maven框架下,利用POI库实现了Excel数据的高效导入与导出功能。通过优化数据处理流程,提升了数据操作的性能和稳定性。项目已发布至GitHub,当前最新版本为0.0.5。该项目不仅适用于小型应用,也可扩展用于大型企业级系统,提供了灵活的数据管理解决方案。GitHub地址:https://github.com/83945105/holygrail,Maven坐标:`com.github.83945105:holygrail:0.0.5`。 ... [详细]
  • 如何将PHP文件上传至服务器及正确配置服务器地址 ... [详细]
  • 深入解析 UIImageView 与 UIImage 的关键细节与应用技巧
    本文深入探讨了 UIImageView 和 UIImage 的核心特性及应用技巧。首先,详细介绍了如何在 UIImageView 中实现动画效果,包括创建和配置 UIImageView 实例的具体步骤。此外,还探讨了 UIImage 的加载方式及其对性能的影响,提供了优化图像显示和内存管理的有效方法。通过实例代码和实际应用场景,帮助开发者更好地理解和掌握这两个重要类的使用技巧。 ... [详细]
  • Python与R语言在功能和应用场景上各有优势。尽管R语言在统计分析和数据可视化方面具有更强的专业性,但Python作为一种通用编程语言,适用于更广泛的领域,包括Web开发、自动化脚本和机器学习等。对于初学者而言,Python的学习曲线更为平缓,上手更加容易。此外,Python拥有庞大的社区支持和丰富的第三方库,使其在实际应用中更具灵活性和扩展性。 ... [详细]
  • Java服务问题快速定位与解决策略全面指南 ... [详细]
  • 在CentOS上部署和配置FreeSWITCH
    在CentOS系统上部署和配置FreeSWITCH的过程涉及多个步骤。本文详细介绍了从源代码安装FreeSWITCH的方法,包括必要的依赖项安装、编译和配置过程。此外,还提供了常见的配置选项和故障排除技巧,帮助用户顺利完成部署并确保系统的稳定运行。 ... [详细]
  • 开发心得:深入探讨Servlet、Dubbo与MyBatis中的责任链模式应用
    开发心得:深入探讨Servlet、Dubbo与MyBatis中的责任链模式应用 ... [详细]
  • 在Java中,匿名函数作为一种无名的函数结构,无法独立调用;而在JavaScript中,不仅有类似的匿名函数,还有立即执行函数(IIFE)和闭包等高级特性。立即执行函数同样基于匿名函数实现,但会在定义时立即执行,而闭包则通过嵌套函数来捕获外部变量,实现数据封装和持久化。这些不同的函数形式在实际开发中各有应用场景,理解其特点有助于更好地利用语言特性进行编程。 ... [详细]
author-avatar
小仙女
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有