操作系统之loader的实现
来源:互联网 发布:上海二手住宅成交数据 编辑:程序博客网 时间:2024/06/07 06:13
上一章已经讲解了笔记本从开始到bios加载MBR(主引导扇区)的相关内容.
这章将介绍MBR跳转到loader的执行,以及用显卡直接输出到字符.有可能会有疑问为何还要写loader.因为mbr只能是512字节.这么小的空间没法做啥.只能作为跳板所以写个loader用来加载内核.
从图可知.显卡的文本模式映射到了B8000处.只要把字符移到此处.就可以在屏幕显示字符,并且每个字符占用2个字节(一个显示字母一个控制颜色).比如
mov byte [B800:0x04],'M' ,mov byte [B800:0x05] 0xA4 将显示一个 一个闪烁的M .字符由字母跟属性控制.前一个是字母显示.第二个是显示的属性比如颜色闪烁之类的
具体文本模式的第二个字节显示属性.请自行google
section MBR vstart=0x7c00jmp start;ds:si指向数据源.es:di指向显存 Message db 'ZYW_OS'start:mov ax,0xb800mov es,axmov di,0mov sp,0x7c00mov si,Message; 清屏(摘自百度);利用0x06号功能,上卷全部行,则可清屏。; -----------------------------------------------------------;INT 0x10 功能号:0x06 功能描述:上卷窗口;------------------------------------------------------;输入:;AH 功能号= 0x06;AL = 上卷的行数(如果为0,表示全部);BH = 上卷行属性;(CL,CH) = 窗口左上角的(X,Y)位置;(DL,DH) = 窗口右下角的(X,Y)位置mov ax,0x0600mov bx,0x0700mov cx,0 ; 左上角: (0, 0)mov dx,0x184f ; 右下角(80,25),int 10h mov cx,start-Messages: movsb mov byte [es:di],0xA4 inc di loop s jmp $ times 510-($-$$) db 0 db 0x55,0xaa
显示效果如图
------------------------------------以上介绍了如何使用显存来显示字符而非bios系统调用-------------------------------------------
接下来介绍如何从硬盘读取loader并加载到内存中..
CPU与外设、存储器的连接和数据交换都需要通过接口设备来实现。
每个连接到I/O总线上的设备都由自己的I/O地址集,即所谓的I/O端口(I/O port)。
每个设备的I/O端口都被组织成一组专用的寄存器,CPU可给控制寄存器发命令对设备进行控制、从状态寄存器读取设备状态、可以向输出寄存器写入数据来把数据输出到设备、可通过读取输入寄存器的内容来从设备取得数据。
总之就是通过读写端口来控制设备。
一个普通的PC主板上通常有两个IDE口,分别对应两个IDE通道:primary和secondary有时也成IDE0和IDE1。
每个IDE通道又能连接两个设备,称为主设备(Master)和从设备(Slave),对不同的IDE通道的访问是通过I/O端口来区分的。
IDE(integrated drive electronics)即电子集成驱动器,主要接硬盘和光驱。
接到主设备上的硬盘称为0号硬盘。
与0号硬盘有关的I/O端口:
1F0H 0号硬盘数据寄存器
1F1H 0号硬盘错误寄存器(读时)、0号硬盘Features寄存器(写时)
1F2H 0号硬盘数据扇区计数
1F3H 0号硬盘扇区数
1F4H 0号硬盘柱面(低字节)
1F5H 0号硬盘柱面(高字节)
1F6H 0号硬盘驱动器/磁头寄存器
1F7H 0号硬盘状态寄存器(读时)、0号硬盘命令寄存器(写时)
1.先选择通道,往该通道的sector count寄存器0x1f2处写入待操作的扇区数目
2.往该通道的三个LBA寄存器(0x1f3-0x1f6)写入扇区起始地址的低24位
3.往0x1f6(device)寄存器写入LBA的24-27位.并置第6位为1,使其成为LBA模式,设置第4位.选择操作的硬盘
4.向该通道的command寄存器写入命令
(5)读取此通道的status寄存器.判断硬盘是否完工
(6)将数据读取出来
接下来改造MBR.并且实现loader.
配置文件(定义地址信息)
loader_base_addr equ 0x900 loader_start_sector equ 0x2
MBR.S 源代码
%include "boot.inc"section MBR vstart=0x7c00jmp start;ds:si指向数据源.es:di指向显存 Message db 'ZYW_OS'start:mov ax,0xb800mov es,axmov di,0mov sp,0x7c00mov si,Message; 清屏(摘自百度);利用0x06号功能,上卷全部行,则可清屏。; -----------------------------------------------------------;INT 0x10 功能号:0x06 功能描述:上卷窗口;------------------------------------------------------;输入:;AH 功能号= 0x06;AL = 上卷的行数(如果为0,表示全部);BH = 上卷行属性;(CL,CH) = 窗口左上角的(X,Y)位置;(DL,DH) = 窗口右下角的(X,Y)位置mov ax,0x0600mov bx,0x0700mov cx,0 ; 左上角: (0, 0)mov dx,0x184f ; 右下角(80,25),int 10h mov cx,start-Messages: movsb mov byte [es:di],0xA4 inc di loop smov eax,loader_start_sector ;eax保存加载程序的位置mov bx,loader_base_addr ;bx保存加载到哪个区域mov cx,1 ;cx保存加载几个扇区(从eax开始)call read_disk jmp loader_base_addr ;跳转到那加载程序那,+300.这个是我自己设定好跳过的数据大小(数据跟代码..混在一起了)read_disk: push eaxmov dx,0x1f2 ;硬盘端口0x1f2 ,设置要读取多少数据mov al,cl ;cl控制读取多少个out dx,al ;写入到寄存器中pop eax;将lba地址存入0x1f3-0x1f6处mov dx,0x1f3out dx,al push cx mov cl,8shr eax,clmov dx,0x1f4out dx,alshr eax,clmov dx,0x1f5out dx,alshr eax,cland al,0x0for al,0xe0mov dx,0x1f6out dx,al pop cx;向0x1f7写入命令mov dx,0x1f7mov al,0x20out dx,al noready:nopin al,dxand al,0x88 cmp al,0x08jnz noready ;开始从0x1f0端口读取数据mov ax,cx mov dx,256mul dxmov cx,axmov dx,0x1f0readdata: in ax,dx mov [bx],ax add bx,2 loop readdata ret times 510-($-$$) db 0 db 0x55,0xaa
loader.S源代码
%include "boot.inc"section loader vstart=loader_base_addrjmp startMessage db 'I am Loader'start:mov si,Messagemov ax,0xb800mov es,axmov di,0mov cx,start-Messages:movsbmov byte [es:di],0xA4inc diloop sjmp $
- 操作系统之loader的实现
- 操作系统之loader的实现
- 一个操作系统的实现(6):加载Loader.bin
- <<orange‘s :一个操作系统的实现>>读书笔记(3)-loader
- 《一个操作系统的实现》笔记(4)-- Boot&Loader
- 一个操作系统的实现--从loader到内核和扩充内核的错误兼参考指令
- Loader的简单实现
- 构建自己的操作系统[2]-Loader
- 专注于操作系统24之boot,loader,kernel
- 专注于操作系统28之用loader加载kernel
- 编写操作系统之键盘交互的实现
- 编写操作系统之键盘交互的实现
- 操作系统之锁的实现方式
- Kyodai loader的实现步骤
- vivi boot loader的实现
- vivi boot loader的实现
- Android之Loader的使用
- 仿照windows的loader实现的pe-loader
- Exchange 2016边缘传输服务器“MSExchange运行状况管理器”无法启动
- (OK)(OK)(All in CLI) running two Android-x86 which connect to NS3(MANETs) via "ethernet bridge"
- Excel -- 3. 数据管理和分析
- Leetcode算法题分类解析:(一)总览
- new、new()和new[]三者的区别
- 操作系统之loader的实现
- Fibonacci 数列及其计算方法
- Linkit Smart 7688 //OpenWrt - 2port
- C语言函数拾遗
- POI之图片导出到PPT简单实例
- ubuntu下安装spark
- C面试宝典-(程序题)1
- Fragment的陷阱
- Android MediaPlayer工具类