首页 > 其他分享 >【操作系统】1.操作系统启动

【操作系统】1.操作系统启动

时间:2023-08-23 16:23:55浏览次数:60  
标签:操作系统 启动 setup 扇区 mov 内存 寄存器 ax

 1.打开电源

(1)x86 PC开机时CPU处于实模式,实模式的寻址方式是CS:IP (CS左移4位+IP)

(2)开机时段寄存器CS=0xFFFF,偏移量IP=0x0000,段寄存器左移4位加上偏移量是实际地址,也就是寻址地址为0xFFFF0 (ROM BIOS映射区)

(3)检查RAM,键盘,显示器,磁盘

(4)将0磁道0扇区512个字节读入0x7c00处(操作系统的引导扇区)

(5)设置cs=0x7c0,ip=0x0000

 2.引导扇区代码bootsect.s

(1)将bootsect从0x7c00处移动到0x90000处

(2)将setup读入到0x90200处

(3)将system读入0x91000处

(4)将PC移动到0x90200处,bootsect结束

1. 移动bootsect.s。读取0x7c00处的内存,首先设置源地址和目标地址,并且将0x7c00内存处的256个字(512字节)移动到了0x90000

start:
  mov ax, #BOOTSEG mov ds, ax // 0x07C0(16位汇编,后面的放入前面)
  mov ax, #INITSEG mov ex, ax // 0x9000
  sub si, si           // 源地址   ds:si 0x7c00
  sub di, di           // 目标地址 es:di 0x90000
  mov cx, #256          // 重复移动256字(512字节)
  rep movw             // 重复移动直到cx为0,将bootsect移动到了0x90000处
  jmpi go, INITSEG            // 跳转到0x9000:go处,将设置es、ss、sp都为0x9000(相当于是初始化)

2. 0x13读磁盘中断,读取setup代码。在磁盘第2个扇区开始,读取4个扇区的内容,并将这4个扇区的内容写入到0x90200内存处。因为bootsect占用512字节,所以需要写在0x90000的512个字节之后,16位表示就是在0x90200处写入。

go: mov ax, cs                // 0x9000
    // 将段寄存器设置为0x9000、栈顶地址设置为0x9fff00,来远离代码位置
    mov ds, ax    mov ex, ax    mov ss, ax    mov sp, #0xff00
load_setup:        
// 载入setup模块, 从磁盘第2个扇区开始读4个扇区, 写入0x90200处 mov dx, #0x0000 // 数据寄存器 mov cx, #0x0002 // 计数寄存器 ch:cx高8位, 0x00(柱面号0); cl:低8位, 0x02(开始扇区为2) mov bx, #0x0200 // 基址寄存器 写到es:bx 0x90200处 mov ax, #0x0200+SETUPLEN // 累加器 ah: ax高8位, 0x20(读磁盘); al:ax低8位, 0x04(读取4个扇区) int 0x13 // BIOS读磁盘扇区中断 jnc ok_load_setup // 跳转指令, CF=0则跳转。如果没有读错,则跳转到加载setup执行;如果读错,则复位驱动器重新读。 mov dx, #0x0000 // 对驱动器0进行操作 mov ax, # 0x0000 // 复位 int 0x13 // 执行0x13中断(BIOS读磁盘扇区的中断) j load_setup //重读

 

3. 0x10显示字符中断,显示字符在显示器上。ok_load_setup,显示欢迎页面,调用read_it读入system,最后将控制权交接给setup模块,也就是将PC移动到0x90200处,开始执行setup。bootsect正式结束。

ok_load_setup:    // 载入setup,显示开机文字,读取system
    // 读取setup,显示开机文字
    mov dl, #0x00    mov ax, #0x0800        // ah=8,获得磁盘驱动器的参数
    int 0x13         mov    ch, #0x00   mov sectors, cx
    mov ah, #0x03    xor bh, bh         int 0x00 // 读光标
    mov cx, #24      mov bx, #0x0007    // 7是显示属性
    mov bp, #msg1    mov ax, #1301      int 0x10 //显示字符
    // 读取system模块到0x10000处
    mov ax, #SYSSEG        // SYSSEG=0X1000
    mov es, ax
    call read_it          // 读入system
    jmpi 0, SETUPSEG      // 转入0x9020:0X0000执行setup.s

 3.引导扇区代码setup.s

读取硬件参数,将操作系统移动到0地址处,进入保护模式,初始化一个很简单的gdt表,跳转到system模块

1. setup主要任务是读取硬件参数,初始化一个数据结构来管理这些硬件设备,并移动操作系统到内存0地址处。其中0x15中断是读取扩展内存大小(Intel原先内存只有1m,我们把1m以外的内存称为扩展内存)放在ax寄存器里,之后放到内存0x90002处。接下来do_move将0x90000处开始的数据移动到内存绝对地址0x00000处。

// 取光标位置,包括其他硬件参数,放到0x90000处
start : mov ax, #INITSEG    mov ds, ax    mov ah, #0x03
        xor bh, bh          int 0x10      mov [0], dx     // 光标位置设置为0x90000
        mov ah, #0x88       int 0x15      mov [2], ax ...    // 读取扩展内存的大小(1m以外的内存称为扩展内存), 放在0x90002处
        cli    // 不允许中断
        mov ax, #0x0000, cld        // 设置读取目标位置和递增读取方式
// 将system模块从0x10000动到0x00000处        
do_mov: mov es, ax          add ax, #0x1000
        cmp ax, #0x9000     jz end_mov              // 若ax=0x9000,表示移动完成,则跳出
        mov ds, ax          sub di, di    sub si, si        // 设置源地址0x90000和目标地址0x00000
        mov cx, #0x8000   // 设置移动数据的长度
        rep movsw         // 将system模块移动到0地址
        jmp do_move

2. 进入保护模式。cs左移4位+ip最大有20位地址,也就是最大内存空间只有1M。setup最后一步要从16位机切换到32寻址方式。

  实模式:CS:IP,CS << 4 + IP,共20位寻址空间

  保护模式:CS实际上是查表GDT(Global Descriptor Table),地址为CS查表 + IP

mov ax,#0x0001  // 将0x0001放入ax寄存器
mov cr0,ax     // 将ax放入cr0寄存器,这一步非常重要
                 // cr0寄存器最后一位是0的时候是CS:IP实模式
                // cr0寄存器最后一位是1的时候是保护模式,需要走另外一条解释指令的电路
jmpi 0,8      // cs:8, ip:0; 这里实际上跳转的地址就是0地址

 4.head.s

head.s是system中的第一个模块,负责重新加载各个数据段寄存器,重新设置中断描述符表,重新设置全局描述符表,设置分页处理机制(一个页目录表和4个页表),打开20号地址线访问4G内存,并且将main函数压栈,head执行完后弹出main,转到main函数。

startup_32:
    movl $0x10, %eax  // 现在开始是32位汇编,前面的放入后面
    mov %ax, %ds
    mov %ax, %es
    mov %as, %fs
    mov %as, %gs        // 指向gdt的0x10数据项
  lss _stact_start, %esp  // 设置系统栈
  call setup_idt       // 设置中断描述符表子程序
  call setup_gdt       // 设置全局描述符表子程序
  mov $0x10, %eax      // 重载所有的段寄存器
...

 5.main函数

main函数中有大量初始化函数,例如初始化硬盘,初始化内存,将每4K内存作为一个页等等

 

标签:操作系统,启动,setup,扇区,mov,内存,寄存器,ax
From: https://www.cnblogs.com/stuxuan/p/17649710.html

相关文章

  • “产业应用创新奖2023”启动征集
    当前,人工智能已经成为新一轮科技革命和产业变革的重要驱动力量,基于强算法、大算力和大数据的大模型成为主流方向。文心大模型和飞桨一直致力于发挥算法模型技术优势,助力AI大生产加速升级。文心+飞桨赋能千行百业,产业创新不断涌现数字医疗中康科技:大模型助力医疗技术创新中康科技基......
  • 【操作系统-进程】进程的调度算法
    目录0进程调度算法的性能指标1【非抢占式】先来先服务(FCFS)调度算法2【非抢占式+抢占式】短进程优先(SPF)调度算法2.1【非抢占式】短进程优先(SPF)调度算法2.2【抢占式】最短剩余时间(SRTN)优先算法3【非抢占式】高响应比优先(HRRN)调度算法4【抢占式】时间片轮转(RR)调度算法案例一:时......
  • Liunx操作系统
    1、什么是Linux系统?Linux®是一个开源的操作系统(OS)。所谓操作系统,是指直接管理系统硬件和资源(如CPU、内存和存储空间)的软件。操作系统位于应用与硬件之间,负责在所有软件与相关的物理资源之间建立连接。Linux理解为一款操作系统和我们现在使用的window操作系统类型。2、为什......
  • Android入门教程之Activity(生命周期,启动...)
    Activity是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件或查看地图等操作。每个Activity都会获得一个用于绘制其用户界面的窗口。窗口通常会充满屏幕,但也可小于屏幕并浮动在其他窗口之上。Activity1.Activity的使用我们新建的工程中带有......
  • Docker开启和关闭容器自启动
    启动容器增加–-restart=always参数设置自启动dockerrun--restart=always--nametest--net=host-dtest//test为镜像河容器名称已启动的容器设置自启动dockerupdate–-restart=always容器ID或者容器名称已启动的容器关闭自启动dockerupdate--restart=no容器ID或者容......
  • SQL Server因设置最大内存太小导致无法启动的解决方案
    首先是    在服务器上发现SQLServer占用内存过大,128G服务器内存它占用高达100多G。于是就去找解决方案,找了几篇文章发现都是通过修改SQLServer服务器最大内存让其释放占用内存,如图所示,我把最大内存修改为128MB。发现问题    然后我就发现我的SQLServer服务无......
  • swift--设置app图标和启动页面
    1,如下图:选择上图步骤1,然后选择步骤2,aapp图标,尺寸上面都有,b启动图,我这是创建好的,如果没有创建,先创建c这块需要置为空接着步骤b进入下图  选择1,点击2选择上图,可以看到3已经创建成功备注1:如下图按照步骤,找到a,然后取消选中fdsfgasfa备注2:选择启动图片资源,如下图按照上......
  • kylin操作系统安装mysql
    首先坑的是麒麟说自己基于ubuntu。结果包管理工具用的yum。然后yum包里还没有mysql只能自己下载安装。1.第一种方式直接下MySQL::DownloadMySQLCommunityServer(ArchivedVersions) 里装好的mysql的tar包,然后解压。解压以后拷贝到/usr/local/mysql目录下注意如果在别的目......
  • linux启动tomcat后,关闭ssh连接,tomcat进程停止
    在tomcat停止后会报错:org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbcWeb应用程序[ROOT]注册了JDBC驱动程序[com.alibaba.druid.proxy.DruidDriver],但在Web应用程序停止时无法注销它。为防止内存泄漏,JDBC驱动程序已被强制取消注册。我以为是代码的问......
  • 一行命令即可启动 Walrus丨入门教程
    应用管理平台Walrus已正式开源,本文将介绍如何上手安装Walrus以及如何借助Walrus进行应用部署。 ⭐开源地址:https://github.com/seal-io/walrus 部署Walrus首先,您需要准备:资源不少于4CPU,8Gi内存的Linux服务器。至少50GB的空余磁盘空间。安装Docker服务......