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,后来被移植到 ...
随机推荐
- 移动APP性能评测与优化
本文是<移动App性能评测与优化>的读书笔记. PS:说是读书笔记,其实就是摘录. 移动App的性能测试主要包括:内存使用情况.电量消耗.功能的流畅度等: 1. 内存 1.1 内存的主要组 ...
- delphi DBgrid应用全书
在一个Dbgrid中显示多数据库 在数据库编程中,不必要也不可能将应用程序操作的所有数据库字段放入一个数据库文件中.正确的数据库结构应是:将数据库字段放入多个数据库文件,相关的数据库都包含一个唯 ...
- [LeetCode]547. 朋友圈(DFS)
题目 班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指所有朋友的集 ...
- node 进阶 | 通过node中如何捕获异常阐述express的特点
node如何捕获异常 node基于js的单线程,有了非阻塞异步回调的概念,但是在处理多个并发连接时,并发环境要求高,最重要的是单线程,单核CPU,一个进程crash则web服务都crash,但是为什么 ...
- Skywalking Php注册不上问题排查
Skywalking是一款分布式追踪应用,具体介绍可以参考 skywalking. 最近公司的一个Php应用在Skywalking后台查不到数据了: 登录到某台服务器上发现注册不上,启动时就报错了: ...
- maximo入门---开发者提要
1.添加控件 在一个程序设计器里添加控件,控件必须要和这个程序对象(这个程序关联的表)的一个属性绑定 ps maximo挺高级的,比如一个date类型的输入框,会自动给他补上时间控件 2.复制程序 复 ...
- 一个提高N倍系统新能的编程点,却总是被普通开发们遗忘
位运算这个概念并不陌生,大多数程序员在进入这个领域的时候或多或少都接触过位运算,估计当时都写过不少练习题的. 位运算本身不难,困难的是大家没有学会在系统设计时用上它,提高系统性能,增加你的不可替代性. ...
- 烦人的Null,你可以走开点了
1. Null 的问题 假设现在有一个需要三个参数的方法.其中第一个参数是必须的,后两个参数是可有可无的. 第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没 ...
- Python-变量-数字类型
数字 number 整形 int 浮点型 float bool True(=1) False(=0) int_num = 10 float_num = 10.1 bool_True = True bo ...
- Centos-当前登录用户信息- w who
w who 显示当前登录系统的用户,但w显示的更为详细 who 相关参数 # 默认输出 用户名.登录终端.登录时间 -a 列出所有信息 -b 系统最近启动日期 -m 当前终端信息,相当于 w ...