《操作系统-工作原理与移植方法介绍.ppt》由会员分享,可在线阅读,更多相关《操作系统-工作原理与移植方法介绍.ppt(31页珍藏版)》请在三一办公上搜索。
1、操作系统-工作原理与移植方法介绍,毕业设计,一、PC机操作系统工作原理简要介绍,1.计算机从加电开始都做了什么?,2.引导程序BIOS将磁盘的第一个扇区(磁盘最开始的512字节)载入内存,放在0 x0000:0 x7c00处,并且这个扇区的最后两个字节是“55AA”,那么这就是一个引导扇区,这个磁盘也就是引导盘。这个大小为512字节 的程序就称为引导程序。如果最后两个字节不是“55AA”,那么BIOS就检查下一个磁盘驱动器。,2.1总结:引导程序所具有的特点1.它的大小是512字节,不能多也不能少,因为BIOS只读512字节到内存中去。2.它的结尾两字节必须是“55AA”,这是引导扇区的标志。
2、3.它总是放在磁盘的第一个扇区上(0磁头,0磁道,1扇区),因为BIOS只读第一个扇区。,2.2系统的内存安排(1M内存),3.CPU的实模式与保护模式3.1实模式下的物理地址实模式有20根地址线,能管理220=1M内存,实模式物理地址计算,3.2保护模式下的物理地址有32根地址线,能管理232=4G内存分页机制为了在有限的物理内存中使用4GB的空间,就需要使用分页机制。人们把物理内存分成许多页,同样也把整个4GB的线性地址空间分成大小相同的许多页。在线性地址空间中,当某些页被使用的时候,某些页可能没有被使用,操作系统可以让CPU 将没有被使用的页调出物理内存(存放在磁盘的某个地方,以备需要的
3、时候再次调入),而把需要使用的页调入,这样,虽然物理内存空间有限,但也几乎可以使用所有的线性地址空间了。这就称为从线性地址到物理地址的映射,这是一个多对一的映射,也就是说多个线性空间中的页对应一个物理空间中的页。,保护模式下的物理地址,4.进程管理进程是系统分配资源与调度运行的独立单位,它由一系列操作所组成,通过这些操作来完成指定的任务。多个进程的运行,就需要进程调度来管理,因为在大部分情况下只有一个CPU,也就是说同一时刻只能有一个进程在运行,其它进程处于休息状态。,进程调度实现原理:每个进程都有一个用来记录该进程允许的执行次数的变量。例如:A获得一个运行周期则减1,减到0就暂停A,运行B。
4、B减到0暂停B,运行C。直到所有的进程都被减到0,重新开始。在进程调度中,优先级高的先执行,低的后执行。这个图中的优先级为:进程A进程B进程C,二、Linux操作系统,1.Red Hat Linux 9.0安装,及简单使用介绍2.嵌入式Linux2.1内核下载地址2.2版本说明:例如,表示这个是Linux2.6版本内核。6为偶数代表这个内核包为稳定版,如果为奇数则为非稳定版。(一般下载偶数版),2.3 Linux 内核源代码的部分目录结构Linux arch 与CPU体系结构相关的部分 boot 系统引导汇编程序 fs 文件系统 include 头文件(*.h)asm 与CPU 体系结构相关的
5、部分 Linux 内核专用部分 init 内核初始化程序 lib 内核库函数 mm 内存管理程序,2.4 Linux的移植简介2.4.1 修改与CPU体系结构有关的文件修改与CPU有关的文件,使操作系统能够在嵌入式平台运行,或者下载安装ARM-Linux补丁文件,来自动修改相应文件。2.4.2 裁剪将操作系统的不需要的部分删除,增加原来没有的并且需要的程序,修改相应的调用文件,使裁剪有效。,2.4.3 建立ARM-Linux开发环境所需资源:1.x86架构PC机,装有Linux操作系统。2.ARM-Linux-toolchain,交叉编绎工具链,不同的工具链可以支持不同的语言,体系结构等。3.
6、与ARM平台相连的网线,用于将编绎后的文件传输到ARM平台。4.构建步骤:1.下载arm-linux-for-x86的toolchain,比如:arm-linux-for-x86.tar.gz 2.解压软件包并安装 tar zxvf arm-linux-for-x86.tar.gz cd arm-linux-for-x86./configure make 在PC机上安装标准Linux操作系统(例如Red Hat Linux),且要确保计算机的网卡驱动、网络通讯配置正常,在进行编译前还需修改相应的Makefile文件,使编译能够顺利通过。开发环境的建立参考嵌入式平台手册即可,三、uC/OSII嵌
7、入式系统移植,1.uC/OS-II操作系统及特点 它是专门为嵌入式应用而设计的,是稳定可靠的实时操作系统(RTOS)。uC/OS-II的主要特点有:可移植性、可裁减性、多任务性。,2.uC/OS-II移植需要修改的文件 由于设计uC/OS-II时就考虑到了在不同处理器上移植,因而移植uC/OS-II实际上需要修改的代码量很小,其中需要修改的部分只是与处理器相关部分的文件。,嵌入式系统结构图,2.1 修改os-cpu.h文件2.1.1 数据类型 其中数据类型定义代码是由于C语言中short、int、long等数据类型是与特定的处理器相关的,因此在uC/OS-II中需重新定义,增强它的可移植性。例
8、如:typedef unsigned char BOOLEAN;/*布尔变量*typedef unsigned char INT8U;*无符号8位整型变量*,2.1.2 堆栈单位 在任务切换时,寄存器的值会保存在当前运行任务的堆栈空间中,所以OS_STK数据类型应该和处理器的寄存器长度是一致的,定义如下:typedef unsigned int OS_ STK;/*堆栈入口宽度为32位*/,2.1.3 堆栈增长方向 堆栈由高地址向低地址增长,是和编译器有关的,当进行函数调用时,入口参数和返回地址一般都会保存在当前任务的堆栈中,编译器的编译选项和由此生成的堆栈指令就会决定堆栈的增长方向。#def
9、ine OS_STK_GROWTH 1/*定义堆栈的增长方向:1=向下,0=向上*/,2.1.4 宏定义 包括开关中断的宏定义及进行任务切换的宏定义。#typedef unsigned int OS_CPU_SR/*保存CPU状态寄存器*/#define OS_ENTER_CRITICAL()(cpu_sr=OS_CPU_SaveSR()/*禁止中断*/#define OS_EXIT_CRITICAL()(OS_CPU_RestoreSR(cpu_sr)/*允许中断*/#define OS_TAS_SW()OSCtrSw()/*任务切换*/,2.2 修改OS_CPU_C.C文件 这里涉及到任务
10、初始化时的一个堆栈设计,也就是在堆栈增长方向上如何定义每个需要保存的寄存器位置。在ARM体系结构下,处理器的现场通常是指pc、lr、r0r12、CPSR、SPSR这些寄存器,是否需要全部保存这些寄存器是由编译器的特性和实时性能的要求来决定的,因为并不是所有编译器都会用到R0R12通用寄存器,但为了处理简单,通常会将它们全部保存。,任务初始化函数(为每个任务申请一个堆栈空间)OS_STK*OSTaskStkInit(void(*task)(void*pd),void*p_arg,OS_STK*ptos,INT16U opt)OS_STK*stk;opt=opt;/*opt is not used
11、,prevent warning*/stk=ptos;/*Load stack pointer*/*(stk)=(OS_STK)task;/*Entry Point*/*(-stk)=/*0;/*LR*/*(-stk)=/*0;/*R12*/省略(R11R2)*(-stk)=/*0;/*R1*/*(-stk)=/*p_arg;/*R0*/*(-stk)=/*ARM_SVC_MODE;/*CPSR(激活IRQ和FIQ中断)*/*(-stk)=/*ARM_SVC_MODE;/*SPSR*/return(stk);,当前任务堆栈初始化完成后,OSTaskStklnit()返回新的堆栈指针stk,在O
12、STaskCreate()执行时将会调用OSTaskStkInit()的初始化过程,然后通过OS_TCBInit()函数调用,将返回的SP指针保存到该任务的TCB块(任务调度表)中。初始化堆栈其实是模拟了一次中断,因为任务被创建后并不是直接就获得执行的,而是通过OS_Sched()函数进行调度分配,满足执行条件后才能获得执行的。为了使这个调度简单一致,就预先将该任务的pc指针和返回地址lr都指向函数入口,以便被调度时从堆栈中恢复刚开始运行时的处理器现场。,此外,在这个文件里面还需要实现如下几个操作系统规定的hook函数(系统钩子函数):OSTaskCreateHook()OSTaskDelHo
13、ok()OSTaskSWHook()OSTaskStatHook()OSTimeTickHook()如果没有特殊需求,则可将它们改为空函数即可。,2.3 修改OS_CPU_A.S文件 用汇编语言编写4个与处理器相关的函数:OSStartHighRdy()/*运行优先级最高的就绪任务*/OSCtxSw()/*任务级的任务切换函数*/OSIntCtxSw()/*中断级的任务切换函数*/OSTickISR()/*中断服务函数*/,编写OSStartHighRdy()void OSStartHighRdy(void);调用用户定义的OSTaskSwHook()函数;获取任务的堆栈指针,使任务重新执行S
14、tack pointer=OSTCBHighRdy-OSTCBStkPtr;OSRunning=TRUE;/*正常的任务切换标志*/;从新的任务堆栈中恢复寄存器;中断返回该函数仅仅在多任务启动时被执行一次。用来启动第一个,也就是最高优先级的任务执行。,编写OSCtxSw()void OSCtxSw(void)保存处理器寄存器堆栈将当前任务的堆栈指针保存到当前任务的OS_TCB中OSTCBCur-OSTCBStkPtr=Stack pointer;调用用户定义的OSTaskSwHook();OSTCBCur=OSTCBHighRdy;OSPrioCur=OSPrioHighRdy;得到需要恢复的
15、任务的堆栈指针:Stack pointer=OSTCBHighRdy-OSTCBStkPtr;将所有处理器寄存器从新任务的堆栈中恢复出来出栈执行中断返回指令该函数用于任务级的切换。,编写OSIntCtxSw()void OSIntCtxSw(void)OSIntExit()调整堆栈指针(通知uC/OS-一个中断服务已执行完毕)将当前任务堆栈指针保存到当前任务的OS_TCB中OSTCBCur-OSTCBStkPtr=堆栈指针调用用户定义的OSTaskSwHook()OSTCBCur=OSTCBHighRdyOSPrioCur=OSPrioHighRdy得到需要恢复的任务的堆栈指针堆栈指针=OST
16、CBHighRdy-OSTCBStkPtr将所有处理器寄存器从新任务的堆栈中恢复出来执行中断返回指令,该函数的目的是能够尽快地让高优先级的任务得到响应,保证系统的实时性能。它的原理基本上与任务级的切换相同,由于进入中断时已经保存了被中断任务的CPU现场,因此这里就不用再进行类似的操作,只需要对堆栈指针做相应的调整。,编写OSTickISR()void OSTickISR(void)保存处理器寄存器;调用OSIntEnter()或者直接将 OSIntNesting加1;调用OSTimeTick();调用OSIntExit();恢复处理器寄存器;执行中断返回指令;该函数是时钟中断函数。C/OS-要求用户提供一个时钟资源来实现时间的延时或时钟中断功能。时钟中断应该每秒钟发生10100次。为了完成该任务,可以使用硬件时钟,也可以从交流电中获得50/60Hz的时钟频率。,3.使用ADS编译uCOS,-结束,更多信息请查阅相关资料,