Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

434 lines
9.6 KiB

  1. ;++
  2. ;
  3. ;Copyright (c) 1995 Microsoft Corporation
  4. ;
  5. ;Module Name:
  6. ;
  7. ; bioschk.asm
  8. ;
  9. ;Abstract:
  10. ;
  11. ; The code in this "image" is responsible for checking if is appropriate
  12. ; for us to start setupldr.bin. We consider this appropriate when we pass
  13. ; BIOS checkings. Setupldr.bin is binary appended at the end of this image.
  14. ;
  15. ;Author:
  16. ;
  17. ; Calin Negreanu (calinn) 16-Dec-1999
  18. ;
  19. ;Environment:
  20. ;
  21. ; Real mode
  22. ; Case 1:
  23. ; Complete image has been loaded at 2000:0000 by the boot code
  24. ; DL = meaningfull data
  25. ; Case 2:
  26. ; First 512 bytes of this image has been loaded at 2000:000 by the boot code
  27. ; BX = meaningfull data
  28. ; DL = meaningfull data
  29. ; DS:SI -> points to a structure containing meaningfull data
  30. ; DS:DI -> points to a structure containing meaningfull data
  31. ;
  32. ;Revision History:
  33. ;
  34. ;--
  35. page ,132
  36. title boot - BIOS check
  37. name bioschk
  38. .8086
  39. CODE SEGMENT
  40. ASSUME CS:CODE,DS:CODE,SS:NOTHING,ES:NOTHING
  41. ORG 0000H
  42. _BiosChk label byte
  43. BiosChkDestSeg EQU 1000h
  44. SetupLdrDestSeg EQU 2000h
  45. MaxCodeSize EQU 0800h ;number of paragraphs (32k)
  46. MaxSetupLdrSize EQU 4000h ;number of paragraphs (256k)
  47. StackSeg EQU 1000h ;stack goes from here
  48. MAXREAD EQU 10000h
  49. MAXSECTORS EQU MAXREAD/0200h
  50. DoubleWord struc
  51. lsw dw ?
  52. msw dw ?
  53. DoubleWord ends
  54. SHARED struc
  55. ReadClusters dd ?
  56. ReadSectors dd ?
  57. SectorBase dd ?
  58. SHARED ends
  59. BPB struc
  60. BytesPerSector dw ?
  61. SectorsPerCluster db ?
  62. ReservedSectors dw ?
  63. Fats db ?
  64. DirectoryEntries dw ?
  65. Sectors dw ?
  66. Media db ?
  67. FatSectors dw ?
  68. SectorsPerTrack dw ?
  69. Heads dw ?
  70. HiddenSectors dd ?
  71. SectorsLong dd ?
  72. BootDriveNumber db ?
  73. BPB ends
  74. JMPFAR MACRO DestOfs,DestSeg
  75. db 0eah
  76. dw OFFSET DestOfs
  77. dw DestSeg
  78. endm
  79. START:
  80. ; If we boot from FAT drives, the next instruction is not executed.
  81. jmp RealStart
  82. FatBegin:
  83. .386
  84. ;
  85. ; If we're here, we've booted off a FAT system and we must load the rest
  86. ; of the binary image at 2000:0200 (right behind this sector).
  87. ;
  88. ;
  89. ; Save away meaningfull data
  90. ;
  91. push dx
  92. push bx
  93. .386
  94. push 06000h
  95. .8086
  96. pop es
  97. xor bx,bx
  98. mov cx,ds:[si].ReservedSectors
  99. mov ds:[di].SectorBase.msw,0
  100. mov ds:[di].SectorBase.lsw,cx
  101. mov ax,ds:[si].FatSectors
  102. cmp ax,080h
  103. jbe FatLt64k
  104. push cx
  105. mov ax,080h
  106. call ds:[di].ReadSectors
  107. pop cx
  108. .386
  109. push 07000h
  110. .8086
  111. pop es
  112. xor bx,bx
  113. mov ax,ds:[si].FatSectors
  114. sub ax,080h
  115. add cx,080h
  116. mov ds:[di].SectorBase.lsw,cx
  117. adc ds:[di].SectorBase.msw,0
  118. FatLt64k:
  119. call ds:[di].ReadSectors
  120. pop dx
  121. xor bx,bx
  122. .386
  123. mov ax,6000h
  124. mov fs,ax
  125. mov ax,7000h
  126. mov gs,ax
  127. .8086
  128. push cs
  129. pop es
  130. mov ah,MAXSECTORS
  131. FatLoop:
  132. push dx
  133. mov al,ds:[si].SectorsPerCluster
  134. sub ah,ds:[si].SectorsPerCluster
  135. cmp dx,0ffffh
  136. jne Fat10
  137. pop dx
  138. pop dx
  139. jmp RealStart
  140. Fat10:
  141. mov cx,dx
  142. call NextFatEntry
  143. inc cx
  144. cmp dx,cx
  145. jne LncLoad
  146. cmp ah,0
  147. jne Lnc20
  148. mov ah,MAXSECTORS
  149. jmp short LncLoad
  150. Lnc20:
  151. add al,ds:[si].SectorsPerCluster
  152. sub ah,ds:[si].SectorsPerCluster
  153. jmp short Fat10
  154. LncLoad:
  155. pop cx
  156. push dx
  157. mov dx,cx
  158. mov cx,10
  159. FatRetry:
  160. push bx
  161. push ax
  162. push dx
  163. push cx
  164. call [di].ReadClusters
  165. jnc ReadOk
  166. mov ax,01h
  167. mov al,ds:[si].BootDriveNumber
  168. int 13h
  169. xor ax,ax
  170. mov al,ds:[si].BootDriveNumber
  171. int 13h
  172. xor ax,ax
  173. FatPause:
  174. dec ax
  175. jnz FatPause
  176. pop cx
  177. pop dx
  178. pop ax
  179. pop bx
  180. dec cx
  181. jnz FatRetry
  182. push cs
  183. pop ds
  184. mov si,offset FAT_ERROR
  185. FatErrPrint:
  186. lodsb
  187. or al,al
  188. jz FatErrDone
  189. mov ah,14
  190. mov bx,7
  191. int 10h
  192. jmp FatErrPrint
  193. FatErrDone:
  194. jmp $
  195. FAT_ERROR db 13,10,"Disk I/O error",0dh,0ah,0
  196. ReadOk:
  197. pop cx
  198. pop dx
  199. pop ax
  200. pop bx
  201. pop dx
  202. .386
  203. mov cl,al
  204. xor ch,ch
  205. shl cx,9
  206. .8086
  207. add bx,cx
  208. jz FatLoopDone
  209. jmp FatLoop
  210. FatLoopDone:
  211. mov ax,es
  212. add ax,01000h
  213. mov es,ax
  214. mov ah,MAXSECTORS
  215. jmp FatLoop
  216. NextFatEntry proc near
  217. push bx
  218. call IsFat12
  219. jnc Next16Fat
  220. Next12Fat:
  221. mov bx,dx
  222. shr dx,1
  223. pushf
  224. add bx,dx
  225. .386
  226. mov dx,fs:[bx]
  227. .8086
  228. popf
  229. jc shift
  230. and dx,0fffh
  231. jmp short N12Tail
  232. shift:
  233. .386
  234. shr dx,4
  235. .8086
  236. N12Tail:
  237. cmp dx,0ff8h
  238. jb NfeDone
  239. mov dx,0ffffh
  240. jmp short NfeDone
  241. Next16Fat:
  242. add dx,dx
  243. jc N16high
  244. mov bx,dx
  245. .386
  246. mov dx,fs:[bx]
  247. .8086
  248. jmp short N16Tail
  249. N16high:
  250. mov bx,dx
  251. .386
  252. mov dx,gs:[bx]
  253. .8086
  254. N16Tail:
  255. cmp dx,0fff8h
  256. jb NfeDone
  257. mov dx,0ffffh
  258. NfeDone:
  259. pop bx
  260. ret
  261. NextFatEntry endp
  262. IsFat12 proc near
  263. .386
  264. push eax
  265. push ebx
  266. push ecx
  267. push edx
  268. movzx ecx, ds:[si].Sectors
  269. or cx,cx
  270. jnz if10
  271. mov ecx, ds:[si].SectorsLong
  272. if10:
  273. movzx ebx, byte ptr ds:[si].Fats
  274. movzx eax, word ptr ds:[si].FatSectors
  275. mul ebx
  276. sub ecx,eax
  277. movzx eax, word ptr ds:[si].DirectoryEntries
  278. shl eax, 5
  279. mov edx,eax
  280. and edx,0ffff0000h
  281. div word ptr ds:[si].BytesPerSector
  282. sub ecx,eax
  283. movzx eax, word ptr ds:[si].ReservedSectors
  284. sub ecx, eax
  285. mov eax, ecx
  286. movzx ecx, byte ptr ds:[si].SectorsPerCluster
  287. xor edx,edx
  288. div ecx
  289. cmp eax, 4087
  290. jae if20
  291. stc
  292. jmp short if30
  293. if20:
  294. clc
  295. if30:
  296. pop edx
  297. pop ecx
  298. pop ebx
  299. pop eax
  300. ret
  301. .8086
  302. IsFat12 endp
  303. Free EQU 512-($-Start)
  304. if Free lt 0
  305. %out FATAL PROBLEM: FAT-specific startup code is greater than
  306. %out 512 bytes. Fix it!
  307. .err
  308. endif
  309. RealStart:
  310. ;
  311. ; we are completely done with the boot sector, we can party on it's memory as we like.
  312. ; set up the stack
  313. ;
  314. mov ax,StackSeg
  315. mov ss,ax
  316. xor sp,sp
  317. mov ax,cs
  318. mov ds,ax
  319. mov es,ax
  320. ;
  321. ; save setupldr data
  322. ;
  323. mov Preserve, dl
  324. ; move ourselves from 2000:0000 to 1000:0000, one paragraph at a time.
  325. mov ax, BiosChkDestSeg
  326. mov es, ax
  327. mov dx, MaxCodeSize
  328. cld
  329. Again1:
  330. xor di, di
  331. xor si, si
  332. mov cx, 10h
  333. rep movsb
  334. mov ax, ds
  335. inc ax
  336. mov ds, ax
  337. mov ax, es
  338. inc ax
  339. mov es, ax
  340. dec dx
  341. jnz Again1
  342. mov ax, BiosChkDestSeg
  343. mov ds, ax
  344. mov es, ax
  345. JMPFAR Continue1, BiosChkDestSeg
  346. Continue1:
  347. ; insert your BIOS check code here
  348. ; instead of a real BIOS check we will check if the user holds down CTRL.
  349. ; If yes, we will behave like BIOS check failed
  350. mov ah,02h
  351. int 16h
  352. and al,00000100b
  353. jz MoveSetupLdr
  354. ; at this point, the BIOS check failed. You can add whatever code you want here
  355. ; to give a message or to make the computer crash. If you don't do anything, the
  356. ; code will jump to 2000:0000 so an infinite loop is going to happen.
  357. jmp Continue2
  358. MoveSetupLdr:
  359. ; move Setupldr code from 2000+MaxCodeSize:0000 to 2000:0000, one paragraph at a time.
  360. push ds
  361. push es
  362. mov ax, SetupLdrDestSeg
  363. mov es, ax
  364. add ax, MaxCodeSize
  365. mov ds, ax
  366. mov dx, MaxSetupLdrSize
  367. cld
  368. Again2:
  369. xor di, di
  370. xor si, si
  371. mov cx, 10h
  372. rep movsb
  373. mov ax, ds
  374. inc ax
  375. mov ds, ax
  376. mov ax, es
  377. inc ax
  378. mov es, ax
  379. dec dx
  380. jnz Again2
  381. pop es
  382. pop ds
  383. Continue2:
  384. mov dl, Preserve
  385. JMPFAR 0,SetupLdrDestSeg
  386. Preserve db ?
  387. .errnz ($-_BiosChk) GT (MaxCodeSize*16 - 2) ;FATAL: BiosChk code is too large
  388. org MaxCodeSize*16 - 2
  389. db 55h,0aah
  390. CODE ENDS
  391. END START