执行过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的更多相关文章

  1. Linux学习(二)-Xshell 5和Xftp 5的安装和使用

    (一)软件介绍: (1)Xshell: Xshell通过互联网可以连接到远程的服务器,然后通过模拟终端来实现对服务器的各种操作,而且这款软件可以很好的解决中文乱码问题,非常的方便快捷. (2)Xftp ...

  2. Linux 学习 (二) 文件处理命令

    Linux达人养成计划 I 学习笔记 ls [选项] [文件或目录] -a: 显示所有文件,包括隐藏文件 -l: 显示详细信息 -d: 查看目录属性 -h: 人性化显示文件大小 -i: 显示inode ...

  3. 【Linux学习二】文件系统

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 一.文件系统 一切皆文件Filesystem Hierarchy St ...

  4. linux学习(二) -- ubuntu下lnmp环境的配置

    亲测的教程,,希望能对大家提供些许帮助,转载请注明出处 ubuntu+nginx+mysql+php7 一.安装Nginx 1.首先添加nginx_signing.key(必须,否则出错) $ wge ...

  5. linux学习(二)-----Linux 的目录结构、远程登录、vi和vim

    linux目录结构 基本介绍 linux 的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录“/”,然后在此 目录下再创建其他的目录. 目录结构具体介绍 Linux 目录总结 1.lin ...

  6. Linux学习--------二

    Linux基础知识 Linux文件系统为一个倒转的单根树状结构文件系统的根为"/" 文件系统严格区分大小写路径 使用"/"分割(windows使用"\ ...

  7. 嵌入式Linux学习(二)

    嵌入式系统和通用计算机的主要区别 嵌入式系统是指以应用为中心,以计算机技术为基础,软件硬件可裁剪,适应应用系统对功能.可靠性.成本.体积.功耗严格要求的专用计算机系统. 嵌入式系统主要由嵌入式微处理器 ...

  8. linux 学习(二)防火墙

    ubuntu 第四 防火墙 安装 sudo apt-get install ufw 启用 sudo ufw enable 拒绝所有 sudo default deny 开启端口 sudo ufw al ...

  9. Linux 学习 二, 安装JDK

    我是利用在window环境下载好JDK,然后传到VMware中linux中 下载JDK http://www.oracle.com/technetwork/java/javase/downloads/ ...

  10. Linux学习(二) wget命令的使用

    近期在Linux下进行一些操作,在非常多地方都用到了wget这个命令,记录一下一些有关wget的使用方法: wget是在Linux下开发的开放源码的软件,作者是Hrvoje Niksic,后来被移植到 ...

随机推荐

  1. Linux:使用SecureCRT来上传和下载文件

    SecureCRT自带的有几种上传下载功能,SecureCRT下的文件传输协议有以下几种:ASCII.Xmodem.Ymodem.Zmodem. ASCII:这是最快的传输协议,但只能传送文本文件.  ...

  2. [转载] 微软发布 SURFACE DUO ANDROID SDK 和模拟器

    模拟器截图 微软今天发布了双屏折叠设备 Surface Duo Android 开发工具(SDK 和模拟器),Windows 10X 开发工具和模拟器之后 2 月 11 日发布,并宣布了新的针对双屏体 ...

  3. [LeetCode]面试题14- I. 剪绳子(DP/贪心)

    题目 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m] .请问 k[0]k[1]...* ...

  4. python文档翻译之python说明

    3.1使用Python进行计数 让我们来使用一些Python的简单命令,通过终端启动解释器等待出现>>>. 3.1.1数值类型 在终端中输入数学表达式,Python解释器会执行这些表 ...

  5. 修改python包pip下载国内源

    第一种方式- pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ 附国内常用镜像源:阿里云:https:// ...

  6. Pycharm永久激活2且jetbrains全系列产品

    Pycharm永久激活2 注意:本教程补丁来源于https://zhile.io,如有侵权请联系作者删除! 本项目只做学习研究之用,不得用于商业用途! 一.激活前注意事项 PyCharm尽量在官网下载 ...

  7. burp suite之spider(爬虫)

    spider (蜘蛛,这里的意思指爬行) 像蜘蛛一样在网站上爬行出网站的个个目录信息,并发送至Target. 1.Control(控制) Spider is paused :停止蜘蛛爬行 Clear ...

  8. 线上Redis高并发性能调优实践

    项目背景 最近,做一个按优先级和时间先后排队的需求.用 Redis 的 sorted set 做排队队列. 主要使用的 Redis 命令有, zadd, zcount, zscore, zrange ...

  9. 消息队列之事务消息,RocketMQ 和 Kafka 是如何做的?

    每个时代,都不会亏待会学习的人. 大家好,我是 yes. 今天我们来谈一谈消息队列的事务消息,一说起事务相信大家都不陌生,脑海里蹦出来的就是 ACID. 通常我们理解的事务就是为了一些更新操作要么都成 ...

  10. Redis小记(一)

    1.redis的数据结构 (1)动态字符串(SDS) redis自身构建了一个简单动态字符串的抽象类型,SDS,在redis里,包含字符串的键值对在底层都是由SDS来实现的. 除了用来保存数据库的字符 ...