linux内核代码注释 赵炯 第三章引导启动程序

时间:2024-01-21 08:24:35
  1. linux内核代码注释

第三章引导启动程序

boot目录中的三个汇编代码文件   bootsect.s和setup.s采用近似intel的汇编语法,需要8086汇编器连接器as86和ld86

head.s用GNU的汇编程序格式   并且运行在保护模式下,需要GNU的as进行编译。为AT&T语法的汇编语言程序。GNU只支持386后的cpu  不支持实模式下的程序

总体功能

linux内核代码注释  赵炯  第三章引导启动程序

pc加电-》cpu进入实模式-》从0xfff0开始执行程序代码(bios地址),进行系统检测,并在物理地址0处开始初始化中断向量--》启动设备的第一个扇区  引导扇区 512字节,读入到内存0x7c00处,并且跳转到此。

linux系统最前面的部分就是boot/bootsect.s   由bios读入到内存绝对地址0x7c00  (31k)--》当此程序执行时,会将自己移动到绝对地址0x90000   576k处--》将启动设备中后2k字节代码boot/setup.s读入到内存0x90200处,而内处的其他部分  system模块 则被读入到从地址0x10000开始处,,后面的setup程序会把system模块移动到内存起始处。  看上图

整个系统从地址0x10000移动到0x0000处,进入保护模式并跳转到系统的鱼虾部分  在0x0000处。此时所有的32位运行方式的设置启动完成,IDT    GDT   以及LDT被加载,cpu和协处理器已经确认,分页机制也已经准备就绪

然后嗲用init/main.c程序

一bootsect.s   程序

(1)

磁盘引导块程序   驻留在磁盘的一个扇区中  引导扇区,0磁道  柱面,0磁头,第1个扇区。pc机加电rom-bios自检后,引导扇区由bios加载到内存0x7c00处,然后将自己移动到内存0x90000处。

作用:

1.将setup模块  (由setup.s编译而成)从磁盘加载到内存,紧接着bootsect的后面位置0x90200、

2.利用BIOS中断0x13取磁盘参数表中当前启动引导盘的参数

3.在屏幕上显示loading system... 字符串

4.将system模块从磁盘加载到内存0x10000开始处,

5.确定根文件系统的设备号   若未指定,则根据所保存的引导盘的每磁道扇区数判别处盘的类型和种类  并保存其设备号于root_dev   引导块0x508地址处,最后长跳转到setup程序的开始处   0x90200   执行setup程序。

(2)代码注释

  1. !
  2. ! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
  3. ! 0x3000 is 0x30000 bytes = 196kB, more than enough for current
  4. ! versions of linux
  5. !
  6. SYSSIZE = 0x3000
  7. !
  8. ! bootsect.s (C) 1991 Linus Torvalds
  9. !
  10. ! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves
  11. ! iself out of the way to address 0x90000, and jumps there.
  12. !
  13. ! It then loads 'setup' directly after itself (0x90200), and the system
  14. ! at 0x10000, using BIOS interrupts.
  15. !
  16. ! NOTE! currently system is at most 8*65536 bytes long. This should be no
  17. ! problem, even in the future. I want to keep it simple. This 512 kB
  18. ! kernel size should be enough, especially as this doesn't contain the
  19. ! buffer cache as in minix
  20. !
  21. ! The loader has been made as simple as possible, and continuos
  22. ! read errors will result in a unbreakable loop. Reboot by hand. It
  23. ! loads pretty fast by getting whole sectors at a time whenever possible.
  24. .globl begtext, begdata, begbss, endtext, enddata, endbss //段定义
  25. .text
  26. begtext:
  27. .data
  28. begdata:
  29. .bss
  30. begbss:
  31. .text
  32. SETUPLEN = 4 ! nr of setup-sectors 扇区数量    定义
  33. BOOTSEG  = 0x07c0 ! original address of boot-sector 开始段
  34. INITSEG  = 0x9000 ! we move boot here - out of the way 初始段
  35. SETUPSEG = 0x9020 ! setup starts here setup程序所在段
  36. SYSSEG   = 0x1000 ! system loaded at 0x10000 (65536). 系统模块段
  37. ENDSEG   = SYSSEG + SYSSIZE ! where to stop loading 停止加载的位置
  38. ! ROOT_DEV: 0x000 - same type of floppy as boot. 软盘类型
  39. ! 0x301 - first partition on first drive etc 硬盘类型
  40. ROOT_DEV = 0x306 启动盘设备类型
  41. entry start 程序入口地址
  42. start:
  43. mov ax,#BOOTSEG
  44. mov ds,ax ds段基地址
  45. mov ax,#INITSEG
  46. mov es,ax es段基地址
  47. mov cx,#256
  48. sub si,si si和di均清0
  49. sub di,di
  50. rep 循环256次    共512个字节的内容
  51. movw 传送字 将bootseg段的代码移动到es指向的initseg段
  52. jmpi go,INITSEG 跳转到initseg段的go标号位置
  53. go: mov ax,cs cs   ds    es指向相同的位置
  54. mov ds,ax
  55. mov es,ax
  56. ! put stack at 0x9ff00.
  57. mov ss,ax ss堆栈段基址位0x9ff00
  58. mov sp,#0xFF00 ! arbitrary value >>512 sp指针的位置调整ss:sp=0x90000:ff00位置  此时位空栈        以上为初始化
  59. ! load the setup-sectors directly after the bootblock.
  60. ! Note that 'es' is already set up.
  61. load_setup: 加载setup程序
  62. mov dx,#0x0000 ! drive 0, head 0 驱动器0   磁头0   dh磁头   dl驱动器号
  63. mov cx,#0x0002 ! sector 2, track 0 扇区2 磁道0      ch磁道号  柱面号    cl开始扇区
  64. mov bx,#0x0200 ! address = 512, in INITSEG 512个字节
  65. mov ax,#0x0200+SETUPLEN ! service 2, nr of sectors ah=2  功能号为2        al=4 扇区数量
  66. int 0x13 ! read it 中断13  读磁盘的功能     读如到es:bx  数据缓冲区
  67. jnc ok_load_setup ! ok - continue 判断cf标志位   cf=0正常   cf=1 出错
  68. mov dx,#0x0000
  69. mov ax,#0x0000 ! reset the diskette 重设寄存器
  70. int 0x13 调用中断13号  复位磁盘
  71. j load_setup 跳转load_setup
  72. ok_load_setup:
  73. ! Get disk drive parameters, specifically nr of sectors/track 以下为获取磁盘驱动器的参数
  74. mov dl,#0x00
  75. mov ax,#0x0800 ! AH=8 is get drive parameters
  76. int 0x13 中断13   ah为8调用获取磁盘参数
  77. mov ch,#0x00 ch清0
  78. seg cs 找cs段执行指令   下一条指令在cs段
  79. mov sectors,cx 保存每磁道扇区数
  80. mov ax,#INITSEG es指向0x9000的段处
  81. mov es,ax
  82. ! Print some inane message
  83. mov ah,#0x03 ! read cursor pos
  84. xor bh,bh
  85. int 0x10 中断  读取光标位置
  86. mov cx,#24 共24个字符
  87. mov bx,#0x0007 ! page 0, attribute 7 (normal) bh为页    bl为属性
  88. mov bp,#msg1 es:bp指向要显示的字符串
  89. mov ax,#0x1301 ! write string, move cursor ah为13 显示字符串功能,  al为1表示写方式
  90. int 0x10 中断调用
  91. ! ok, we've written the message, now
  92. ! we want to load the system (at 0x10000)
  93. mov ax,#SYSSEG es指向0x1000处
  94. mov es,ax ! segment of 0x010000
  95. call read_it 调用子程序    134行
  96. call kill_motor 关闭马达 214行
  97. ! After that we check which root-device to use. If the device is
  98. ! defined (!= 0), nothing is done and the given device is used.
  99. ! Otherwise, either /dev/PS0 (2,28) or /dev/at0 (2,8), depending
  100. ! on the number of sectors that the BIOS reports currently.
  101. seg cs
  102. mov ax,root_dev
  103. cmp ax,#0
  104. jne root_defined
  105. seg cs
  106. mov bx,sectors
  107. mov ax,#0x0208 ! /dev/ps0 - 1.2Mb
  108. cmp bx,#15
  109. je root_defined
  110. mov ax,#0x021c ! /dev/PS0 - 1.44Mb
  111. cmp bx,#18
  112. je root_defined
  113. undef_root:
  114. jmp undef_root
  115. root_defined:
  116. seg cs
  117. mov root_dev,ax
  118. ! after that (everyting loaded), we jump to
  119. ! the setup-routine loaded directly after
  120. ! the bootblock:
  121. jmpi 0,SETUPSEG
  122. ! This routine loads the system at address 0x10000, making sure
  123. ! no 64kB boundaries are crossed. We try to load it as fast as
  124. ! possible, loading whole tracks whenever we can.
  125. !
  126. ! in: es - starting address segment (normally 0x1000)
  127. !
  128. sread: .word 1+SETUPLEN ! sectors read of current track 磁道中已经读取的扇区数  开始时已经读取1扇区   bootsect和setup程序所占的扇区数为setuplen
  129. head: .word 0 ! current head
  130. track: .word 0 ! current track
  131. read_it:
  132. mov ax,es
  133. test ax,#0x0fff es必须是64k边界   es实际指向的内存为0x10000共20位  相与的是高16位     数值结果不保存
  134. die: jne die ! es must be at 64kB boundary
  135. xor bx,bx ! bx is starting address within segment      bx指向段基地址
  136. rp_read:
  137. mov ax,es
  138. cmp ax,#ENDSEG ! have we loaded all yet?    判断es是否等于停止加载的段地址
  139. jb ok1_read 小于时跳转到ok1_read标号处继续执行,否则返回
  140. ret
  141. ok1_read:
  142. seg cs cs段的指令执行
  143. mov ax,sectors 取每磁道扇区数
  144. sub ax,sread ax-sread  等于未读取的扇区数  结果送ax
  145. mov cx,ax
  146. shl cx,#9 左移9位  相当于乘以512  结果为未读扇区的字节数
  147. add cx,bx 加上bx(段内偏移值)   此次读操作后段内读入字节数
  148. jnc ok2_read cf标志位判断   是否有进位  如果不等于1  则跳转,即没有超过64k
  149. je ok2_read 等于64k则跳转    156行处
  150. xor ax,ax 超过64k   即加上此次将读磁道上所有未读扇区时会超过64k ,则ax清0
  151. sub ax,bx ax-bx  计算此次能读入的字节数    64k-bx(段内读偏移)
  152. shr ax,#9 再次将字节数转换成扇区数    右移9位 相当于除以512
  153. ok2_read:
  154. call read_track 调用read_track
  155. mov cx,ax
  156. add ax,sread
  157. seg cs
  158. cmp ax,sectors
  159. jne ok3_read
  160. mov ax,#1
  161. sub ax,head
  162. jne ok4_read
  163. inc track
  164. ok4_read:
  165. mov head,ax
  166. xor ax,ax
  167. ok3_read:
  168. mov sread,ax
  169. shl cx,#9
  170. add bx,cx
  171. jnc rp_read
  172. mov ax,es
  173. add ax,#0x1000
  174. mov es,ax
  175. xor bx,bx
  176. jmp rp_read
  177. read_track:
  178. push ax
  179. push bx
  180. push cx
  181. push dx
  182. mov dx,track
  183. mov cx,sread
  184. inc cx
  185. mov ch,dl
  186. mov dx,head
  187. mov dh,dl
  188. mov dl,#0
  189. and dx,#0x0100
  190. mov ah,#2
  191. int 0x13
  192. jc bad_rt
  193. pop dx
  194. pop cx
  195. pop bx
  196. pop ax
  197. ret
  198. bad_rt: mov ax,#0
  199. mov dx,#0
  200. int 0x13
  201. pop dx
  202. pop cx
  203. pop bx
  204. pop ax
  205. jmp read_track
  206. /*
  207. * This procedure turns off the floppy drive motor, so
  208. * that we enter the kernel in a known state, and
  209. * don't have to worry about it later.
  210. */
  211. kill_motor:
  212. push dx
  213. mov dx,#0x3f2
  214. mov al,#0
  215. outb
  216. pop dx
  217. ret
  218. sectors:
  219. .word 0
  220. msg1:
  221. .byte 13,10
  222. .ascii "Loading system ..."
  223. .byte 13,10,13,10
  224. .org 508
  225. root_dev:
  226. .word ROOT_DEV
  227. boot_flag:
  228. .word 0xAA55
  229. .text
  230. endtext:
  231. .data
  232. enddata:
  233. .bss
  234. endbss: