引导扇区

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

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

引导扇区格式

AddressDescriptionSize in bytes
HexDec
0000Code440
1b8440Optional disk signature4
1bc4440x00002
1be446Four 16-byte entries for primary partitions64
1fe5100xaa552

代码示例

GNU asNASM
.code16
.section .data
msg:
	.ascii "Hello World!"
.section .text
.globl	_start
_start:
	mov	%cs, %ax
	mov	%ax, %ds
	mov	%ax, %es
	mov	$msg, %ax
	mov	%ax, %bp
	mov	$12, %cx
	mov	$0x1301, %ax
	mov	$0x000c, %bx
	movb	$0x00, %dl
	int	$0x10
idle:
	jmp	idle
	org	7c00h
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	mov	ax, msg
	mov	bp, ax
	mov	cx, 12
	mov	ax, 1301h
	mov	bx, 000ch
	mov	dl, 0
	int 10h
	jmp $
msg:			db "Hello World!"
times 	510-($-$) 	db 0
dw	0xaa55
as -o boot.o boot.s
ld --oformat binary -Ttext 7c00 \
 -Tdata 7c20 -o boot boot.o
dd bs=512 count=2880 if=boot of=floppy.img
echo -ne "\x55\xaa" | dd seek=510 bs=1 of=floppy.img
nasm boot.s -o boot
dd 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 color
IRGBIRGB

I代表Blink Enable(闪烁效果)


HexBinaryColor
00000Black 
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内核完全剖析》赵炯

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值