linux学习(二)--setup.s
执行过bootsect.s,加载了所有系统代码之后,开始向32位模式转变,为main函数的调用做准备,同样,附上图往下看
1 INITSEG = 0x9000 ! we move boot here - out of the way
2 SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
3 SETUPSEG = 0x9020 ! this is the current segment
4
5 .globl begtext, begdata, begbss, endtext, enddata, endbss
6 .text
7 begtext:
8 .data
9 begdata:
10 .bss
11 begbss:
12 .text
13
14 entry start
15 start:
16
17 //保存当前光标位置
18 mov ax,#INITSEG
19 mov ds,ax ;ds设置成INITSEG
20 mov ah,#0x03 ;int 10读光标功能号3
21 xor bh,bh
22 int 0x10 ;调用中断,读取光标位置
23 mov [0],dx ;光标信息存在dx中,并存入0x90000处
24 mov ah,#0x88 ;int 15取扩展内存大小功能号0x88
25 int 0x15 ;调用中断
26 mov [2],ax ;返回从100000开始的扩展内存大小
27
28 //保存显卡当前显示模式
29 mov ah,#0x0f
30 int 0x10
31 mov [4],bx ; bh = display page
32 mov [6],ax ; al = video mode, ah = window width
33
34 //检查显示方式(EGA/VGA),并选取参数
35 mov ah,#0x12
36 mov bl,#0x10
37 int 0x10
38 mov [8],ax
39 mov [10],bx ;显示内存,显示状态
40 mov [12],cx ;显卡特性参数
41
42 //取第0个硬盘信息
43 mov ax,#0x0000
44 mov ds,ax
45 lds si,[4*0x41];取中断向量,41的值,即硬盘0参数表的地址
46 mov ax,#INITSEG
47 mov es,ax
48 mov di,#0x0080 ;传输向量表到达的目的地址:9000:0080
49 mov cx,#0x10 ;取10字节
50 rep
51 movsb ;循环复制
52
53 //取第一个磁盘信息
54 mov ax,#0x0000
55 mov ds,ax
56 lds si,[4*0x46];取中断向量,46的值,即硬盘1参数表的地址
57 mov ax,#INITSEG
58 mov es,ax
59 mov di,#0x0090 ;传输向量表到达的目的地址:9000:0090
60 mov cx,#0x10 ;取10字节
61 rep
62 movsb
63
64 //检查是否存在第二个硬盘
65 mov ax,#0x01500
66 mov dl,#0x81
67 int 0x13
68 jc no_disk1 ;如果cf==1,跳转,没有第二个磁盘
69 cmp ah,#3 ;判断是否有硬盘
70 je is_disk1
71 //没有则删除第二个硬盘表
72 no_disk1:
73 mov ax,#INITSEGjj
74 mov es,ax
75 mov di,#0x0090
76 mov cx,#0x10
77 mov ax,#0x00
78 rep
79 stosb
80
81 is_disk1:
82
83 //开始保护模式方面的工作
84
85 cli ;不允许中断
86
87 //首先我们将系统模块移动到新的目标位置
88
89 mov ax,#0x0000
90 cld ! 'direction'=0, movs moves forward
91 do_move:
92 mov es,ax ;被复制到的目的地址es:di=>0000:0
93 add ax,#0x1000
94 cmp ax,#0x9000
95 jz end_move
96 mov ds,ax ;原地址ds:si=>1000:0
97 sub di,di
98 sub si,si
99 mov cx,#0x8000 ;移动0x8000字节(64k)
100 rep
101 movsw
102 jmp do_move
103
104 //加载段描述符
105
106 end_move:
107 mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-)
108 mov ds,ax ;ds指向setup段
109 lidt idt_48 ;加载中断描述符表寄存器
110 lgdt gdt_48 ;加载全局描述符表寄存器
111
112 //开启A20地址线,准备进入32位寻址模式
113
114 call empty_8042
115 mov al,#0xD1 ! command write
116 out #0x64,al
117 call empty_8042
118 mov al,#0xDF ! A20 on
119 out #0x60,al
120 call empty_8042
121
122 ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
123 ! we put them right after the intel-reserved hardware interrupts, at
124 ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
125 ! messed this up with the original PC, and they haven't been able to
126 ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
127 ! which is used for the internal hardware interrupts as well. We just
128 ! have to reprogram the 8259's, and it isn't fun.
129
130 mov al,#0x11 ! initialization sequence
131 out #0x20,al ! send it to 8259A-1
132 .word 0x00eb,0x00eb ! jmp $+2, jmp $+2,$表示当前指令地址
133 out #0xA0,al ! and to 8259A-2
134 .word 0x00eb,0x00eb
135 mov al,#0x20 ! start of hardware int's (0x20)
136 out #0x21,al
137 .word 0x00eb,0x00eb
138 mov al,#0x28 ! start of hardware int's 2 (0x28)
139 out #0xA1,al
140 .word 0x00eb,0x00eb
141 mov al,#0x04 ! 8259-1 is master
142 out #0x21,al
143 .word 0x00eb,0x00eb
144 mov al,#0x02 ! 8259-2 is slave
145 out #0xA1,al
146 .word 0x00eb,0x00eb
147 mov al,#0x01 ! 8086 mode for both
148 out #0x21,al
149 .word 0x00eb,0x00eb
150 out #0xA1,al
151 .word 0x00eb,0x00eb
152 mov al,#0xFF ! mask off all interrupts for now
153 out #0x21,al
154 .word 0x00eb,0x00eb
155 out #0xA1,al
156
157 ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
158 ! need no steenking BIOS anyway (except for the initial loading :-).
159 ! The BIOS-routine wants lots of unnecessary data, and it's less
160 ! "interesting" anyway. This is how REAL programmers do it.
161 !
162 ! Well, now's the time to actually move into protected mode. To make
163 ! things as simple as possible, we do no register set-up or anything,
164 ! we let the gnu-compiled 32-bit programs do that. We just jump to
165 ! absolute address 0x00000, in 32-bit protected mode.
166
167 mov ax,#0x0001 ! protected mode (PE) bit
168 lmsw ax ! This is it!
169 jmpi 0,8 ! jmp offset 0 of segment 8 (cs)
170 ; 跳转到8:0位置,这里的8为实模式下的段选择符,目的地址是0x00000000
171 //关于8的解析,这里的8对应二进制的"1000",这里的后两位0表示内核特权级,倒数第三位的0表示gdt
172 //1表示用全局描述符表的第1项,该项指出代码的基地址是0,也就是接下来执行的head.s
173
174 ! This routine checks that the keyboard command queue is empty
175 ! No timeout is used - if this hangs there is something wrong with
176 ! the machine, and we probably couldn't proceed anyway.
177
178 //检查键盘命令队列是否为空,当输入缓冲器为空则可以对其进行写命令
179 empty_8042:
180 .word 0x00eb,0x00eb
181 in al,#0x64 ! 8042 status port
182 test al,#2 ! is input buffer full?
183 jnz empty_8042 ! yes - loop
184 ret
185 //全局描述符表开始处
186 gdt:
187 .word 0,0,0,0 ! dummy//第一描述符,不用
188
189 //这里在gdt表中的偏移量为08,联系我们上面的jmpi 0,8,也就是调用此处的表内容
190 //加载代码段寄存器时,使用这个偏移
191 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
192 .word 0x0000 ! base address=0
193 .word 0x9A00 ! code read/exec
194 .word 0x00C0 ! granularity=4096, 386
195
196 //这里在gdt表中的偏移量是10,当加载数据段寄存器时,使用这个偏移
197 .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
198 .word 0x0000 ! base address=0
199 .word 0x9200 ! data read/write
200 .word 0x00C0 ! granularity=4096, 386
201
202 idt_48:
203 .word 0 ! idt limit=0
204 .word 0,0 ! idt base=0L
205
206 gdt_48:
207 .word 0x800 ! gdt limit=2048, 256 GDT entries
208 .word 512+gdt,0x9 ! gdt base = 0X9xxxx
209
210 .text
211 endtext:
212 .data
213 enddata:
214 .bss
215 endbss:
linux学习(二)--setup.s的更多相关文章
- Linux学习(二)-Xshell 5和Xftp 5的安装和使用
(一)软件介绍: (1)Xshell: Xshell通过互联网可以连接到远程的服务器,然后通过模拟终端来实现对服务器的各种操作,而且这款软件可以很好的解决中文乱码问题,非常的方便快捷. (2)Xftp ...
- Linux 学习 (二) 文件处理命令
Linux达人养成计划 I 学习笔记 ls [选项] [文件或目录] -a: 显示所有文件,包括隐藏文件 -l: 显示详细信息 -d: 查看目录属性 -h: 人性化显示文件大小 -i: 显示inode ...
- 【Linux学习二】文件系统
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 一.文件系统 一切皆文件Filesystem Hierarchy St ...
- linux学习(二) -- ubuntu下lnmp环境的配置
亲测的教程,,希望能对大家提供些许帮助,转载请注明出处 ubuntu+nginx+mysql+php7 一.安装Nginx 1.首先添加nginx_signing.key(必须,否则出错) $ wge ...
- linux学习(二)-----Linux 的目录结构、远程登录、vi和vim
linux目录结构 基本介绍 linux 的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录“/”,然后在此 目录下再创建其他的目录. 目录结构具体介绍 Linux 目录总结 1.lin ...
- Linux学习--------二
Linux基础知识 Linux文件系统为一个倒转的单根树状结构文件系统的根为"/" 文件系统严格区分大小写路径 使用"/"分割(windows使用"\ ...
- 嵌入式Linux学习(二)
嵌入式系统和通用计算机的主要区别 嵌入式系统是指以应用为中心,以计算机技术为基础,软件硬件可裁剪,适应应用系统对功能.可靠性.成本.体积.功耗严格要求的专用计算机系统. 嵌入式系统主要由嵌入式微处理器 ...
- linux 学习(二)防火墙
ubuntu 第四 防火墙 安装 sudo apt-get install ufw 启用 sudo ufw enable 拒绝所有 sudo default deny 开启端口 sudo ufw al ...
- Linux 学习 二, 安装JDK
我是利用在window环境下载好JDK,然后传到VMware中linux中 下载JDK http://www.oracle.com/technetwork/java/javase/downloads/ ...
- Linux学习(二) wget命令的使用
近期在Linux下进行一些操作,在非常多地方都用到了wget这个命令,记录一下一些有关wget的使用方法: wget是在Linux下开发的开放源码的软件,作者是Hrvoje Niksic,后来被移植到 ...
随机推荐
- Linux下vim的安装及配置
目录 一.vim的下载 二.vim的基本知识 三.vim的基本配置 四.vim与外部文件的复制粘贴 一.vim的下载 Ubuntu系统,输入命令: sudo apt install vim Cento ...
- 学习 | mockjs入门
最近工作有用到mockjs模拟数据,实现前后端分离,今天系统的把mockjs的API都过了一遍,算是入门吧. 什么是mockjs mockjs就是一个模拟数据,生成随机数据,拦截ajax请求. 为什么 ...
- JVM--先说本地方法接口
本地方法接口 在讲Java虚拟机运行时数据区中本地方法栈之前,我们先来说说运行时数据区之外的一个叫本地方法接口的东西简称JNI(Java Native Interface) 简单来讲,一个Native ...
- 纯java代码在控制台运算电话本(不使用数据库)
分享学习 Task_08 package cn.rzpt; import java.util.List; import java.util.Scanner; public class Task_08 ...
- 教你怎么"白嫖"图床
本次白嫖适用于有自己域名的. 访问 又拍云,注册 注册好后,访问又拍云联盟 按照说明申请即可 结束 静等通过即可,经过我与又拍云联系核实他们审核通过都会在每周五的下午18:00统一发送审核结果邮件通知 ...
- 11.深入k8s:kubelet工作原理及源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 kubelet信息量是很大的,通过我这一篇文章肯定是讲不全的,大家可 ...
- ECMAScript 6新特性简介
目录 简介 ECMAScript和JavaScript的关系 let和const 解构赋值 数组的扩展 函数的扩展 简介 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言 ...
- 关于取整函数ceil(),floor(),round()函数得应用
ceil()返回向上取整最接近的整数. double ceil(double); floor()返回向下取整最接近的整数. double floor(double); round()用于对浮点数的四舍 ...
- el-table行点击事件row-click与列按钮事件冲突
需求简述 表格用el-table实现,操作列的编辑按钮点击事件正常实现.现要为行加一点击事件,即row-click.加上后,发现点击操作列的编辑按钮时,会触发按钮本身事件,同时会触发行点击事件.第一版 ...
- LDA主题模型困惑度计算
对于LDA模型,最常用的两个评价方法困惑度(Perplexity).相似度(Corre). 其中困惑度可以理解为对于一篇文章d,所训练出来的模型对文档d属于哪个主题有多不确定,这个不确定成都就是困惑度 ...