引导扇区

来源:互联网 发布:一键转手绘软件 编辑:程序博客网 时间:2024/05/01 15:17

CPU上电后会自动跳转到地址 0xFFFF0(BIOS ROM)处执行,BIOS完成一系列自检后将软盘(假设从软驱引导)第一个扇区(Cylinder/Head/Sector=0/0/1)复制到内存地址0x7C00处,并跳转到该地址执行引导代码;

第一扇区最后两个字节必须是"0x55,0xAA"才能被当作引导扇区加载。

引导扇区格式

AddressDescriptionSize in bytesHexDec0000Code4401b8440Optional disk signature41bc4440x000021be446Four 16-byte entries for primary partitions641fe5100xaa552

代码示例

GNU asNASM
.code16.section .datamsg:.ascii "Hello World!".section .text.globl_start_start:mov%cs, %axmov%ax, %dsmov%ax, %esmov$msg, %axmov%ax, %bpmov$12, %cxmov$0x1301, %axmov$0x000c, %bxmovb$0x00, %dlint$0x10idle:jmpidle
org7c00hmovax, csmovds, axmoves, axmovax, msgmovbp, axmovcx, 12movax, 1301hmovbx, 000chmovdl, 0int 10hjmp $msg:db "Hello World!"times 510-($-$) db 0dw0xaa55
as -o boot.o boot.sld --oformat binary -Ttext 7c00 \ -Tdata 7c20 -o boot boot.odd bs=512 count=2880 if=boot of=floppy.imgecho -ne "\x55\xaa" | dd seek=510 bs=1 of=floppy.img
nasm boot.s -o bootdd bs=512 count=2880 if=boot of=floppy.img     


GNU as(gas)

汇编大致有AT&T和Inter两种语法,只是采用不同的书写格式而已;汇编器GNU as采用AT&T语法; NASM采用Inter语法;

--oformat binary: 用来去除ELF头,将boot.o链接成纯二进制代码;

-Ttext和-Tdata用于修改代码段和数据段的起始地址,因为CS和DS初始为0,所以重定位只是改变代码中的相对地址而已(可使用objdump -d -mi8086 boot.o观察链接前的"b8 00 00"三个字节,链接重定位后使用hexdump -C boot查看则变成了"b8 20 7c")

gas默认会将数据段会定位到0x1010以后,这样会超出引导扇区512字节的限制;观察发现0x20后面就没有代码了,可以将数据段定位至此,压缩空间;


默认链接:

00000000  8c c8 8e d8 8e c0 b8 1c  8c 89 c5 b9 0c 00 b8 01  |................|00000010  13 bb 0c 00 b2 00 cd 10  eb fe 00 00 00 00 00 00  |................|00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|*00001010  00 00 00 00 00 00 00 00  00 00 00 00 48 65 6c 6c  |............Hell|00001020  6f 20 57 6f 72 6c 64 21                           |o World!|

数据段重定位:

00000000  8c c8 8e d8 8e c0 b8 20  7c 89 c5 b9 0c 00 b8 01  |....... |.......|00000010  13 bb 0c 00 b2 00 cd 10  eb fe 00 00 00 00 00 00  |................|00000020  48 65 6c 6c 6f 20 57 6f  72 6c 64 21              |Hello World!|

软驱映像(Image)

在linux下可使用dd命令生成Floppy Image,大小为1.44M(1M=1000KB,1KB=1024B),即2880个扇区(1扇区=512B);

因为gas没法像NASM那样方便的在代码中填充若干0后再填充引导魔数(magic number),因此只好手动使用dd寻址后修改;

生成image文件后,将其插入虚拟机的虚拟软驱引导即可验证。(Linux环境常用虚拟机有VirturalBox、VMWare、Boches、Virt-Manager等)


BIOS中断

本样例代码使用BIOS中断0x10显示字符串:

AH=0x13 #写字符串

AL=1 #写模式

BH=0 #页号

BL=0x0C #字符颜色属性

CX=12 #字符数

DH,DL=0,0  #起始行,列

ES:BP=0:$msg #写入地址


BIOS Color Attribute


Attribute(HL)Background ColorCharacter colorIRGBIRGB

I代表Blink Enable(闪烁效果)


HexBinaryColor00000Black 10001Blue 20010Green 30011Cyan 40100Red 50101Magenta 60110Brown 70111Light Gray 81000Dark Gray 91001Light Blue A1010Light Green B1011Light Cyan C1100Light Red D1101Light Magenta E1110Yellow F1111White 

参考:

http://en.wikipedia.org/wiki/BIOS_interrupt_call

http://susam.in/articles/boot-sector-code/

http://gas.linuxsir.org/docs/as.html/index.html

http://www.ibm.com/developerworks/linux/library/l-gas-nasm/index.html

http://objectmix.com/asm-x86-asm-370/69342-tralnslate-sintax-nasm-gas.html

http://linuxgazette.net/issue77/krishnakumar.html

http://www.pcguide.com/ref/hdd/file/structMBR-c.html

《自己动手写操作系统》于渊

《Linux内核完全剖析》赵炯

原创粉丝点击