- ;;;;;;;实现进入进入保护模式,简单实现gdt,还没实现idt,用fat格式,这样利于内核文件的扩展。编写好内核之后,
- ;;;;;;;;可以直接放到软盘的根目录下。不需要在用镜像文件写入磁盘。
- ;;;;;;;;内存分配,堆栈在8FFFF,内核在500H,目录文件名被读取到7E00,等待扩展保护模式中断,完善磁盘读文件过程
- [bits16]
- [org0x7c00];告诉编译器程序加载到7c00处
- CATALOGequ0x7E00;catalogloadedat0x7e00
- KERNELequ0x500;kernel.binloadedat0x500.
- jmpStart
- ;引导区文件系统数据
- ;----------------------------------------------------------------------------
-
brOEMDB"T'sOS";0003h-引导程序的名字
- brBPSDW0x200;000Bh-每扇区的字节数512
- brSPCDB0x01;000Dh-每簇扇区数
- brResCountDW0x0001;000Eh-保留扇区数
- brFATsDB0x02;0010h-FAT备份数
- brRootEntriesDW0x00e0;0011h-根目录文件数
- brSectorCount
- DW2880;0013h-磁盘容量扇区数<32MB
- brMediaDB240;0015h-媒体描述符
- brSPFDW9;0016h-每FAT扇区数
- brSPHDW18;0018h-每磁道扇区数
- brHPCDW2;001Ah-盘面数
- brHiddenDD0;001Ch-隐藏扇区数
- brSectorsDD0;0020h-如果大于32m的扇区总数
- DB0;0024h-物理驱动器号
- DB0;0025h-系统保留
- DB29H;0026h-扩展扇区标记(包含29h)
- brSerialNumDD00000006H;0027h-卷ID
-
brLabelDB'NONAME';002Bh-卷标
-
brFSIDDB'FAT12';0036h-系统保留
- ;------------------------------------------------------------------------
- Start:
- movax,cs
- movds,ax
- moves,ax
- movax,0x8000;栈放在0x1F00段里,这里栈有问题(栈放在0x1F00段里,会覆盖掉中断程序。)!!!!!!!!!!!!!!!
- movss,ax
- movsp,0xffff;堆栈入口8FFFF
- callDispStr;调用显示字符串例程
- callLoadFile;把目录区读入到200的地方,bios
- callFindFile;在7E00的地方找kernel.bin,读出来放到500的地方,并显示读取成功
- callClrscr;先清屏
- ;=============================================
- ;SwitchPro建立GDT,进入保护模式
- ;=============================================
- SwitchPro;
- ;打开A20
-
inal,92h
- oral,00000010b
-
out92h,al
- ;end打开A20
- ;设置GDT
- cli
- ;movax,KERNEL;lgdt指令加载gdtr是以ds为数据段加载
- ;movds,ax
- ;leasi,[dwordgdtr]
- lgdt[gdtr]
- ;leasi,[dwordidtr]
- ;lidt[dwordgdtr]
- moveax,cr0
- oreax,1
- movcr0,eax
- jmpdwordselcode:0;进入保护模式,并且跳到下面的段中
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;jmpKERNEL保护模式下,跳到kenel.bin开始执行内核.等待内核编码完成在实现
- [bits32]
- CODE32:
- sti
- moveax,codesel_gdt
- movebx,datasel_gdt
- movax,ProMessage
- movbp,ax
- movcx,ProMsglength
- ;callPrintMsg;保护模式中断有问题,需要修改这里,最好能利用实模式下的bios中断程序。
- ;===================
- movax,videosel;初始化gs,使其指向显示内存
- movgs,ax
- movword[gs:0],0x741;在保护模式下显示一个白色的字符A
- ;===================
- jmp$;到此停止!!!!!!!!!!!!!!!!!!!!!!!
- [bits16]
- ;===================================================================
- ;初始化gdtr和gdt
- ;===================================================================
- gdtr:
- dwgdt_end-gdt-1;gdt的长度--16位(800H)GDT界限gdtlimit=2048,256GDTentries
- ;这里应该是伪长度7,15,23,31,因为从0开始计算的
- ddgdt;gdt的物理地址--32位GDT基地址
- ;0x00007c930017!!!!!!!!
- gdt:
- gdt0:
- dw0,0,0,0;一定要为0
- codesel_gdt:
- dw0xffff;界限Limit值=0x100000*0x1000=4GB
- dwCODE32;0x0000;基地址=CODE32.!!!!!!!是不是最好设置从0开始?
- db0x00
- db0x9A;表示存在可执行可读代码段
- db0xCF;粒度以及32位代码1100=0XC
- db0x00
- datasel_gdt:
- dw0xffff;界限4GB
- dw0x0000;基地址
- db0x00
- db0x92;表示存在可读写数据段
- db0xCF;粒度以及数据锻大小4G,1100=0XC
- db0x00
- ;========================
- videoselequ$-gdt
- dw3999
- dw0x8000;基址是0xb8000
- db0x0b
- db0x92
- db0x00
- db0x00
- ;========================
- gdt_end:
- selcodeequcodesel_gdt-gdt;索引值1,2,3....
- seldataequdatasel_gdt-gdt
- ;=============================================
- ;DispStr显示boot已经启动!
- ;=============================================
- DispStr:
- movax,BootMessage
- movbp,ax;es:bp=串地址
- movcx,Msglength;cx=串长度
- callPrintMsg
- ret
- ;=============================================
- ;LoadFile把目录从软盘中读出来!
- ;=============================================
- LoadFile:
- movax,19;开始的扇区
- movbx,CATALOG;目录放在7E00H的地方!!!!!!!!!!!!!!!!!!!!!!!!!!!
- movcx,14;目录扇区个数
- loopreadsec:
- pushax
- pushbx
- pushcx
- callLBACHS;调用转换
- movdl,0;因为是a:所以为0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- movah,0x02;BIOS读取扇区命令
- moval,0x01;一个扇区
-
int0x13;调用中断
- nop
- popcx
- popbx
- popax
- addbx,200
- incax
- looploopreadsec
- ret
- ;=============================================
- ;转换逻辑块访问为读取磁盘所使用的磁道,盘面,扇区
- ;相对扇区=(逻辑扇区/每磁道扇区数)+1
- ;相对盘面=(逻辑扇区/每磁道扇区数)MOD盘面数
- ;相对磁道=逻辑扇区/(每磁道扇区数*盘面数)
- ;=============================================
- LBACHS:
- xordx,dx;dx=0
- movcx,18
- divcx;div:ax/18->商:ax余数:dx
- incdl;sec;
- movcl,dl;sector
- xordx,dx;dx=0
- pushbx
- movbx,2
- divbx;ax/2->商:ax余数:dx
- popbx
- movch,al;track
- movdh,dl;head
- ret
- ;=============================================
- ;FindFile查找文件名,并且装到0x500,显示LoadKernel.binSuccess!
- ;=============================================
- FindFile:
- cld;地址自动增加
- movcx,224;根目录共有224个文件
- movdi,CATALOG;目录放在7E00H的地方!!!!!!!!!!!!!!!!!!!!!
- .l_findfile:
- pushcx
- leasi,[Kernel];?
- pushdi
- movcx,11;8+3=0xb文件名和后缀长度
- repecmpsb
- popdi
- jefindfile_ok
- adddi,32;开始找下1个文件
- popcx
- loop.l_findfile
- movax,LoadKerFail;失败
- movbp,ax;es:bp=串地址
- movcx,LoadKerFaillength;cx=串长度
- callPrintMsg
- ret
- findfile_ok:
- popcx
- adddi,26;取文件占用的第一个簇号,即起始簇
- movax,[di]
- addax,31;簇转成扇区
- movbx,KERNEL;文件放在0x500!!!!!!!!!!!!!!!!!!!!!!!!!!!
- callLBACHS;调用转换
- movdl,0;因为是a:所以为0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- movah,0x02;BIOS读取扇区命令
- moval,0x03;一个扇区,这里不应该只读一个扇区,应该根据文件大小来决定,等待修改!!!!!
-
int0x13;调用中断,内核放在0x1e00!;在磁盘的位置?
- movax,LoadKerSuess;成功
- movbp,ax;es:bp=串地址
- movcx,LoadKerlength;cx=串长度
- callPrintMsg
- ret
- ;=============================================
- ;清屏
- ;=============================================
- Clrscr:
- movax,0x0600;使用中断10h的功能6,实现卷屏,如果al=0则清屏
- movcx,0x0000;清屏
- movdx,0x174f;卷屏至23,79
- movbh,0;使用颜色0来填充
-
int0x10;调用10h中断
- ret
- ;=============================================
- ;显示信息
- ;=============================================
- PrintMsg:
- movax,01301h;ah=13,al=01h
- movbx,000ch;页号为0(bh=0)黑底红字(bl=0Ch,高亮)
- movdl,0
- movdh,BYTE[NoLine]
-
int10h;10h号中断
- adddh,1
- movBYTE[NoLine],dh
- ret
-
BootMessage:db"WelcometoT'sOS!",0x0D,0x0A
- Msglengthequ$-BootMessage
- DB0x00
-
Kernel:db'KERNELBIN';8+3=11位;将来这里改成内核的文件名!!!!!!!!!!!!!
-
LoadKerSuess:db'LoadKernel.binSuccess!',0x0D,0x0A
- LoadKerlengthequ$-LoadKerSuess
- DB0x00
-
LoadKerFail:db'LoadKernel.binFail!',0x0D,0x0A
- LoadKerFaillengthequ$-LoadKerFail
- DB0x00
-
ProMessage:db"I'mintheProMode!",0x0D,0x0A
- ProMsglengthequ$-ProMessage
- DB0x00
- NoLineDB0x00
- times510-($-$$)db0;填充剩下的空间,使生成的二进制代码恰好为512字节
- dw0xaa55;结束标志
- ;把这段代码用NASM编译一下:
- ;nasmboot.asm–oboot.bin
- ;应该把内核在pro模式下加载就对了!
版权声明:本文为博主原创文章,未经博主允许不得转载。
分享到:
相关推荐
我们整个ARM课程就分为三部分,这是第一部分,实现一个自己的最小bootloader 1.Read Me 一、实现功能 1.硬件初始化 2.延时判断加载操作系统还是进入Bootloader Shell 3.加载操作系统 4.Bootloadershell 二、...
en.stsw-str7026.zip bootloader (IAP)源代码 通过串口下载数据 开机通过检测io口电平判断是否有升级请求 flash driver 内嵌 在boot 中,没有copy到ram中执行 简单的bootloader,适合初学者,练习程序的跳转之类的
平台:STM32103 Bootloader用于应用程序.BIN文件的升级,支持XMODEM XMODEM_1K协议.易上手,可缩短开发周期.
BootLoader启动代码分析
Bootloader源代码
c51实现bootloader的源代码,keil c51下实现的
了解Bootloader过程,嵌入式开发不可缺少的重要部分
原资源:有朋友邮件问我如何用CANoe的CAPL读取S19文件并解析,以实现bootloader刷写。基于此,我愿和大家一起分享我以前写的代码,不是很完善,敬请大家见谅。有更优化的,请和我分享,谢谢! PS:和这个资源一样,...
本文详细讲解了bootloader启动过程,对深入理解bootloader和对自己写bootloader有很大帮助。
有朋友邮件问我如何用CANoe的CAPL读取S19文件并解析,以实现bootloader刷写。基于此,我愿和大家一起分享我以前写的代码,不是很完善,敬请大家见谅。有更优化的,请和我分享,谢谢! 我的邮箱:tianhua_ming@126....
vivi 源代码,一种基于s3c2410的Linux操作系统的bootloader源代码。
bootloader 实现的流程, cpu及外设的初始化,代码的搬移,内核的引导的实现
本文主要介绍一种多核DSP Bootloader代码的加载方法,感性趣的朋友可以参考下。
里程碑android Bootloader源代码bin二进制格式
Bootloader简介 几种发布的Bootloader Bootloader工作模式 Bootloader启动过程 vivi Bootloader源代码分析 vivi Bootloader接口命令 vivi 源代码修改移植
ARM Bootloader 的实现
本文档以MSP430F247为例详细的阐述了bootloader的原理及实现方法。理论上讲任何一个以 FLASH ROM为程序载体,本身提供在线擦写FLASH ROM功能而又不需要外加编程电压的MCU,都可以自行嵌入bootloader。