[bits 16]
[org 0x7c00] ; 告诉编译器程序加载到7c00处
CATALOG equ 0x7E00;catalog loaded at 0x7e00
KERNEL equ 0x500;kernel.bin loaded at 0x500.
jmp Start
; 引导区文件系统数据
;----------------------------------------------------------------------------
brOEM DB " T's OS " ; 0003h - 引导程序的名字
brBPS DW 0x200 ; 000Bh - 每扇区的字节数 512
brSPC DB 0x01 ; 000Dh - 每簇扇区数
brResCount DW 0x0001 ; 000Eh - 保留扇区数
brFATs DB 0x02 ; 0010h - FAT 备份数
brRootEntries DW 0x00e0 ; 0011h - 根目录文件数
brSectorCount
DW 2880 ; 0013h - 磁盘容量扇区数< 32MB
brMedia DB 240 ; 0015h - 媒体描述符
brSPF DW 9 ; 0016h - 每FAT扇区数
brSPH DW 18 ; 0018h - 每磁道扇区数
brHPC DW 2 ; 001Ah - 盘面数
brHidden DD 0 ; 001Ch - 隐藏扇区数
brSectors DD 0 ; 0020h - 如果大于32m的扇区总数
DB 0 ; 0024h - 物理驱动器号
DB 0 ; 0025h - 系统保留
DB 29H ; 0026h - 扩展扇区标记(包含29h)
brSerialNum DD 00000006H ; 0027h - 卷ID
brLabel DB 'NO NAME ' ; 002Bh - 卷标
brFSID DB 'FAT12 ' ; 0036h - 系统保留
;------------------------------------------------------------------------
Start:
mov ax, cs
mov ds, ax
mov es, ax
mov ax,0x8000 ;栈放在0x1F00段里,这里栈有问题(栈放在0x1F00段里)!!!!!!!!!!!!!!!
mov ss,ax
mov sp,0xffff; 堆栈入口
call DispStr ; 调用显示字符串例程
call LoadFile; 把目录区读入到200的地方
call FindFile; 在200的地方找把kernel.bin,读出来并显示读取成功
;=============================================
;SwitchPro建立GDT,进入保护模式
;=============================================
SwitchPro;
; 打开A20
in al, 92h
or al, 00000010b
out 92h, al
; end 打开A20
; 设置GDT
cli
;mov ax,KERNEL; lgdt 指令加载 gdtr 是以ds为数据段加载
;mov ds,ax
;lea si, [dword gdtr]
lgdt [gdtr]
;lea si, [dword idtr]
;lidt [dword gdtr]
mov eax, cr0
or eax,1
mov cr0, eax
jmp dword selcode:CODE32;进入保护模式,并且跳到下面的段中
;jmp KERNEL;保护模式下该怎样跳到kenel.bin开始执行内核?
[bits 32]
CODE32:
sti
moveax,codesel_gdt
movebx,datasel_gdt
movax,ProMessage
movbp,ax
movcx,ProMsglength
jmp$; 到此停止!!!!!!!!!!!!!!!!!!!!!!!
[bits 16]
;===================================================================
;初始化gdtr和gdt
;===================================================================
gdtr:
dw gdt_end - gdt-1; gdt的长度--16位(800H)GDT界限gdt limit=2048, 256 GDT entries
;这里应该是伪长度7,15,23,31,因为从0开始计算的
dd gdt ; gdt的物理地址--32位GDT基地址
;0x00007c930017!!!!!!!!
gdt:
gdt0:
dw 0,0,0,0 ; 一定要为0
codesel_gdt:
dw 0xffff ; 界限Limit值 = 0x100000 * 0x1000 = 4GB
dw 0x0000 ; 基地址 = 0
db 0x00
db 0x9A ; 表示 存在 可执行可读代码段
db 0xCF ; 粒度以及32位代码1100=0XC
db 0x00
datasel_gdt:
dw 0xffff ; 界限4GB
dw 0x0000 ; 基地址
db 0x00
db 0x92 ; 表示 存在 可读写数据段
db 0xCF ; 粒度以及数据锻大小4G,1100=0XC
db 0x00
gdt_end:
selcode equ codesel_gdt - gdt;索引值1,2,3....
seldata equ datasel_gdt - gdt
;=============================================
;DispStr 显示boot已经启动!
;=============================================
DispStr:
mov ax, BootMessage
mov bp, ax ; es:bp = 串地址
mov cx, Msglength ; cx = 串长度
call PrintMsg
ret
;=============================================
;LoadFile 把目录从软盘中读出来!
;=============================================
LoadFile:
mov ax,19;开始的扇区
mov bx,CATALOG ;目录放在7E00H的地方!!!!!!!!!!!!!!!!!!!!!!!!!!!
mov cx,14;目录扇区个数
loopreadsec:
push ax
push bx
push cx
call LBACHS ; 调用转换
mov dl, 0 ; 因为是a:所以为0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mov ah, 0x02 ; BIOS 读取扇区命令
mov al, 0x01 ; 一个扇区
int 0x13 ; 调用中断
nop
pop cx
pop bx
pop ax
add bx,200
inc ax
loop loopreadsec
ret
;=============================================
; 转换逻辑块访问为读取磁盘所使用的磁道,盘面,扇区
; 相对扇区 = (逻辑扇区 / 每磁道扇区数) + 1
; 相对盘面 = (逻辑扇区 / 每磁道扇区数) MOD 盘面数
; 相对磁道 = 逻辑扇区 / (每磁道扇区数 * 盘面数)
;=============================================
LBACHS:
xor dx, dx ; dx = 0
mov cx,18
div cx ; div: ax/18 -> 商:ax 余数:dx
inc dl ;sec ;
mov cl, dl ;sector
xor dx, dx ; dx = 0
push bx
mov bx,2
div bx ; ax/2 -> 商:ax 余数:dx
pop bx
mov ch, al ; track
mov dh, dl ; head
ret
;=============================================
;FindFile 查找文件名,并且装到0x500,显示Load Kernel.bin Success!
;=============================================
FindFile:
cld;地址自动增加
mov cx,224;根目录共有224个文件
mov di,CATALOG;目录放在7E00H的地方!!!!!!!!!!!!!!!!!!!!!
.l_findfile:
push cx
lea si,[Kernel] ;?
push di
mov cx,11;8+3=0xb文件名和后缀长度
repe cmpsb
pop di
je findfile_ok
add di,32;开始找下1个文件
pop cx
loop .l_findfile
mov ax, LoadKerFail;失败
mov bp, ax ; es:bp = 串地址
mov cx, LoadKerFaillength ; cx = 串长度
call PrintMsg
ret
findfile_ok:
pop cx
add di,26;取文件占用的第一个簇号,即起始簇
mov ax,[di]
add ax,31;簇转成扇区
mov bx,KERNEL;文件放在0x500!!!!!!!!!!!!!!!!!!!!!!!!!!!
call LBACHS ; 调用转换
mov dl, 0 ; 因为是a:所以为0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
mov ah, 0x02 ; BIOS 读取扇区命令
mov al, 0x03 ; 一个扇区,这里不应该只读一个扇区,应该根据文件大小来决定!!!!!
int 0x13 ; 调用中断,内核放在0x1e00!
mov ax, LoadKerSuess;成功
mov bp, ax ; es:bp = 串地址
mov cx, LoadKerlength ; cx = 串长度
call PrintMsg
ret
;=============================================
;显示信息
;=============================================
PrintMsg:
mov ax, 01301h ; ah = 13, al = 01h
mov bx, 000ch ; 页号为0(bh = 0) 黑底红字(bl = 0Ch,高亮)
mov dl, 0
mov dh, BYTE [NoLine]
int 10h ; 10h 号中断
add dh,1
mov BYTE [NoLine],dh
ret
BootMessage: db "Welcome to T's OS!",0x0D,0x0A
Msglength equ $-BootMessage
DB 0x00
Kernel: db 'KERNEL BIN';8+3=11位;将来这里改成内核的文件名!!!!!!!!!!!!!
LoadKerSuess: db 'Load Kernel.bin Success!',0x0D,0x0A
LoadKerlength equ $-LoadKerSuess
DB 0x00
LoadKerFail: db 'Load Kernel.bin Fail!',0x0D,0x0A
LoadKerFaillength equ $-LoadKerFail
DB 0x00
ProMessage: db "I'm in the Pro Mode!",0x0D,0x0A
ProMsglength equ $-ProMessage
DB 0x00
NoLine DB 0x00
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志
;把这段代码用NASM编译一下:
;nasm boot.asm –o boot.bin
;应该把内核在pro模式下加载就对了!
版权声明:本文为博主原创文章,未经博主允许不得转载。
分享到:
相关推荐
1. **启动模式**:STM32有多种启动模式,如HSI(内部高速时钟)、HSI48(内部48MHz时钟)、MSI(多速内部时钟)、HSE(外部高速时钟)等,Bootloader需要根据配置选择合适的启动模式。 2. **闪存编程**:STM32的...
这个我成功解BL锁后的配置环境和使用工具。 这个压缩包已经配置号的PHP8.3和Xiaomi-HyperOS-BootLoader-Bypass的解BL锁的软件 另外我还添加了settings.apk增加成功率。
这个压缩包文件"stm32_bootloader-master_stm32bootloader_Bootloader_stm32bootload"包含了一个STM32 Bootloader的源代码库,用于理解和开发自己的STM32 Bootloader。 STM32是意法半导体(STMicroelectronics)...
了解以上知识点后,无论是对3D打印爱好者还是开发者来说,都能更好地理解并利用mkstft35_V1_open_bootloader来改进和定制自己的3D打印设备。通过深入学习这个开源项目,我们可以提升对Bootloader原理的理解,也能...
STM32DUINO Bootloader项目解决了这个问题,通过适配使得STM32微控制器可以与Arduino IDE兼容,为开发者提供了一种熟悉的编程环境。 在"STM32duino-bootloader-master.zip"压缩包中,包含了STM32DUINO Bootloader...
【BootLoader-prj】这个文件可能是项目源代码或者编译后的二进制文件,包含实现上述BootLoader功能的具体代码。开发者可以通过查看这些文件来了解BootLoader的工作原理,学习如何编写针对LPC1768的BootLoader,或者...
5. **传递控制给操作系统内核**:完成所有准备工作后,BootLoader将控制权交给操作系统内核,此时,内核开始自己的初始化流程。 ### 核心知识点详解 #### 硬件初始化 硬件初始化是BootLoader中最基础也是最重要的...
stm32-can-bootloader-master STM32F1XX 系列MCU bootloader CAN 通讯升级,只需要更改APP跳转地址和CANH,CANL 定义口就可以使用了,调试通过
STM32 Bootloader是嵌入式系统开发中的关键部分,它是微控制器在上电或复位后执行的第一段代码,负责加载应用程序或者进行固件更新。STM32 Bootloader源代码的深入理解对于开发基于STM32系列微控制器的在线升级系统...
BootLoader是一种特殊的程序,它是微控制器(如STM32F407)在上电或复位时首先执行的代码,其主要任务是初始化硬件,包括CPU、内存、外设等,并加载操作系统或应用程序到内存中执行。STM32F407是一款基于ARM Cortex-...
STM32-HID-Bootloader 是一款用于STM32微控制器的Bootloader程序,它基于USB Human Interface Device(HID)类协议。该程序允许通过USB接口对STM32芯片进行固件更新,无需额外的通信协议或者专用的编程器。这种...
BootLoader是嵌入式系统中的一个重要组成部分,它在系统启动时负责加载操作系统或者应用程序到内存中执行。在针对LPC1768微控制器的系统中,BootLoader扮演着至关重要的角色。LPC1768是NXP公司生产的一款基于Cortex-...
《HC32F460 Bootloader:IAP Bootloader V1.0 深度解析》 在嵌入式系统开发中,Bootloader扮演着至关重要的角色,它是程序加载到微控制器的第一步,负责初始化硬件、设置内存映射以及加载应用程序到运行地址。本文...
BootLoader作为UDS服务中的关键部分,是汽车电子系统启动过程中的第一步,它负责加载和执行应用程序到微控制器中。"UDS_BootLoader-master.zip"这个压缩包包含了一个BootLoader的示例和相关的参考说明,旨在帮助初学...
U-Boot的代码结构类似于Linux内核,很多驱动程序直接来源于Linux内核,这使得开发者可以更容易地进行移植和维护工作。 #### U-Boot的目录结构 U-Boot的源代码组织结构清晰,主要目录包括但不限于: - **common**...
有朋友邮件问我如何用CANoe的CAPL读取S19...基于此,我愿和大家一起分享我以前写的代码,不是很完善,敬请大家见谅。有更优化的,请和我分享,谢谢! 我的邮箱:tianhua_ming@126.com 如果回复不是很及时,请谅解!
2. **第二阶段**:第二阶段Bootloader通常由更高级别的语言(如C)编写,提供了更多功能,如设备检测、网络或串行加载、文件系统的处理,以及最终加载Linux内核映像和设备树 blob(Device Tree Blob)。对于LPC22...
- **进入Bootloader模式**:根据设备的具体型号,可能需要通过特定的按键组合或硬件引脚设置将J-Link置于bootloader模式。 - **更新Bootloader**:使用J-Flash或J-Link Commander,选择`bootloader.bin`文件,然后...