关于miniOS的介绍
http://www.linuxidc.com/Linux/2012-07/64876.htm
本实验源码包含三部分:
miniOS源码:miniOS_xxxx(开发板名)工程目录下。
miniOS应用程序跑马灯:miniOS_app_led工程目录下。
miniOS应用程序打印程序:miniOS_app_print工程目录下。
miniOS源码 与 程序下载:
免费下载地址在 http://linux.linuxidc.com/
用户名与密码都是www.linuxidc.com
具体下载目录在 /2012年资料/7月/10日/小型多任务操作系统miniOS的实现/
操作步骤:
(1)在ADS下编译miniOS_xxxx工程,选择Norflash启动,然后通过H-Jtag将minios_org.bin烧写到Norflash中0地址处。
(2)编译应用程序miniOS_app_led和miniOS_app_print,选择Norflash启动,通过H-Jtag将miniOS_app_print.bin烧写到0x10000地址处,将miniOS_app_led.bin烧写0x20000地址处。
(3)启动开发板,可以看到miniOS启动信息。miniOS最多同时支持62个进程执行(在2440开发板64M内存上),miniOS启动完毕之后,默认只有系统内核进程在执行,可以通过按K1键,新创建进程,最多创建62个,按K2键,随机杀死一个进程,按K6键可以启动跑马灯进程。
(4)如果读者想写一个程序,让miniOS启动它,则根据编写规则,编写程序,如果需要系统调用,还要自己实现系统调用接口。
分析miniOS代码分为下面章节:
1. miniOS内存分布
2. 重要头文件说明
3. 启动代码分析
4. MMU与内存保护的实现
5. 内核定时器与中断处理
6. CPU模式切换
7. 进程调度与上下文切换技术
8. 软件中断与系统调用
9. 系统调试、优化及可改进地方
下面来看下第1节:
miniOS V2.0内存分布图:
Linux内核中内核地址空间分为:
- 直接内存映射区(Direct Memory Region)即:低端物理内存
- 动态内存映射区(VMalloc Region)即:高端物理内存
- 其它映射区
miniOS里,虚拟地址空间分为两大部分:
- 用户程序空间:0x0 ~ 0x80000000
- 内核管理空间:0x80000000 ~ 0xC0000000
>> 用户程序空间每个进程使用其中的32M虚拟地址空间,其空间地址和其PID有如下关系:
PID * 32M = PID的进程空间
其中,0~32M空间为0号进程空间,其实是当前正在运行的地址空间。
之所以这么设计,是因为ARM CPU在开启了MMU之后,将低于32M的地址作为进程内空间,当地址高于32M时,MMU会将其进行地址转换,具体内容,请参考:MMU与内存管理章节。
每个进程空间为32M,将来进行进程切换时,只需要按照上面定义的关系,线性偏移即可,减少进程切换时的复杂度。
每个进程的实际物理内存空间为1M,也就是说每个进程只有1M的物理地址空间,当用户程序超过1M时,程序不能运行(当然还没有超过1M的程序),它们的映射关系如下所示:
0x30000000 ~ 0x34000000 —-> 0x0 ~ 0x80000000
>> 内核管理地址空间又可以细分为以下几个部分:
- 物理内存完全映射区:0x80000000 ~ 0x84000000
- 外设寄存器地址映射区:0x98000000 ~ 0xB0000000
- 启动ROM映射区:0xC0100000 ~ 0xC0000000
>> 物理内存完全映射区,主要用于管理进程实际地址空间,它其实是0x30000000 ~ 0x80000000的一个线性偏移地址(0x50000000),当我们需要在内核空间里操作用户空间时,使用该完整映射区,非常方便操作,比如:加载程序到进程空间时,只需通过简单的计算即可知道其虚拟地址。
例如:启动5号进程时,其物理地址放在0x30000000开始的第5M空间里,那么其虚拟地址为0x30000000 + 5M + 0x50000000(偏移地址)。
>> 外设寄存器地址映射区,用来操作外设寄存器,当使用到外设寄存器时,可以通过简单的加减运算可以得到其虚拟地址。
>> 启动ROM映射区,用来映射NOR FLASH。
物理内存空间结构:
由上图可知,0号进程物理空间里(0x30000000 ~ 0x30100000),其实除了存放os代码外,还有其它的用途。
- 页表放到了内存地址0x30000000处
- OS代码放到了0x300F0000,该地址是故意而为之
最开始的1MB物理内存地址0x30000000~0x30100000为0号内核进程地址空间,其实就是OS代码区和内核栈区及页表区。
由于OS代码放到了物理内存0x300F0000处,其被映射到虚拟地址0x800F0000处,所以ADS里设置的OS代码的运行地址为0x800F0000