ucore lab1 bootloader学习笔记
---恢复内容开始---
开机流程回忆
以Intel 80386为例,计算机加电后,CPU从物理地址0xFFFFFFF0(由初始化的CS:EIP确定,此时CS和IP的值分别是0xF000和0xFFF0))开始执行。在0xFFFFFFF0这里只是存放了一条跳转指令,通过跳转指令跳到BIOS例行程序起始点。BIOS做完计算机硬件自检和初始化后,会选择一个启动设备(例如软盘、硬盘、光盘等),并且读取该设备的第一扇区(即主引导扇区或启动扇区)到内存一个特定的地址0x7c00处,然后CPU控制权会转移到那个地址继续执行。至此BIOS的初始化工作做完了,进一步的工作交给了ucore的bootloader。
简单来说,就是
加电-->CPU执行内存地址为0xFFFFFFF0的指令(一条跳转指令)--->跳到BIOS程序起始点,执行BIOS程序(功能:计算机硬件自检和初始化),自检等完成后--->选择一启动设备,并读取第一扇区(主引导扇区)到内存的0x7c00处--->BIOS所有工作完成后, CPU执行内存的0x7c00中的程序,即bootloader。
bootloader启动过程
BIOS将通过读取硬盘主引导扇区到内存,并转跳到对应内存中的位置执行bootloader。bootloader完成的工作包括:
- 打开A20地址线,设置CR0,切换到保护模式,启用分段机制
- 读磁盘中ELF执行文件格式的ucore操作系统到内存
- 显示字符串信息
- 把控制权交给ucore操作系统
对应其工作的实现文件在lab1中的boot目录下的三个文件asm.h、bootasm.S和bootmain.c。
代码简单分析
bootasm.S
.code16 # Assemble for -bit mode cli # Disable interrupts cld # String operations increment # Set up the important data segment registers (DS, ES, SS). xorw %ax, %ax # Segment number zero movw %ax, %ds # -> Data Segment movw %ax, %es # -> Extra Segment movw %ax, %ss # -> Stack Segment
注释:.code16表示为16位的实模式,cli表示屏蔽系统中断 6-9为清空ds , es , ss 等段寄存器内容。
# Enable A20: # For backwards compatibility with the earliest PCs, physical # address line is tied low, so that addresses higher than # 1MB wrap around to zero by default. This code undoes this. seta20.: inb $0x64, %al # input buffer empty). testb $0x2, %al movb $0xd1, %al # 0xd1 -> port 0x64 outb %al, $0x64 # 0xd1 's P2 port seta20.2: inb $0x64, %al # Wait for not busy(8042 input buffer empty). testb $0x2, %al jnz seta20.2 movb $0xdf, %al # 0xdf -> port 0x60 bit) to
注释: 参考“百度文库 激活A20地址线详解”
# Switch from real to protected mode, using a bootstrap GDT # and segment translation that makes virtual addresses # identical to physical addresses, so that the # effective memory map does not change during the switch. lgdt gdtdesc movl %cr0, %eax orl $CR0_PE_ON, %eax movl %eax, %cr0
注释:通过将CR0寄存器第一位置1,开启保护模式。
# Set up the stack pointer --start(0x7c00) movl $0x0, %ebp movl $start, %esp call bootmain
注释:跳转到bootmain.c
bootmain.c
bootloader让CPU进入保护模式后,下一步的工作就是从硬盘上加载并运行OS。考虑到实现的简单性,bootloader的访问硬盘都是LBA模式的PIO(Program IO)方式,即所有的IO操作是通过CPU访问硬盘的IO地址寄存器完成。
一般主板有2个IDE通道,每个通道可以接2个IDE硬盘。访问第一个硬盘的扇区可设置IO地址寄存器0x1f0-0x1f7实现的,具体参数见下表。一般第一个IDE通道通过访问IO地址0x1f0-0x1f7来实现,第二个IDE通道通过访问0x170-0x17f实现。每个通道的主从盘的选择通过第6个IO偏移地址寄存器来设置。
表一 磁盘IO地址和对应功能
第6位:为1=LBA模式;0 = CHS模式 第7位和第5位必须为1
IO地址 | 功能 |
0x1f0 | 读数据,当0x1f7不为忙状态时,可以读。 |
0x1f2 | 要读写的扇区数,每次读写前,你需要表明你要读写几个扇区。最小是1个扇区 |
0x1f3 | 如果是LBA模式,就是LBA参数的0-7位 |
0x1f4 | 如果是LBA模式,就是LBA参数的8-15位 |
0x1f5 | 如果是LBA模式,就是LBA参数的16-23位 |
0x1f6 | 第0~3位:如果是LBA模式就是24-27位 第4位:为0主盘;为1从盘 |
0x1f7 | 状态和命令寄存器。操作时先给命令,再读取,如果不是忙状态就从0x1f0端口读数据 |
当前 硬盘数据是储存到硬盘扇区中,一个扇区大小为512字节。读一个扇区的流程(可参看boot/bootmain.c中的readsect函数实现)大致如下:
- 等待磁盘准备好
- 发出读取扇区的命令
- 等待磁盘准备好
- 把磁盘扇区数据读到指定内存
/* waitdisk - wait for disk ready */ static void waitdisk(void) { while ((inb(0x1F7) & 0xC0) != 0x40) /* do nothing */; } /* readsect - read a single sector at @secno into @dst */ static void readsect(void *dst, uint32_t secno) { // wait for disk to be ready waitdisk(); outb(); // count = 1 outb(0x1F3, secno & 0xFF); outb() & 0xFF); outb() & 0xFF); outb() & 0xF) | 0xE0); outb(0x1F7, 0x20); // cmd 0x20 - read sectors // wait for disk to be ready waitdisk(); // read a sector insl(); }
---恢复内容结束---
ucore lab1 bootloader学习笔记的更多相关文章
- DSP - Bootloader学习笔记2
DSP - Bootloader学习笔记2 彭会锋 1 本文主要以F2812为例进行说明的: F28027内部资源 F28027内存映射
- DSP bootloader学习笔记1
DSP bootloader学习笔记1 彭会锋 参考: TMS320F28xx DSP中内部Flash的应用研究 http://wenku.baidu.com/view/83e9837931b765c ...
- ucore lab8 文件系统 学习笔记
最后一战果然过瘾.代码量够多,新机制够复杂度,都管饱.做这一课就像从高山上往下走,坡急且路险,还不知自己的方位,琢磨不透系统的架构.待到下了山,回头一看豁然开朗,原来方才自己所下的山是这般模样.在这里 ...
- ucore操作系统学习笔记(一) ucore lab1系统启动流程分析
一.ucore操作系统介绍 操作系统作为一个基础系统软件,对下控制硬件(cpu.内存.磁盘网卡等外设),屏蔽了底层复杂多样的硬件差异:对上则提供封装良好的应用程序接口,简化应用程序开发者的使用难度.站 ...
- ucore操作系统学习笔记(二) ucore lab2物理内存管理分析
一.lab2物理内存管理介绍 操作系统的一个主要职责是管理硬件资源,并向应用程序提供具有良好抽象的接口来使用这些资源. 而内存作为重要的计算机硬件资源,也必然需要被操作系统统一的管理.最初没有操作系统 ...
- Linux 学习笔记
Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...
- GRUB学习笔记(转自http://www.cnblogs.com/evilzy/archive/2008/03/30/1130173.html)
grub学习笔记1 首先要了解的几个概念 1.1 启动管理器 启动管理器是存储在磁盘开始扇区中的一段程序,例如,硬盘的MBR(Master Boot Record),在系统完成启动测试后,如果系统是从 ...
- jz2440-linux3.4.2-kernel移植【学习笔记】【原创】
平台:jz2440 作者:庄泽彬(欢迎转载,请注明作者) 说明:韦东山二期视频学习笔记 交叉编译工具:arm-linux-gcc (GCC)4.3.2 linux:linu3.4.2 PC环境:ubu ...
- Linux学习笔记——基于鸟哥的Linux私房菜
Linux学习笔记--基于鸟哥的Linux私房菜 ***** ARM与嵌入式linux的入门建议 (1) 学习基本的裸机编程:ARM7或ARM9,理解硬件架构和控制原理 (这一步是绝对的根基) (2) ...
随机推荐
- RecyclerView.ItemDecoration
decoration 英文意思: 英[ˌdekəˈreɪʃn] 美[ˌdɛkəˈreʃən] n. 装饰品; 装饰,装潢; 装饰图案,装饰风格; 奖章; [例句]The decoration and ...
- C语言之循环次数
#include<stdio.h>int main(){int num,count=0,i=0,ret=0;scanf("%d",&num);while(num ...
- css选择器的优先级问题
当我们写页面的时候,不知道你会不会产生这样的问题,为什么我给他添加的这条样式分明已经选择到我要给的元素了,但是他的样式并没有生效,那是为什么呢? 定义的属性有冲突时,浏览器会选择用那一套样式呢,下面来 ...
- JavaScript学习笔记(十五)——对象之Date,RegExp
在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...
- Zabbix 3.0 部署监控 [二]
一.添加监控主机及设置 1.创建主机 Agent可以干一些SNMP无法干的事情,例如自定义监控项 snmp相关文章:http://www.abcdocker.com/abcdocker/1376 ...
- mysql安装后服务启动不了(总结)
mysql安装后服务启动不了 1.1 前言 最近真的是倒霉到家,装个mysql都能把所有的问题给问候了一遍······不过这也是一个宝贵的经验,得好好总结下,毕竟也不知道以后会不会再次遇到.如果有网友 ...
- 学习makefile的一个工程示例
前言 makefile推荐资料为陈皓的跟我一起写makefile,需要pdf资源的可以私我 正文 工程目录结构 ---include(放置头文件.h) ------student.h(Student类 ...
- sublime text 3 ctrl+b浏览器启动html
sublime text 2 和3 都可以快速设置浏览器启动,本人在这里介绍如何不下插件启动浏览器.第一步:打开Tool-->build system ---> new build sy ...
- COM组件转换为.NET元数据2
上一篇通过命令的方式实现COM组件与.NET元素的转换.这次直接在VS中转换. 以下为步骤:
- Android应用开发allowBackup敏感信息泄露的一点反思
1 背景 [工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处.尊重劳动成果] 事实上这篇文章可能有些小题大作,但回过头想想还是非常有必要的,有点阴沟里翻船的感觉. ...