- 29
- 0
- 约 35页
- 2017-09-27 发布于海南
- 举报
linux的启动过程;从开机加电到main函数之前的过程;bios的启动原理简单叙述 ;加载第一部分代码--引导程序(bootsect); 这个程序将引导程序加载到0X07C00处。
为什么是0X07C00处??
;加载第二部分代码--SETUP;2 复制bootsect;movw
jmpi go, INITSEG
go:mov ax, cs
mov ds, ax
这是一段很有趣的代码,大家看看,自己先分析分析!!;将Setup程序加载到内存中;加载system模块;现在bootsect的任务已经完成 下面通过jmpi 0, SETUPSEG这条语句跳转至0X90200处(setup处),开始执行setup。
setup利用BIOS程序提取内存运行的所需系统数据这些数据将覆盖bootsec程序所在区域。共510个字节,这种方式对内存的使用率极为高效。
到目前为止操作系统内核的加载工作已经完成。接下来系统通过加载到内存中的代码,将实现从实模式到保护模式的转换。
;开始向32位模式转变,为main函数的调用做准备;rep
movsw
jmp do_move
理解这样做的意义吗???;设置中断描述符表和全局描述符表; .word 0,0
gdt_48:
.word 0x800
.word 512 + gdt , 0x9
GDT表对保护模式下管理段描述符有重大意义!
;接下来打开A20实现32位寻址,并将CR0寄存器的第0位设置为1(开启保护模式)
代码如下:
mov ax , #0x0001
lmsw ax
jmpi 0, 8 ;;;从main到怠速 ;第一阶段:创建进程0,并让进程0具备32位保护模式下的主机运算能力。
第二阶段:以进程0为母本创建进程1,进程1还能以文件的方式与外设进行数据交互
第三阶段:以进程1为母本创建进程2,进程2在全面具备进程1所拥有的能力和环境的基础上,进一步具备支持“人机交互”的能力,最终实现怠速。;作为一个支持多进程的现代操作系统,意味着各个用户程序在运行的过程中,彼此不能干扰,才能保证正常的运转。然而,进程自身并没有一个天然的“边界”,所以需要人为的设计一套“边界”来保护它,这套边界就是为进程提供的进程管理数据结构,包括:进程管理结构(task_struct),进程槽(tase[])和GDT等。task_struct是每个进程所独有的,它标识了进程的各项属性,包括剩余时间片,进程状态等,task存储着系统所以进程的task_struct结构的指针。;物理内存的规划;
;系统对除了内核的数据域外是使用分页管理的,于是使用一个叫mem_map[]的数组记录每个页面的使用次数。
为啥不对内核数据区进行分页管理呢??
;进程0创建前的准备工作;经过一系列的准备工作进程0具备了在主机上执行的能力,接下来进程就可以工作了,进程0这时就做了一件事,创建进程1.;main.c 中对fork()的声明:static inline _syscall0(int, fork);
static inline _syscall0(type , name)
{
long __res;
__asm__ volatile (int $0X80 : =a (__res)
:0 (__NR__##name));
if (__res = 0)
return (type) __res;
errno = -__res;
return -1;
};接着在进程槽中为进程1申请一个空闲的位置并获取进程号,
先调用fing_empty_process函数,为这个进程获得一个可用的进程号和一个空闲的任务号。
接下来将进程0的管理数据结构拷贝给进程1的管理结构,调用copy_process()来实现的,这些内容作为进程1管理结构的雏形。具体执行如下:
调用get_free_page函数, 在主内存末端申请一个空闲页面具体代码如下:;; ...
p-pid = last_pid;
p-father = current-pid;
p-counter = p-priority;
p-signal = 0;
p-alaem = 0;
/*还要将进程1的TSS 中的成员进行初始化,等 等工作.*/
...
};接下来设置进程1的线性地址空间及物理页面。每个进程都有可能加载自己的代码,这些代码主要占主内存的空间。
所以这里要为进程1设置页目录项,以及为其创建页表,并将进程0的页表项复制给进程1的项表中,以此为进程1将来执行代码创造条件。创建页目录项和复制页表,使用copy_mem函数来完成的。在此不做赘述。进程1此时还没有对应的代码,,它与进程0管理的页面暂时完全一致,等将来有了自己的代码时,再把
原创力文档

文档评论(0)