操作系统开发系列—13.a.进程 ●】的更多相关文章

现在又出现了另外一个的问题,在中断处理过程中是否应该允许下一个中断发生? 让我们修改一下代码,以便让系统可以在时钟中断的处理过程中接受下一个时钟中断.这听起来不是个很好的主意,但是可以借此来做个试验. 首先,因为CPU在响应中断的过程中会自动关闭中断,我们需要人为地打开中断,加入sti指令:然后,为保证中断处理过程足够长,以至于在它完成之前就会有下一个中断产生,我们在中断处理例程中调用一个延迟函数.代码如下: extern delay hwint00: ; Interrupt routine f…
首先打开时钟中断: out_byte(INT_M_CTLMASK, 0xFE); // Master 8259, OCW1. out_byte(INT_S_CTLMASK, 0xFF); // Slave 8259, OCW1. 为了让时钟中断可以不停地发生而不是只发生一次,还需要设置EOI: hwint00: ; Interrupt routine for irq 0 (the clock). mov al, EOI ; `. reenable out INT_M_CTL, al ; / ma…
进程的切换及调度等内容是和保护模式的相关技术紧密相连的,这些代码量可能并不多,但却至关重要. 我们需要一个数据结构记录一个进程的状态,在进程要被挂起的时候,进程信息就被写入这个数据结构,等到进程重新启动的时候,这个信息重新被读出来. 在很多情况下,进程和进程调度是运行在不同的层级上的.这里本着简单的原则,我们让所有任务运行在ring1,而让进程切换运行在ring0. 诱发进程切换的原因不只一种,比较典型的情况是发生了时钟中断.但并非在每一次时钟中断时都一定会发生进程切换,不过这里为了容易理解和实…
我们再来添加一个任务,首先添加一个进程体: void TestC() { int i = 0x2000; while(1){ disp_str("C"); disp_int(i++); disp_str("."); delay(1); } } 然后在global.c: PUBLIC TASK task_table[NR_TASKS] = {{TestA, STACK_SIZE_TESTA, "TestA"}, {TestB, STACK_SIZE…
在我们的操作系统中,已经存在的3个进程是运行在ring1上的,它们已经不能任意地使用某些指令,不能访问某些权限更高的内存区域,但如果一项任务需要这些使用指令或者内存区域时,只能通过系统调用来实现,它是应用程序和操作系统之间的桥梁. 所以,一件事情就可能是应用程序做一部分,操作系统做一部分.这样,问题就又涉及特权级变换. 很明显,这已经难不倒我们了,因为进程的切换就是不停地在重复这么一个特权级变换的过程.在那里,触发变换的是外部中断,我们把这个诱因换一下就可以了,变成"int nnn",…
上面的三个进程都是延迟相同的时间,让我们修改一下,尝试让它们延迟不同的时间. void TestA() { int i = 0; while (1) { disp_str("A."); milli_delay(300); } } void TestB() { int i = 0x1000; while(1){ disp_str("B."); milli_delay(900); } } void TestC() { int i = 0x2000; while(1){…
计数器的工作原理是这样的:它有一个输入频率,在PC上是1193180HZ.在每一个时钟周期(CLK cycle),计数器值会减1,当减到0时,就会触发一个输出.由于计数器是16位的,所以最大值是65535,因此,默认的时钟中断的发生频率就是1193180/65536约等于18.2HZ. 我们可以通过编程来控制8253.因为如果改变计数器的计数值,那么中断产生的时间间隔也就相应改变了. 比如,如果想让系统每10ms产生一次中断,也就是让输出频率为100HZ,那么需要为计数器赋值为1193180/1…
进程此时不仅是在运行而已,它可以随时被中断,可以在中断处理程序完成之后被恢复.进程此时已经有了两种状态:运行和睡眠.我们已经具备了处理多个进程的能力,只需要让其中一个进程处在运行态,其余进程处在睡眠态就可以了. 在main.c中进程A的代码的下面添加进程B: void TestB() { int i = 0x1000; while(1){ disp_str("B"); disp_int(i++); disp_str("."); delay(1); } } 打印的字母…
1.前言 通过前面一系列文章的学习,我们对微信公众号开发已经有了一个比较深入和全面的了解. 微信公众号开发为企业解决那些问题呢? 我们经常看到微信公众号定制开发.微信公众平台定制开发,都不知道这些能给企业带来什么,让很多人产生疑惑,那么下面就来给你解答. 我们都知道微信公众号是微信推出的一款提资讯和服务的平台应用,但却需要通过微信公众号开发技术来真正实现平台化.那么,作为想通过移动互联网来发展业务,或者需要改变目前经营状况,解决当前发展瓶颈问题的企业.商家或个体商户来说,微信公众号是一个很好的实…
因为CPU只有一个,同一时刻要么是客户进程在运行,要么是操作系统在运行,如果实现进程,需要一种控制权转换机制,这种机制便是中断. 要做的工作有两项:设置8259A和建立IDT. /*======================================================================* init_8259A *======================================================================*/ PU…
org 07c00h ;伪指令,告诉编译器程序会被加载到7c00处 mov ax, cs mov ds, ax mov es, ax call DispStr ;调用显示字符串例程 jmp $ ;无限循环 DispStr: mov ax, BootMessage mov bp, ax ;ES:BP=字符串地址 mov cx, 22 ;CX=字符串长度 mov ax, 01301h ;AH=13,AL=01h mov bx, 000ch ;页号为0(BH=0)黑底红字(BL=0Ch,高亮) mov…
ELF文件的结构如下图所示: ELF文件由4部分组成,分别是ELF头(ELF header).程序头表(Program header table).节(Sections)和节头表(Section header table). 实际上,一个文件中不一定包含全部这些内容,而且它们的位置也未必如上图所示这样安排,只有ELF头的位置是固定的,其余各部分的位置.大小等信息由ELF头中的各项值来决定. ELF header的格式如下代码所示: #define EI_NIDENT 16 typedef str…
a.我们先来体验一下在Linux下用汇编编程的感觉,见代码 [section .data] ; 数据在此 strHello db "Hello, world!", 0Ah STRLEN equ $ - strHello [section .text] ; 代码在此 global _start ; 我们必须导出 _start 这个入口,以便让链接器识别 _start: mov edx, STRLEN mov ecx, strHello mov ebx, 1 mov eax, 4 ; sy…
一个操作系统从开机到开始运行,大致经历“引导—>加载内核入内存—>跳入保护模式—>开始执行内核”这样一个过程.也就是说,在内核开始执行之前不但要加载内核,而且还有准备保护模式等一系列工作,如果全都交给引导扇区来做,512字节很可能是不够用的,所以不妨把这个过程交给另外的模块来完成,我们把这个模块叫做Loader.引导扇区负责把Loader加载入内存并且把控制权交给它,其他工作放心地交给Loader来做,因为它没有512字节的限制,将会灵活得多. 为了操作方便,把软盘做成FAT12格式.这…
一直以来,我们把所有的段描述符都放在GDT中,而不管它属于内核还是用户程序,为了有效地在任务之间实施隔离,处理器建议每个任务都应当具有自己的描述符表,称为局部描述符表LDT,并且把专属于自己的那些段放到LDT中. 和GDT一样,LDT也是用来存放描述符的.不同之处在于,LDT只属于某个任务.或者说,每个任务都有自己的LDT,每个任务私有的段,都应当在LDT中进行描述.另外,LDT的第1个描述符,也就是0号槽位,也是有效的.可以使用的. [SECTION .gdt] ; GDT ; 段基址, 段界…
于是我换了一个思路来理解这个typedef 我们首先看常规的变量定义: int INT//定义了一个名为INT的int型变量. char *c//定义了一个名为c的char型指针变量 void(*Fun)(void);//定义了一个名为Fun的,返回值为void,无参数的函数指针 加上typedef以后,就可以理解为,原来的变量名变成了自己本身对应的类型名 如INT就代表了int类型 c就变成了char* Fun就代表了“返回值为void,无参数的函数指针”型 理解typedef的关键就是,别把…
8259A虽然已经设置完成,但是我们还没有真正开始使用它呢. 所有的中断都会触发一个函数spurious_irq(),这个函数的定义如下: PUBLIC void spurious_irq(int irq) { disp_str("spurious_irq: "); disp_int(irq); disp_str("\n"); } spurious_irq()其实什么也不做,仅仅是把IRQ号打印出来而已. 其实现在已经可以make并运行了,但是不会有什么效果,因为我…
先来看一个简单的Makefile,我们把它放在目录/boot下,可以用来编译boot.bin和loader.bin. # Makefile for boot # Programs, flags, etc. ASM = nasm ASMFLAGS = -I include/ # This Program TARGET = boot.bin loader.bin # All Phony Targets .PHONY : everything clean all # Default starting…
现在把esp.GDT等内容放进内核中,我们现在可以用C语言了,只要能用C,我们就避免用汇编. 下面看切换堆栈和GDT的关键代码: ; 导入函数 extern cstart ; 导入全局变量 extern gdt_ptr [SECTION .bss] StackSpace resb 2 * 1024 StackTop: ; 栈顶 ; 把 esp 从 LOADER 挪到 KERNEL mov esp, StackTop ; 堆栈在 bss 段中 sgdt [gdt_ptr] ; cstart() 中…
实际上,我们要做的工作是根据内核的Program header table的信息进行类似下面这个C语言语句的内存复制: memcpy(p_vaddr, BaseOfLoaderPhyAddr+p_offset, p_filesz); 复制可能不止一次,如果Program header有n个,复制就进行n次. 每一个Program header都描述一个段,语句中的P_offset为段在文件中的偏移,p_filesz为段在文件中的长度,p_vaddr为段在内存中的虚拟地址. 由ld生成的可执行文件…
现在,内核已经被我们加载进内存了,该是跳入保护模式的时候了. 首先是GDT以及对应的选择子,我们只定义三个描述符,分别是一个0~4GB的可执行段.一个0~4GB的可读写段和一个指向显存开始地址的段: ; GDT ; 段基址 段界限, 属性 LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符 LABEL_DESC_FLAT_C: Descriptor 0, 0fffffh, DA_CR|DA_32|DA_LIMIT_4K ;0-4G LABEL_DESC_FLAT_RW: D…
Loader要做两项工作,我们先来做第一项,把内核加载到内存: 1.加载内核到内存. 2.跳入保护模式. 首先编译无内核时: nasm boot.asm -o boot.bin nasm loader.asm -o loader.bin dd if=boot.bin of=a.img bs=512 count=1 conv=notrunc sudo mount -o loop a.img /mnt/hgfs/ sudo cp loader.bin /mnt/hgfs/ -v sudo umoun…
原文:[Xamarin开发 Android 系列 13] 应用打包部署 开始倒叙咯................ 先更新大宝部署吧,这个章节比较的Easy,童鞋们不用费脑筋.点解?从界面上填写几个参数,其他都是傻瓜式的[下一步],童鞋们是否喜欢.卤煮 反正很是受用. 我们开发好的程序,需要打包成 .apk,成为安卓的安装包.然后就可以通过下载的形式安装到 用户终端手机/平板/TV/Watch....... 发布程序 主要的还是将应用发布到 谷歌的官方商店 Google Play..再然后就是其…
原文:循序渐进学.Net Core Web Api开发系列[13]:中间件(Middleware) 系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇介绍如何使用中间件(Middleware). 二.初步演练 先写几个中间件 public class DemoAMiddleware { private readonly RequestDelegate _…
懒骨头(http://blog.csdn.net/iamlazybone QQ:124774397 ) 写下这些东西的同时 旁边放了两部电影 周星驰的<还魂夜> 甄子丹的<特殊身份> 骨头听着电影读代码 别有一番风味 接上篇,今天继续看一下这个demo. -------------------------------------------------------------------------------------------------------------------…
系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇介绍如何使用中间件(Middleware). 二.初步演练 先写几个中间件 public class DemoAMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public Dem…
概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力的.今天就会给大家介绍这部分内容: Web请求和响应 使用代理方法 简化请求方法 图片缓存 扩展--文件分段下载 扩展--文件上传 NSURLSession 数据请求 文件上传 文件下载 会话 UIWebView 浏览器实现 UIWebView与页面交互 网络状态 Web请求和响应 使用代理方法 做…
C#设计模式总结 一. 设计原则 使用设计模式的根本原因是适应变化,提高代码复用率,使软件更具有可维护性和可扩展性.并且,在进行设计的时候,也需要遵循以下几个原则:单一职责原则.开放封闭原则.里氏代替原则.依赖倒置原则.接口隔离原则.合成复用原则和迪米特法则.下面就分别介绍了每种设计原则. 1.1 单一职责原则 就一个类而言,应该只有一个引起它变化的原因.如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会影响到其他的职责.另外,把多个职责耦合在一起,也会影响复用性. 1.…
来自:http://www.cocoachina.com/ios/20150318/11364.html 概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地通知:另一类是推送通知,也叫远程通知.两种通知在iOS中的表现一致,可以通过横幅或者弹出提醒两种形式告诉用户,并且点击通知可以会打开应用程序,但是实现原理却完全不同.今天就和大家一块去看一下如何…
概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地通知:另一类是推送通知,也叫远程通知.两种通知在iOS中的表现一致,可以通过横幅或者弹出提醒两种形式告诉用户,并且点击通知可以会打开应用程序,但是实现原理却完全不同.今天就和大家一块去看一下如何在iOS中实现这两种机制,并且在文章后面会补充通知中心的内容避免初学者对两种概念的混淆. 本地通知 推送通…