[操作系统理论] 1, 操作系统的启动

一, 执行BIOS程序

x86 PC刚开机的时候, CPU处于实模式, 实模式和保护模式相对应, 实模式的寻址是cs:ip (CS左移4位+ip). 开机时, cs=0xFFFF, ip=0x0000, 也就是说cpu从0xFFFF0地址处开始执行, 但是我们发现0xFFFF0这个地址距离0xFFFFF只有16个字节, 这16个字节并不能做什么事情, 所以在0xFFFF0处的指令是一个跳转指令 jmp far f000:e05b 跳转到对应的地址处执行. 这里的代码具体的任务是检查硬件, 如RAM, 键盘, 显示器, 软盘, 硬盘等. 如果电脑的这些硬件没有什么问题, 就将启动设备(可以是磁盘, 软盘, U盘等, 这可以在BIOS菜单中设置)的0磁道0扇区的512个字节的代码读入到0x7c00处, 然后设置cs=0x7c0, ip=0x0000, CPU就从0x7c00处开始执行了

二, 操作系统的引导(1)

在磁盘的0磁道1扇区中处的程序对应的源代码是bootsect.s  下面是对这个程序代码的简要分析:

......

_start:
    ! bootsect模块是在内存中的0x7c00处
    ! 先把bootsect模块自身拷贝到内存中的0x90000处
    ! 然后在0x9000段里继续向下执行
    mov    ax,#BOOTSEG       ! BOOTSEG  = 0x07c0
    mov    ds,ax
    mov    ax,#INITSEG       ! INITSEG  = 0x9000
    mov    es,ax
    mov    cx,#256
    sub    si,si
    sub    di,di
    rep
    movw
    jmpi    go,INITSEG    

go:    mov    ax,cs
    mov    ds,ax
    mov    es,ax

    ! 把0磁道2扇区开始的4个扇区的程序读入到0x90200处, 这个模块的名字叫做setup
load_setup:
    mov    dx,#0x0000
    mov    cx,#0x0002
    mov    bx,#0x0200
    mov    ax,#0x0200+SETUPLEN       ! SETUPLEN = 4
    int    0x13

    jnc    ok_load_setup
    mov    dx,#0x0000
    mov    ax,#0x0000
    int    0x13
    j    load_setup

ok_load_setup:

    ......

    ! 获取光标位置
    mov    ah,#0x03
    xor    bh,bh
    int    0x10

    ! 打印启动信息到屏幕上
    mov    cx,#24
    mov    bx,#0x0007
    mov    bp,#msg1
    mov    ax,#0x1301
    int    0x10

    mov    ax,#SYSSEG
    mov    es,ax
    call    read_it
    ......

! 读入system模块到0x10000处, 此处代码比较复杂, 省略了read_it:
    ......

msg1:
    .byte 13,10
    .ascii "Loading system ..."
    .byte 13,10,13,10

......

总结一下bootsect模块的主要任务:

1, bootsect模块本身是在内存的0x7c00处

2, 首先将bootsect模块自身复制到0x90000处

3, 将setup模块复制到0x90200处

4, 显示一些欢迎进入系统的信息

5, 将system模块复制到0x10000处

此时, 内存中的情况如下:

三, 操作系统的引导(2)

在磁盘的0磁道2扇区到5扇区中处的程序对应的源代码是setup.s. 下面是对这个程序代码的简要分析:

......

start:

    ! 取出光标位置的信息, 存放到地址0x90000处
    mov    ax,#INITSEG     ! INITSEG = 0x9000
    mov    ds,ax
    mov    ah,#0x03
    xor    bh,bh
    int    0x10
    mov    [0],dx

    ! 取出内存大小的信息, 存放到地址0x90002处
    mov    ah,#0x88
    int    0x15
    mov    [2],ax
    ......

    ! 将system模块移动到地址0x0处
do_move:
    mov    es,ax        ! destination segment
    add    ax,#0x1000
    cmp    ax,#0x9000
    jz    end_move
    mov    ds,ax        ! source segment
    sub    di,di
    sub    si,si
    mov     cx,#0x8000
    rep
    movsw
    jmp    do_move

end_move:
    mov    ax,#SETUPSEG
    mov    ds,ax
    lidt    idt_48        ! 将IDT表的地址存放到LDTR寄存器中
    lgdt    gdt_48        ! 将GDT表的地址存放到GDTR寄存器中

    ! 切换到保护模式
    mov    ax,#0x0001    ! CR0寄存器的第0位如果为0表示启动实模式, 为1表示启动保护模式,
    lmsw    ax        ! 启用保护模式. 这个可以替换为mov cr0,ax 用lmsw是为了兼容以前的CPU

    ! ip的值为0, cs的值为8(0b0000,0000,0000,10000)
    ! 在保护模式下, cs表示选择子, 即GDT表的索引
    ! 通过查GTD表可以知道基址为0, 即跳转到0x0地址处开始执行
    jmpi    0,8        

    ! 初始化GDT表
gdt:
    .word    0,0,0,0
    .word    0x07FF, 0x0000, 0x9A00, 0x00C0
    .word    0x07FF, 0x0000, 0x9200, 0x00C0

    ! idt是保护模式下的中断函数表
idt_48:
    .word    0            ! idt limit=0
    .word    0,0            ! idt base=0L

    ! gdt是全局描述符表
gdt_48:
    .word    0x800        ! gdt limit=2048, 256 GDT entries
    .word    512+gdt,0x9    ! gdt base = 0X9xxxx

    ......

总结一下setup模块的主要任务:

1, 读取硬件相关的信息, 并将这些信息存储到0x9000处

2, 将system模块复制到0x0000处

3, 从实模式切换到保护模式

4, 跳转到0x0000处开始执行system模块

至此, 操作系统的引导就完成了

时间: 2024-08-29 10:23:42

[操作系统理论] 1, 操作系统的启动的相关文章

#23 centos5(RHEL)系列操作系统的启动流程、与命令mkinitrd、dracut的使用

centos(RHEL)系列操作系统的启动流程:Intel x86兼容架构: Linux的系统组成:内核 + 应用程序  GUN/Linux:单纯的指Linux内核: 从硬盘存储和启动操作系统的角度: Linux的系统组成:内核 + 根文件系统(rootfs) 内核功能:进程管理,文件系统管理,内存管理,网络协议,驱动程序,安全功能,... Linux系统的系统运行环境可以分为两部分: 内和空间:内核代码(系统调用) 就是内核进程占用的CPU和内存资源的总和: 用户空间:应用程序(进程或线程)

Linux操作系统的启动

最近一直在看0.12版本的内核,一直想实现一个简单的多任务内核,发现还真得先了解linux操作系统的启动过程. 1.BIOS 开机程序被写入ROM当中,计算机通电之后的第一件事就是读取它. 这块芯片里的程序叫做基本输入输出系统,简称BIOS 1.1硬件自检 检查计算机硬件能否满足运行的基本条件,这叫做硬件自检 1.2启动顺序 硬件自检完成之后,BIOS就把控制权转交给下一阶段的启动程序. 这时,BIOS需要知道,"下一阶段的启动程序"具体放在那里.也就是说,BIOS需要有一个外部存储设

操作系统理论

操作系统理论: 1. 操作系统是什么? 操作系统是一个协调\管理\控制计算机硬件资源与应用软件资源的一段控制程序 有两大功能: 1. 将复杂的硬件操作封装成简单的接口给应用程序或者用户去使用 2. 将多个进程对硬件的竞争变得有序 操作系统发展史 并发: 多个任务看起来是同时运行的 串行:一个任务完完整整地运行完毕,才能运行下一个任务 多道技术:(复用=>共享/共用) 1. 空间上的复用:多个任务复用内存空间 2. 时间上的复用:多个任务复用cpu的时间 1. 一个任务占用cpu时间过长会被操作系

linux操作系统的启动流程--学生作业

首先,先不急着将启动流程,,先说下linux操作系统的相关知识 一:linux的组成部分: 内核+根(/)文件系统 1)内核: 存放位置 centos6的位置是 /boot 目录下的"vmlinuz-2.6.32-573.12.1.el6.x86_64" "2.6.32"是版本号:"573.12.1"是release号.内核的作用是负责核心的内存管理.进程管理.网络协议栈.文件系统.驱动程序.安全功能.linux内核是单内核设计,但是他支持多模块

4月23日 python学习总结 套接字UDP和 操作系统理论,多道理论

一.套接字UDP udp是无链接的,先启动哪一端都不会报错 UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务.不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了. 即面向消息的通信是有消息保护边界的.   服务器 #服务器 ss = socket

我是如何学习写一个操作系统(三):操作系统的启动之保护模式

前言 上一篇其实已经说完了boot的大致工作,但是Linux在最后进入操作系统之前还有一些操作,比如进入保护模式.在我自己的FragileOS里进入保护模式是在引导程序结束后完成的. 实模式到保护模式属于操作系统的一个大坎,所以需要先提一下 从实模式到保护模式 实模式和保护模式都是CPU的工作模式,它们的主要区别就是寻址方式 实模式出现于早期8088CPU时期.当时由于CPU的性能有限,一共只有20位地址线(所以地址空间只有1MB),以及8个16位的通用寄存器,以及4个16位的段寄存器.所以为了

#24 centos6(RHEL)系列操作系统的启动流程、与命令chkconfig、grub的使用

所有由rc脚本关闭或启动的链接文件的原文件都存在于/etc/rc.d/init.d,系统为了方便使用,为此目录创建了链接/etc/init.d 所有/etc/inid.d(/etc/rc.d/init.d)目录中的脚本执行方式: # /etc/init.d/srv_script {start|stop|restart|status} # service srv_script {start|stop|restart|status} chkconfig命令: chkconfig - updates

#25 centos7(RHEL)系列操作系统的启动流程、systemd的特性、与命令systemctl的使用

systemd的新特性: 1.在系统引导的时候可以实现服务的并行启动: 2.能够实现按需激活进程: 在系统启动时,需要随系统启动服务,其服务进程并没有启动,但是systemd为每一个此类服务进程都注册了对应的套接字:我们称这种服务处理方式为"半激活状态": 3.能够对当前系统的用户空间的每个进程状态快照:以后如果进程出现问题或故障,可以迅速恢复进程状态至过去的某一时刻: 4.systemd内部有一种基于依赖关系来定义的服务控制逻辑: 核心管理概念:unit文件 由systemd相关的配

[操作系统理论] 2, 系统调用的实现

一, 操作系统的保护机制 1, 直观的想法 假设有一个系统调用whoami(), 这个系统调用的功能是显示出当前计算机的所有者. 假设这台计算机是我的, 那么在操作系统的内核部分的内存中的某一个地方存放着我的名字: "aixiangfei", 假设这个内存的地址是100. 对于whoami()的实现, 最直观的想法就是: 直接把地址100处的字符串复制过来, 然后打印到到屏幕上. 如果真的是这种实现方法, 那么这个操作系统是非常不安全的! 比如说: 我们的密码肯定也是被保存在了操作系统