setup作用

①读取参数放在0x90000处。

②将原本在0x10000处的system模块移至0x00000处

③加载中断描述符表,全局描述符表,进入32位保护模式。

概念

关于实模式和保护模式区别及寻址方式,该博客已经很详尽:http://blog.csdn.net/rosetta/article/details/8933200,只是有个别信息没有。

IDT:Interrupt Descriptor Table--中断描述表

GDT:Global Descriptor Table   --全局描述表

LDT:Local Descriptor Table    --局部描述表

在Intel架构中,更准确的说是保护模式下,大部分内存管理和中断服务例程都通过描述符表来控制。每个描述符存储了CPU随时可能需要获取的一个单个对象(例如服务例程、任务、一段代码或数据等)的信息。如果试图装载一个数据到一个段寄存器中,CPU需要进行安全性和访问控制检查,来确认是否获得了访问该内存区域的许可。一旦检查结束,一些有用的信息(例如最低和最高地址)被缓存在CPU中的几个不可见的寄存器中。

Intel定义了3种类型的描述符表:中断描述符表IDT(用以替换中断向量表IVT)、全局描述符表GDT和局部描述符表LDT。每个表分别通过LIDT、LGDT、LLDT指令以(size, linear address)的形式定义(注:是载入描述符表的指令,这里就是说表包含了大小和基址组成。)。大多数情况下,操作系统中启动期指定这些表的位置,然后通过一个指针直接读写这些表。

  1. 全局描述符表GDT:
 
全局描述符表在系统中只能有一个,且可以被每一个任务所共享.任何描述符都可以放在GDT中,但中断门和陷阱门放在GDT中是不会起作用的.能被多个任务共享的内存区就是通过GDT完成的,
 
  2. 局部描述符表LDT:
 
局部描述符表在系统中可以有多个,通常情况下是与任务的数量保持对等,但任务可以没有局部描述符表.任务间不相干的部分也是通过LDT实现的.这里涉及到地址映射的问题.和GDT一样,中断门和陷阱门放在LDT中是不会起作用的.
 
  3. 中断描述符表IDT:
 
和GDT一样,中断描述符表在系统最多只能有一个,中断描述符表内可以存放256个描述符,分别对应256个中断.因为每个描述符占用8个字节,所以IDT的长度可达2K.中断描述符表中可以有任务门、中断门、陷阱门三个门描述符,其它的描述符在中断描述符表中无意义。
 
  4. 段选择子
在保护模式下,段寄存器的内容已不是段值,而称其为选择子.该选择子指示描述符在上面这三个表中的位置,所以说选择子即是索引值。
当我们把段选择子装入寄存器时不仅使该寄存器值,同时CPU将该选择子所对应的GDT或LDT中的描述符装入了不可见部分。这样只要我们不进行代码切换(不重新装入新的选择子)CPU就会不会对不可见部分存储的描述符进行更新,可以直接进行访问,加快了访问速度。一旦寄存器被重新赋值,不可见部分也将被重新赋值。

  setup源代码注释

  1. !
  2. ! setup.s (C) Linus Torvalds
  3. !
  4. ! setup.s is responsible for getting the system data from the BIOS,
  5. ! and putting them into the appropriate places in system memory.
  6. ! both setup.s and system has been loaded by the bootblock.
  7. !
  8. ! This code asks the bios for memory/disk/other parameters, and
  9. ! puts them in a "safe" place: 0x90000-0x901FF, ie where the
  10. ! boot-block used to be. It is then up to the protected mode
  11. ! system to read them from there before the area is overwritten
  12. ! for buffer-blocks.
  13. !
  14.  
  15. ! NOTE! These had better be the same as in bootsect.s!
  16.  
  17. INITSEG = 0x9000 ! we move boot here - out of the way
  18. SYSSEG = 0x1000 ! system loaded at 0x10000 ().
  19. SETUPSEG = 0x9020 ! this is the current segment
  20.  
  21. .globl begtext, begdata, begbss, endtext, enddata, endbss
  22. .text
  23. begtext:
  24. .data
  25. begdata:
  26. .bss
  27. begbss:
  28. .text
  29.  
  30. entry start
  31. start:
  32.  
  33. ! ok, the read went well so we get current cursor position and save it for
  34. ! posterity.
  35. ! input:
  36. ! BH = page number.
  37. ! return:
  38. ! DH = row.
  39. ! DL = column.
  40. ! CH = cursor start line.
  41. ! CL = cursor bottom line.
  42. mov ax,#INITSEG ! this is done in bootsect already, but...
  43. mov ds,ax
  44. mov ah,#0x03 ! read cursor pos
  45. xor bh,bh
  46. int 0x10 ! save it in known place, con_init fetches
  47. mov [],dx ! it from 0x90000.光标的行 列的值
  48.  
  49. ! Get memory size (extended mem, kB) 内存大小
  50.  
  51. mov ah,#0x88
  52. int 0x15
  53. mov [],ax
  54.  
  55. ! Get video-card data: 声卡数据
  56.  
  57. mov ah,#0x0f
  58. int 0x10
  59. mov [],bx ! bh = display page
  60. mov [],ax ! al = video mode, ah = window width
  61.  
  62. ! check for EGA/VGA and some config parameters VGA和配置参数
  63.  
  64. mov ah,#0x12
  65. mov bl,#0x10
  66. int 0x10
  67. mov [],ax
  68. mov [],bx
  69. mov [],cx
  70.  
  71. ! Get hd0 data 磁盘第一分区数据
  72.  
  73. mov ax,#0x0000
  74. mov ds,ax
  75. lds si,[*0x41]
  76. mov ax,#INITSEG
  77. mov es,ax
  78. mov di,#0x0080
  79. mov cx,#0x10
  80. rep
  81. movsb
  82.  
  83. ! Get hd1 data 磁盘第二分区数据
  84.  
  85. mov ax,#0x0000
  86. mov ds,ax
  87. lds si,[*0x46]
  88. mov ax,#INITSEG
  89. mov es,ax
  90. mov di,#0x0090
  91. mov cx,#0x10
  92. rep
  93. movsb
  94.  
  95. ! Check that there IS a hd1 :-) 检查是否存在第二个硬盘,不存在则清空磁盘二的参数表
  96.  
  97. mov ax,#0x01500
  98. mov dl,#0x81
  99. int 0x13
  100. jc no_disk1
  101. cmp ah,#
  102. je is_disk1
  103. no_disk1: !清空磁盘二的参数表
  104. mov ax,#INITSEG
  105. mov es,ax
  106. mov di,#0x0090
  107. mov cx,#0x10
  108. mov ax,#0x00
  109. rep
  110. stosb
  111. is_disk1:
  112.  
  113. ! now we want to move to protected mode ...开始我们要保护模式方面的工作了。
  114.  
  115. cli ! no interrupts allowed !cli是关中断,防止有些硬件中断对程序的干扰 sti是开中断,允许硬件中断
  116.  
  117. ! first we move the system to it's rightful place
  118.  
  119. mov ax,#0x0000
  120. cld ! 'direction'=0, movs moves forward cld即告诉程序si,di向前移动,std指令为设置方向,告诉程序si,di向后移动
  121. do_move: ! 0x1000=64k 循环移动ds:si->es:di数据,总共移动cx=(0x9000-0x1000)=0x8000的数据
  122. mov es,ax ! destination segment
  123. add ax,#0x1000
  124. cmp ax,#0x9000
  125. jz end_move
  126. mov ds,ax ! source segment
  127. sub di,di
  128. sub si,si
  129. mov cx,#0x8000
  130. rep
  131. movsw
  132. jmp do_move
  133.  
  134. ! then we load the segment descriptors
  135.  
  136. end_move: ! 从实模式进入保护模式
  137. mov ax,#SETUPSEG ! right, forgot this at first. didn't work :-)
  138. mov ds,ax
  139. lidt idt_48 ! load idt with , 指令以(size=, linear address=)的形式加载中断描述符表
  140. lgdt gdt_48 ! load gdt with whatever appropriate
  141. ! 指令以(size=0x800, linear address=+gdt,0x9)的形式加载全局描述符表
  142.  
  143. ! that was painless, now we enable A20
  144.  
  145. call empty_8042!等待为空
  146. mov al,#0xD1 ! command write
  147. out #0x64,al
  148. call empty_8042
  149. mov al,#0xDF ! A20 on
  150. out #0x60,al
  151. call empty_8042
  152.  
  153. ! well, that went ok, I hope. Now we have to reprogram the interrupts :-(
  154. ! we put them right after the intel-reserved hardware interrupts, at
  155. ! int 0x20-0x2F. There they won't mess up anything. Sadly IBM really
  156. ! messed this up with the original PC, and they haven't been able to
  157. ! rectify it afterwards. Thus the bios puts interrupts at 0x08-0x0f,
  158. ! which is used for the internal hardware interrupts as well. We just
  159. ! have to reprogram the 's, and it isn't fun.
  160.  
  161. mov al,#0x11 ! initialization sequence
  162. out #0x20,al ! send it to 8259A-
  163. .word 0x00eb,0x00eb ! jmp $+, jmp $+
  164. out #0xA0,al ! and to 8259A-
  165. .word 0x00eb,0x00eb
  166. mov al,#0x20 ! start of hardware int's (0x20)
  167. out #0x21,al
  168. .word 0x00eb,0x00eb
  169. mov al,#0x28 ! start of hardware int's (0x28)
  170. out #0xA1,al
  171. .word 0x00eb,0x00eb
  172. mov al,#0x04 ! - is master
  173. out #0x21,al
  174. .word 0x00eb,0x00eb
  175. mov al,#0x02 ! - is slave
  176. out #0xA1,al
  177. .word 0x00eb,0x00eb
  178. mov al,#0x01 ! mode for both
  179. out #0x21,al
  180. .word 0x00eb,0x00eb
  181. out #0xA1,al
  182. .word 0x00eb,0x00eb
  183. mov al,#0xFF ! mask off all interrupts for now
  184. out #0x21,al
  185. .word 0x00eb,0x00eb
  186. out #0xA1,al
  187.  
  188. ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't
  189. ! need no steenking BIOS anyway (except for the initial loading :-).
  190. ! The BIOS-routine wants lots of unnecessary data, and it's less
  191. ! "interesting" anyway. This is how REAL programmers do it.
  192. !
  193. ! Well, now's the time to actually move into protected mode. To make
  194. ! things as simple as possible, we do no register set-up or anything,
  195. ! we let the gnu-compiled -bit programs do that. We just jump to
  196. ! absolute address 0x00000, in -bit protected mode.
  197.  
  198. mov ax,#0x0001 ! protected mode (PE) bit
  199. lmsw ax ! This is it!
  200. jmpi , ! jmp offset of segment (cs)
  201.  
  202. ! This routine checks that the keyboard command queue is empty
  203. ! No timeout is used - if this hangs there is something wrong with
  204. ! the machine, and we probably couldn't proceed anyway.
  205. empty_8042:
  206. .word 0x00eb,0x00eb
  207. in al,#0x64 ! 8042 status port
  208. test al,#2 ! is input buffer full?
  209. jnz empty_8042 ! yes - loop
  210. ret
  211.  
  212. gdt:
  213. .word 0,0,0,0 ! dummy
  214.  
  215. .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
  216. .word 0x0000 ! base address=0
  217. .word 0x9A00 ! code read/exec
  218. .word 0x00C0 ! granularity=4096, 386
  219.  
  220. .word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
  221. .word 0x0000 ! base address=0
  222. .word 0x9200 ! data read/write
  223. .word 0x00C0 ! granularity=4096, 386
  224.  
  225. idt_48:
  226. .word 0 ! idt limit=0
  227. .word 0,0 ! idt base=0L
  228.  
  229. gdt_48:
  230. .word 0x800 ! gdt limit=2048, 256 GDT entries
  231. .word 512+gdt,0x9 ! gdt base = 0X9xxxx
  232.  
  233. .text
  234. endtext:
  235. .data
  236. enddata:
  237. .bss
  238. endbss:

linux kernel 0.11 setup的更多相关文章

  1. linux kernel 0.11 head

    head的作用 注意:bootsect和setup汇编采用intel的汇编风格,而在head中,此时已经进入32位保护模式,汇编的采用的AT&T的汇编语言,编译器当然也就变成对应的编译和连接器 ...

  2. linux kernel 0.11 bootsect

    bootsect作用 ①将自己移动到0x90000处 ②将setup从磁盘读到0x90200处 ③将system从磁盘读到0x10000处 寄存器 汇编代码中存在:数据段data seg 栈段 sta ...

  3. Linux内核0.11 setup文件说明

    一.总体功能介绍 这是关于Linux-kernel-0.11中boot文件夹下setup.s源文件的实现功能的总结说明. setup.s是一个操作系统加载程序,它的主要功能是利用BIOS中断读取机器系 ...

  4. Linux Kernel 4.11首个候选版本开放下载

    Linus Torvalds宣布了即将到来的Linux Kernel 4.11内核分支的首个候选(RC)版本,用户可下载.编译并在自己的GNU/Linux发行版本中进行测试.Linus Torvald ...

  5. Linux Kernel 0.12 启动简介,调试记录(Ubuntu1804, Bochs, gdb)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  6. Linux内核0.11代码阅读(转)

    最近决定开始阅读Linux 0.11的源代码. 学习Linux操作系统的核心概念最好的方法莫过于阅读源代码.而Linux当前最新的源代码包已经有70MB左右,代码十分庞大,要想深入阅读十分困难.而Li ...

  7. Linux内核0.11体系结构 ——《Linux内核完全注释》笔记打卡

    0 总体介绍 一个完整的操作系统主要由4部分组成:硬件.操作系统内核.操作系统服务和用户应用程序,如图0.1所示.操作系统内核程序主要用于对硬件资源的抽象和访问调度. 图0.1 操作系统组成部分 内核 ...

  8. Linux mysql8.0.11安装

    准备:检查是否已安装过mysql,若有便删除(linux系统自带的) rpm -qa | grep mariadb rpm -e nodeps mariadb-libs-5.5.56-2.el7.x8 ...

  9. Linux Kernel 3.11.4/3.10.15/3.4.65/3.0.99

    Linux 今天又发布了4个更新版本,分别是: 3.11.4 2013-10-05 [tar.xz] [pgp] [patch] [view patch] [view inc] [cgit] [cha ...

随机推荐

  1. 在EXCEL中使用SQL查询

    Excel2007及以上版本才有这个功能,2003版本的要么路过学习一下.要么去升级下自己的版本. Microsoft query 用的是 access 语法 如:判断空 oracle ------- ...

  2. Swift 学习一函数&函数属性&懒加载

    函数 函数相当于OC中的方法 格式: func 函数名(参数列表) -> 返回值类型 {    代码块    return 返回值} func 函数名(参数列表){  // 返回值为Void 可 ...

  3. ZJOI2009 假期的宿舍

    题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识. ...

  4. 学习记录 Java常见的几种字符集以及对 AscII的了解

     1.ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte). ...

  5. BFPRT(线性查找算法)

    BFPRT算法解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分 析,BFPRT可以保证在最坏情况下仍为线性时间复杂度.该算法的思想与快速排序思想相似,当然,为使得算法 ...

  6. TCP/IP详解学习笔记(8)-- UDP:用户数据报协议

    1.UDP概述 UDP是一种无连接的, 即发送数据前不需要建立连接,因此减小的开销和发送数据的延迟. UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表. UDP是面向报文 ...

  7. python os模块sys模块常用方法

    官方文档看这里 https://docs.python.org/3.5/library/os.html http://www.cnblogs.com/wupeiqi/articles/5501365. ...

  8. Qt, 我回来了。。。

    说起qt,大学时就有接触,但一直没有深入,这个周六周天利用两于时间重新温习了一下,跟之前用过的vs上的MFC.C++ builder比起来,Qt封装很人性化,库也比较全,写个 一般的小工具很轻松. 参 ...

  9. Android 弹出框

    1.Java package com.fish.helloworld; import android.app.Activity; import android.app.AlertDialog; imp ...

  10. C puzzles详解【26-30题】

    第二十六题(不会) The following is a simple program which implements a minimal version of banner command ava ...