• 从boot引导到loader引导完整运行


     此文针对该文章对loader引导进行了完善后的完整运行过程。(具体细节请参见下文)

    boot引导升级,成功引导运行loader_What’smean的博客-CSDN博客boot引导升级,成功引导运行loaderhttps://blog.csdn.net/weixin_42492218/article/details/127751460?spm=1001.2014.3001.5501

    loader.asm完整代码

    (无注释):

    注释详解请看:  完整的loader引导代码详解_What’smean的博客-CSDN博客

    1. org 10000h
    2. jmp Label_Start
    3. %include "fat12.inc"
    4. BaseOfKernelFile equ 0x00
    5. OffsetOfKernelFile equ 0x100000
    6. BaseTmpOfKernelAddr equ 0x00
    7. OffsetTmpOfKernelFile equ 0x7E00
    8. MemoryStructBufferAddr equ 0x7E00
    9. [SECTION gdt]
    10. LABEL_GDT: dd 0,0
    11. LABEL_DESC_CODE32: dd 0x0000FFFF,0x00CF9A00
    12. LABEL_DESC_DATA32: dd 0x0000FFFF,0x00CF9200
    13. GdtLen equ $ - LABEL_GDT
    14. GdtPtr dw GdtLen - 1
    15. dd LABEL_GDT
    16. SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
    17. SelectorData32 equ LABEL_DESC_DATA32 - LABEL_GDT
    18. [SECTION gdt64]
    19. LABEL_GDT64: dq 0x0000000000000000
    20. LABEL_DESC_CODE64: dq 0x0020980000000000
    21. LABEL_DESC_DATA64: dq 0x0000920000000000
    22. GdtLen64 equ $ - LABEL_GDT64
    23. GdtPtr64 dw GdtLen64 - 1
    24. dd LABEL_GDT64
    25. SelectorCode64 equ LABEL_DESC_CODE64 - LABEL_GDT64
    26. SelectorData64 equ LABEL_DESC_DATA64 - LABEL_GDT64
    27. [SECTION .s16]
    28. [BITS 16]
    29. Label_Start:
    30. mov ax, cs
    31. mov ds, ax
    32. mov es, ax
    33. mov ax, 0x00
    34. mov ss, ax
    35. mov sp, 0x7c00
    36. ;======= display on screen : Start Loader......
    37. mov ax, 1301h
    38. mov bx, 000fh
    39. mov dx, 0200h ;row 2
    40. mov cx, 12
    41. push ax
    42. mov ax, ds
    43. mov es, ax
    44. pop ax
    45. mov bp, StartLoaderMessage
    46. int 10h
    47. ;======= open address A20
    48. push ax
    49. in al, 92h
    50. or al, 00000010b
    51. out 92h, al
    52. pop ax
    53. cli
    54. db 0x66
    55. lgdt [GdtPtr]
    56. mov eax, cr0
    57. or eax, 1
    58. mov cr0, eax
    59. mov ax, SelectorData32
    60. mov fs, ax
    61. mov eax, cr0
    62. and al, 11111110b
    63. mov cr0, eax
    64. sti
    65. ;======= reset floppy
    66. xor ah, ah
    67. xor dl, dl
    68. int 13h
    69. ;======= search kernel.bin
    70. mov word [SectorNo], SectorNumOfRootDirStart
    71. Lable_Search_In_Root_Dir_Begin:
    72. cmp word [RootDirSizeForLoop], 0
    73. jz Label_No_LoaderBin
    74. dec word [RootDirSizeForLoop]
    75. mov ax, 00h
    76. mov es, ax
    77. mov bx, 8000h
    78. mov ax, [SectorNo]
    79. mov cl, 1
    80. call Func_ReadOneSector
    81. mov si, KernelFileName
    82. mov di, 8000h
    83. cld
    84. mov dx, 10h
    85. Label_Search_For_LoaderBin:
    86. cmp dx, 0
    87. jz Label_Goto_Next_Sector_In_Root_Dir
    88. dec dx
    89. mov cx, 11
    90. Label_Cmp_FileName:
    91. cmp cx, 0
    92. jz Label_FileName_Found
    93. dec cx
    94. lodsb
    95. cmp al, byte [es:di]
    96. jz Label_Go_On
    97. jmp Label_Different
    98. Label_Go_On:
    99. inc di
    100. jmp Label_Cmp_FileName
    101. Label_Different:
    102. and di, 0FFE0h
    103. add di, 20h
    104. mov si, KernelFileName
    105. jmp Label_Search_For_LoaderBin
    106. Label_Goto_Next_Sector_In_Root_Dir:
    107. add word [SectorNo], 1
    108. jmp Lable_Search_In_Root_Dir_Begin
    109. ;======= display on screen : ERROR:No KERNEL Found
    110. Label_No_LoaderBin:
    111. mov ax, 1301h
    112. mov bx, 008Ch
    113. mov dx, 0300h ;row 3
    114. mov cx, 21
    115. push ax
    116. mov ax, ds
    117. mov es, ax
    118. pop ax
    119. mov bp, NoLoaderMessage
    120. int 10h
    121. jmp $
    122. ;======= found loader.bin name in root director struct
    123. Label_FileName_Found:
    124. mov ax, RootDirSectors
    125. and di, 0FFE0h
    126. add di, 01Ah
    127. mov cx, word [es:di]
    128. push cx
    129. add cx, ax
    130. add cx, SectorBalance
    131. mov eax, BaseTmpOfKernelAddr ;BaseOfKernelFile
    132. mov es, eax
    133. mov bx, OffsetTmpOfKernelFile ;OffsetOfKernelFile
    134. mov ax, cx
    135. Label_Go_On_Loading_File:
    136. push ax
    137. push bx
    138. mov ah, 0Eh
    139. mov al, '.'
    140. mov bl, 0Fh
    141. int 10h
    142. pop bx
    143. pop ax
    144. mov cl, 1
    145. call Func_ReadOneSector
    146. pop ax
    147. ;;;;;;;;;;;;;;;;;;;;;;;
    148. push cx
    149. push eax
    150. push fs
    151. push edi
    152. push ds
    153. push esi
    154. mov cx, 200h
    155. mov ax, BaseOfKernelFile
    156. mov fs, ax
    157. mov edi, dword [OffsetOfKernelFileCount]
    158. mov ax, BaseTmpOfKernelAddr
    159. mov ds, ax
    160. mov esi, OffsetTmpOfKernelFile
    161. Label_Mov_Kernel: ;------------------
    162. mov al, byte [ds:esi]
    163. mov byte [fs:edi], al
    164. inc esi
    165. inc edi
    166. loop Label_Mov_Kernel
    167. mov eax, 0x1000
    168. mov ds, eax
    169. mov dword [OffsetOfKernelFileCount], edi
    170. pop esi
    171. pop ds
    172. pop edi
    173. pop fs
    174. pop eax
    175. pop cx
    176. ;;;;;;;;;;;;;;;;;;;;;;;
    177. call Func_GetFATEntry
    178. cmp ax, 0FFFh
    179. jz Label_File_Loaded
    180. push ax
    181. mov dx, RootDirSectors
    182. add ax, dx
    183. add ax, SectorBalance
    184. jmp Label_Go_On_Loading_File
    185. Label_File_Loaded:
    186. mov ax, 0B800h
    187. mov gs, ax
    188. mov ah, 0Fh ; 0000: 黑底 1111: 白字
    189. mov al, 'G'
    190. mov [gs:((80 * 0 + 39) * 2)], ax ; 屏幕第 0 行, 第 39 列。
    191. KillMotor:
    192. push dx
    193. mov dx, 03F2h
    194. mov al, 0
    195. out dx, al
    196. pop dx
    197. ;======= get memory address size type
    198. mov ax, 1301h
    199. mov bx, 000Fh
    200. mov dx, 0400h ;row 4
    201. mov cx, 24
    202. push ax
    203. mov ax, ds
    204. mov es, ax
    205. pop ax
    206. mov bp, StartGetMemStructMessage
    207. int 10h
    208. mov ebx, 0
    209. mov ax, 0x00
    210. mov es, ax
    211. mov di, MemoryStructBufferAddr
    212. Label_Get_Mem_Struct:
    213. mov eax, 0x0E820
    214. mov ecx, 20
    215. mov edx, 0x534D4150
    216. int 15h
    217. jc Label_Get_Mem_Fail
    218. add di, 20
    219. cmp ebx, 0
    220. jne Label_Get_Mem_Struct
    221. jmp Label_Get_Mem_OK
    222. Label_Get_Mem_Fail:
    223. mov ax, 1301h
    224. mov bx, 008Ch
    225. mov dx, 0500h ;row 5
    226. mov cx, 23
    227. push ax
    228. mov ax, ds
    229. mov es, ax
    230. pop ax
    231. mov bp, GetMemStructErrMessage
    232. int 10h
    233. jmp $
    234. Label_Get_Mem_OK:
    235. mov ax, 1301h
    236. mov bx, 000Fh
    237. mov dx, 0600h ;row 6
    238. mov cx, 29
    239. push ax
    240. mov ax, ds
    241. mov es, ax
    242. pop ax
    243. mov bp, GetMemStructOKMessage
    244. int 10h
    245. ;======= get SVGA information
    246. mov ax, 1301h
    247. mov bx, 000Fh
    248. mov dx, 0800h ;row 8
    249. mov cx, 23
    250. push ax
    251. mov ax, ds
    252. mov es, ax
    253. pop ax
    254. mov bp, StartGetSVGAVBEInfoMessage
    255. int 10h
    256. mov ax, 0x00
    257. mov es, ax
    258. mov di, 0x8000
    259. mov ax, 4F00h
    260. int 10h
    261. cmp ax, 004Fh
    262. jz .KO
    263. ;======= Fail
    264. mov ax, 1301h
    265. mov bx, 008Ch
    266. mov dx, 0900h ;row 9
    267. mov cx, 23
    268. push ax
    269. mov ax, ds
    270. mov es, ax
    271. pop ax
    272. mov bp, GetSVGAVBEInfoErrMessage
    273. int 10h
    274. jmp $
    275. .KO:
    276. mov ax, 1301h
    277. mov bx, 000Fh
    278. mov dx, 0A00h ;row 10
    279. mov cx, 29
    280. push ax
    281. mov ax, ds
    282. mov es, ax
    283. pop ax
    284. mov bp, GetSVGAVBEInfoOKMessage
    285. int 10h
    286. ;======= Get SVGA Mode Info
    287. mov ax, 1301h
    288. mov bx, 000Fh
    289. mov dx, 0C00h ;row 12
    290. mov cx, 24
    291. push ax
    292. mov ax, ds
    293. mov es, ax
    294. pop ax
    295. mov bp, StartGetSVGAModeInfoMessage
    296. int 10h
    297. mov ax, 0x00
    298. mov es, ax
    299. mov si, 0x800e
    300. mov esi, dword [es:si]
    301. mov edi, 0x8200
    302. Label_SVGA_Mode_Info_Get:
    303. mov cx, word [es:esi]
    304. ;======= display SVGA mode information
    305. push ax
    306. mov ax, 00h
    307. mov al, ch
    308. call Label_DispAL
    309. mov ax, 00h
    310. mov al, cl
    311. call Label_DispAL
    312. pop ax
    313. ;=======
    314. cmp cx, 0FFFFh
    315. jz Label_SVGA_Mode_Info_Finish
    316. mov ax, 4F01h
    317. int 10h
    318. cmp ax, 004Fh
    319. jnz Label_SVGA_Mode_Info_FAIL
    320. add esi, 2
    321. add edi, 0x100
    322. jmp Label_SVGA_Mode_Info_Get
    323. Label_SVGA_Mode_Info_FAIL:
    324. mov ax, 1301h
    325. mov bx, 008Ch
    326. mov dx, 0D00h ;row 13
    327. mov cx, 24
    328. push ax
    329. mov ax, ds
    330. mov es, ax
    331. pop ax
    332. mov bp, GetSVGAModeInfoErrMessage
    333. int 10h
    334. Label_SET_SVGA_Mode_VESA_VBE_FAIL:
    335. jmp $
    336. Label_SVGA_Mode_Info_Finish:
    337. mov ax, 1301h
    338. mov bx, 000Fh
    339. mov dx, 0E00h ;row 14
    340. mov cx, 30
    341. push ax
    342. mov ax, ds
    343. mov es, ax
    344. pop ax
    345. mov bp, GetSVGAModeInfoOKMessage
    346. int 10h
    347. ;======= set the SVGA mode(VESA VBE)
    348. mov ax, 4F02h
    349. mov bx, 4180h ;========================mode : 0x180 or 0x143
    350. int 10h
    351. cmp ax, 004Fh
    352. jnz Label_SET_SVGA_Mode_VESA_VBE_FAIL
    353. ;======= init IDT GDT goto protect mode
    354. cli ;======close interrupt
    355. db 0x66
    356. lgdt [GdtPtr]
    357. ; db 0x66
    358. ; lidt [IDT_POINTER]
    359. mov eax, cr0
    360. or eax, 1
    361. mov cr0, eax
    362. jmp dword SelectorCode32:GO_TO_TMP_Protect
    363. [SECTION .s32]
    364. [BITS 32]
    365. GO_TO_TMP_Protect:
    366. ;======= go to tmp long mode
    367. mov ax, 0x10
    368. mov ds, ax
    369. mov es, ax
    370. mov fs, ax
    371. mov ss, ax
    372. mov esp, 7E00h
    373. call support_long_mode
    374. test eax, eax
    375. jz no_support
    376. ;======= init temporary page table 0x90000
    377. mov dword [0x90000], 0x91007
    378. mov dword [0x90800], 0x91007
    379. mov dword [0x91000], 0x92007
    380. mov dword [0x92000], 0x000083
    381. mov dword [0x92008], 0x200083
    382. mov dword [0x92010], 0x400083
    383. mov dword [0x92018], 0x600083
    384. mov dword [0x92020], 0x800083
    385. mov dword [0x92028], 0xa00083
    386. ;======= load GDTR
    387. db 0x66
    388. lgdt [GdtPtr64]
    389. mov ax, 0x10
    390. mov ds, ax
    391. mov es, ax
    392. mov fs, ax
    393. mov gs, ax
    394. mov ss, ax
    395. mov esp, 7E00h
    396. ;======= open PAE
    397. mov eax, cr4
    398. bts eax, 5
    399. mov cr4, eax
    400. ;======= load cr3
    401. mov eax, 0x90000
    402. mov cr3, eax
    403. ;======= enable long-mode
    404. mov ecx, 0C0000080h ;IA32_EFER
    405. rdmsr
    406. bts eax, 8
    407. wrmsr
    408. ;======= open PE and paging
    409. mov eax, cr0
    410. bts eax, 0
    411. bts eax, 31
    412. mov cr0, eax
    413. jmp SelectorCode64:OffsetOfKernelFile
    414. ;======= test support long mode or not
    415. support_long_mode:
    416. mov eax, 0x80000000
    417. cpuid
    418. cmp eax, 0x80000001
    419. setnb al
    420. jb support_long_mode_done
    421. mov eax, 0x80000001
    422. cpuid
    423. bt edx, 29
    424. setc al
    425. support_long_mode_done:
    426. movzx eax, al
    427. ret
    428. ;======= no support
    429. no_support:
    430. jmp $
    431. ;======= read one sector from floppy
    432. [SECTION .s16lib]
    433. [BITS 16]
    434. Func_ReadOneSector:
    435. push bp
    436. mov bp, sp
    437. sub esp, 2
    438. mov byte [bp - 2], cl
    439. push bx
    440. mov bl, [BPB_SecPerTrk]
    441. div bl
    442. inc ah
    443. mov cl, ah
    444. mov dh, al
    445. shr al, 1
    446. mov ch, al
    447. and dh, 1
    448. pop bx
    449. mov dl, [BS_DrvNum]
    450. Label_Go_On_Reading:
    451. mov ah, 2
    452. mov al, byte [bp - 2]
    453. int 13h
    454. jc Label_Go_On_Reading
    455. add esp, 2
    456. pop bp
    457. ret
    458. ;======= get FAT Entry
    459. Func_GetFATEntry:
    460. push es
    461. push bx
    462. push ax
    463. mov ax, 00
    464. mov es, ax
    465. pop ax
    466. mov byte [Odd], 0
    467. mov bx, 3
    468. mul bx
    469. mov bx, 2
    470. div bx
    471. cmp dx, 0
    472. jz Label_Even
    473. mov byte [Odd], 1
    474. Label_Even:
    475. xor dx, dx
    476. mov bx, [BPB_BytesPerSec]
    477. div bx
    478. push dx
    479. mov bx, 8000h
    480. add ax, SectorNumOfFAT1Start
    481. mov cl, 2
    482. call Func_ReadOneSector
    483. pop dx
    484. add bx, dx
    485. mov ax, [es:bx]
    486. cmp byte [Odd], 1
    487. jnz Label_Even_2
    488. shr ax, 4
    489. Label_Even_2:
    490. and ax, 0FFFh
    491. pop bx
    492. pop es
    493. ret
    494. ;======= display num in al
    495. Label_DispAL:
    496. push ecx
    497. push edx
    498. push edi
    499. mov edi, [DisplayPosition]
    500. mov ah, 0Fh
    501. mov dl, al
    502. shr al, 4
    503. mov ecx, 2
    504. .begin:
    505. and al, 0Fh
    506. cmp al, 9
    507. ja .1
    508. add al, '0'
    509. jmp .2
    510. .1:
    511. sub al, 0Ah
    512. add al, 'A'
    513. .2:
    514. mov [gs:edi], ax
    515. add edi, 2
    516. mov al, dl
    517. loop .begin
    518. mov [DisplayPosition], edi
    519. pop edi
    520. pop edx
    521. pop ecx
    522. ret
    523. ;======= tmp IDT
    524. IDT:
    525. times 0x50 dq 0
    526. IDT_END:
    527. IDT_POINTER:
    528. dw IDT_END - IDT - 1
    529. dd IDT
    530. ;======= tmp variable
    531. RootDirSizeForLoop dw RootDirSectors
    532. SectorNo dw 0
    533. Odd db 0
    534. OffsetOfKernelFileCount dd OffsetOfKernelFile
    535. DisplayPosition dd 0
    536. ;======= display messages
    537. StartLoaderMessage: db "Start Loader"
    538. NoLoaderMessage: db "ERROR:No KERNEL Found"
    539. KernelFileName: db "KERNEL BIN",0
    540. StartGetMemStructMessage: db "Start Get Memory Struct."
    541. GetMemStructErrMessage: db "Get Memory Struct ERROR"
    542. GetMemStructOKMessage: db "Get Memory Struct SUCCESSFUL!"
    543. StartGetSVGAVBEInfoMessage: db "Start Get SVGA VBE Info"
    544. GetSVGAVBEInfoErrMessage: db "Get SVGA VBE Info ERROR"
    545. GetSVGAVBEInfoOKMessage: db "Get SVGA VBE Info SUCCESSFUL!"
    546. StartGetSVGAModeInfoMessage: db "Start Get SVGA Mode Info"
    547. GetSVGAModeInfoErrMessage: db "Get SVGA Mode Info ERROR"
    548. GetSVGAModeInfoOKMessage: db "Get SVGA Mode Info SUCCESSFUL!"

    当boot.asm和loader.asm准备完成后,在将两文件进行编译生成.bin文件之前需要准备一个名为fat12.inc的文件,fatl2 inc文件是从Boot引导程序中提取出的FAT12文件系统结构。

    编写fat12.inc

    vim fat12.inc

    fat12.inc文件内容:

    1. RootDirSectors equ 14
    2. SectorNumOfRootDirStart equ 19
    3. SectorNumOfFAT1Start equ 1
    4. SectorBalance equ 17
    5. BS_OEMName db 'MINEboot'
    6. BPB_BytesPerSec dw 512
    7. BPB_SecPerClus db 1
    8. BPB_RsvdSecCnt dw 1
    9. BPB_NumFATs db 2
    10. BPB_RootEntCnt dw 224
    11. BPB_TotSec16 dw 2880
    12. BPB_Media db 0xf0
    13. BPB_FATSz16 dw 9
    14. BPB_SecPerTrk dw 18
    15. BPB_NumHeads dw 2
    16. BPB_hiddSec dd 0
    17. BPB_TotSec32 dd 0
    18. BS_DrvNum db 0
    19. BS_Reserved1 db 0
    20. BS_BootSig db 29h
    21. BS_VolID dd 0
    22. BS_VolLab db 'boot loader'
    23. BS_FileSysType db 'FAT12 '

     将两文件进行编译生成.bin文件

    1. nasm boot.asm -o boot.bin
    2. nasm loader.asm -o loader.bin

    创建镜像文件/软盘等相关内容

    内容同:在Linux下安装配置bochs,并成功跑一个简单的boot引导(超详细)_What’smean的博客-CSDN博客
    如图所示,建议与bochsrc在同一目录下

     

    创建为软盘即fd,大小默认1.44M即可,命名为boot.img

    之后为查看创建是否成功

     将生成的boot.bin写入img文件中


    执行命令

    dd if=boot.bin of=boot.img bs=512 count=1 conv=notrunc

    这行命令中的if = boot.bin指定输入源文件名,而of=boot .img则指定输出文件名,参数bs=512指定传输的块大小为512B,参数count=1指定写入到目标文件的块数量,参数conv=notrunc规定在写入数据后不截断(改变)输出文件的尺寸大小。

    dd if=boot.bin of=boot.img bs=512 count=1 conv=notrunc
     执行日志:

     将loader.asm写入boot.img镜像中

    当loader.asm程序编译结束后,必须将生成的二进制程序loader.bin复制到虚拟软盘镜像文件boot.img中。此处的复制过程与boot.bin程序的写入过程采用了完全不同方法,当boot.bin程序写入到boot.img虚拟软盘镜像文件后,boot.img虚拟软盘已经拥有了FAT12文件系统,那么应该借助挂载命令mount和复制命令cp,把引导加载程序loader.bin复制到文件系统中。

    整个复制过程需要执行以下命令:

    1. mount boot.img /media/ -t vfat -o loop 挂载 目录 -t vfat 指定磁盘文件系统
    2. cp loader.bin /media/ 复制到文件系统
    3. sync //强制同步命令
    4. umount /media/ //卸载目录

    执行bochs

    bochs -f ./bochsrc

    一路回车然后输入  c  即可,下图为最终效果图

  • 相关阅读:
    JVM内存管理及垃圾回收机制
    Artifact XXXwar exploded Artifact is being deployed, please wait...(已解决)
    《Python进阶系列》二十九:append浅拷贝机制——你真的会用append函数吗?
    使用CSS的Positions布局打造响应式网页
    面向对象编程之类方法@classmethod
    javascript基本语法(一)
    metrics server request failed - “403 Forbidden“
    【容器】docker基础使用
    ciscn_2019_s_9
    C语言qsort函数
  • 原文地址:https://blog.csdn.net/weixin_42492218/article/details/127809184