|
|
|
发新文章 |
|
|
Skelix的实验平台是linux,我这里没有,索性在windows建立一个模拟的,用mysys和mingw也可以用,但代码问题多多。 这里修改的代码时Skelix教程的第二篇里面的源码,一一记录下来先: 1. 修改makefile,如下:
AS=as -Iinclude
LD=ld

KERNEL_OBJS= load.o

.s.o:
 $ {AS} -a $< -o $*.o >$*.map

all: final.img

 final.img: bootsect kernel $ {KERNEL_OBJS}
objcopy -S -O binary bootsect.o bootsect
 objcopy -S -O binary $ {KERNEL_OBJS} kernel
@wc -c kernel
cat bootsect kernel > final.img
@wc -c final.img

bootsect: bootsect.o
 $ {LD} -N -e start -Ttext 0x7c00 -o bootsect $<

 kernel: $ {KERNEL_OBJS}
 $ {LD} -N -e pm_mode -Ttext 0x0000 -o $@ $ {KERNEL_OBJS}

clean:
rm -f *.img kernel bootsect *.o *.map


修改理由:ld在windows无法之间生产二进制文件,需要使用objcopy来产生二进制文件 2. 修改load.s代码如下:
# Skelix by Xiaoming Mo (xiaoming.mo@skelix.org)
# Licence: GPLv2
.text
.globl pm_mode
.include "kernel.inc"
.org 0
pm_mode:
movl $DATA_SEL,%eax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
movl $STACK_BOT,%esp

cld
movl $0x10200,%esi
movl $0x200, %edi
movl $(KERNEL_SECT-1)<<7,%ecx
rep
movsl

movb $0x06, %al #橙色输出
movl $msg, %esi
movl $0xb8000,%edi
1:
cmpb $0, (%esi)
je 1f
movsb
stosb
jmp 1b
1: jmp 1b
msg:
.string "Hello World!\x0"


修改理由:偶喜欢橙子,把白字干脆改成橙色的,纯属个人爱好 3.修改bootsect.s代码如下(修改理由:不知是不是ld在windows下的bug,链结的代码的起始地址0x7c00没有效果,偶只好在程序里面在设定一下ds段寄存器):
# Skelix by Xiaoming Mo (xiaoming.mo@skelix.org)
# Licence: GPLv2
.text
.globl start
.include "kernel.inc"
.code16
start:
jmp code
gdt:
.quad 0x0000000000000000 # null descriptor
.quad 0x00cf9a000000ffff # cs
.quad 0x00cf92000000ffff # ds
.quad 0x0000000000000000 # reserved for further use
.quad 0x0000000000000000 # reserved for further use
gdt_48:
.word .-gdt-1 # Special pointer which includes the limit: The max bytes
# taken up by the GDT, minus 1. Again, this NEEDS to be packed

.long GDT_ADDR
code:
xorw %ax, %ax
movw %ax, %ds # ds = 0x0000
movw %ax, %ss # stack segment = 0x0000
movw $0x1000,%sp # arbitrary value
# used before pmode

## read rest of kernel to 0x10000
movw $0x1000,%ax
movw %ax, %es
xorw %bx, %bx # es:bs destination address
movw $KERNEL_SECT,%cx
movw $1, %si # 0 is boot sector,跳过引导扇区
rd_kern:
call read_sect
addw $512, %bx
incw %si
loop rd_kern
#add by Liu Qi for debug
pushw %ax
movb $0x32, %al
movb $0x0e, %ah
int $0x10
popw %ax
#end of add by Liu Qi

cli
## move first 512 bytes of kernel to 0x0000
## it will move rest of kernel to 0x0200,
## that is, next to this sector
##注意:实模式下的中断向量表会被覆盖
cld
movw $0x1000,%ax
movw %ax, %ds
movw $0x0000,%ax
movw %ax, %es
xorw %si, %si
xorw %di, %di
movw $512>>2,%cx
rep
movsl
#add by Liu Qi
movw $0x7c0, %ax
movw %ax, %ds
#end of add by Liu QI
## move gdt
movw $GDT_ADDR>>4,%ax
movw %ax, %es
movw $gdt, %si
xorw %di, %di
movw $GDT_SIZE>>2,%cx
rep
movsl


enable_a20:
## The Undocumented PC
inb $0x64, %al
testb $0x2, %al
jnz enable_a20
movb $0xdf, %al
outb %al, $0x64

#add by Liu Qi
movw $0x7c0, %ax
movw %ax, %ds
#end of add by Liu QI
lgdt gdt_48 #注意:这里应该使用的ds访问gdt_48
## enter pmode
movl %cr0, %eax
orl $0x1,%eax
movl %eax, %cr0

ljmp $CODE_SEL, $0x0

## in: ax: LBA address, starts from 0
## es:bx address for reading sector
read_sect:
pushw %ax
pushw %cx
pushw %dx
pushw %bx

movw %si, %ax
xorw %dx, %dx
movw $18, %bx # 18 sectors per track
# for floppy disk
divw %bx
incw %dx
movb %dl, %cl # cl=sector number
xorw %dx, %dx
movw $2, %bx # 2 headers per track
# for floppy disk
divw %bx

movb %dl, %dh # head
xorb %dl, %dl # driver
movb %al, %ch # cylinder
popw %bx # save to es:bx
rp_read:
movb $0x1, %al # read 1 sector
movb $0x2, %ah
int $0x13
jc rp_read
popw %dx
popw %cx
popw %ax
ret
.org 0x1fe, 0x90
.word 0xaa55


|