设为首页 加入收藏

TOP

Linux-0.11抠代码-bootsect(一)
2014-11-24 02:50:49 来源: 作者: 【 】 浏览:1
Tags:Linux-0.11 代码 -bootsect

//bootfun.s
.global asm_message
.global asm_memmove
.global asm_readsector
.global asm_checkLBA
.code16


//extern void asm_memmove(void* src,void* des,int icount);
asm_memmove:
#源地址 ds:si 目的地址 es:di
pushw %bp
movw %sp,%bp
#movw 6(%bp),%ax 第1个参数
#movw 10(%bp),%bx 第2个参数
#movw 14(%bp),%cx 第3个参数
1:
movl 6(%bp),%eax
movw %ax,%si
movw $0,%ax
movb $4,%cl
shr %cl,%eax
movw %ax,%ds
2:
movl 10(%bp),%eax
movw %ax,%di
movw $0,%ax
movb $4,%cl
shr %cl,%eax
movw %ax,%es
movl 14(%bp),%ecx
rep movsb

movw %bp,%sp
popw %bp
ret

asm_checkLBA:
movb $0x41,%ah
movw $0x55aa,%bx
int $0x13
lahf
and $0x01,%ah
xor $0x01,%ah
ret

asm_message:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
movw %ax,%si
1:
lodsb
cmpb $0,%al
je 1f
movw $1,%bx
movb $0xe,%ah
int $0x10
jmp 1b
1:
movl %ebp,%esp
popl %ebp
ret


#extern void asm_readsector(void* des,int driver ,int head,int track,int sector,int iCount);
;// 以下10行的用途是利用BIOS中断INT 13h将setup模块从磁盘第2个扇区
;// 开始读到90200h开始处,共读4个扇区。如果读出错,则复位驱动器,并
;// 重试,没有退路。
;// INT 13h 的使用方法如下:
;// ah = 02h - 读磁盘扇区到内存;al = 需要读出的扇区数量;
;// ch = 磁道(柱面)号的低8位; cl = 开始扇区(0-5位),磁道号高2位(6-7);
;// dh = 磁头号; dl = 驱动器号(如果是硬盘则要置为7);
;// es:bx ->指向数据缓冲区; 如果出错则CF标志置位。
asm_readsector:
pushw %bp
movw %sp,%bp
1:
movl 6(%bp),%eax
movw %ax,%bx
movb $4,%cl
movw $0, %ax
shr %cl,%eax
movw %ax,%es

movb 14(%bp),%dh ;// drive 0, head 0
movb 10(%bp),%dl

movb 18(%bp),%ch ;// sector 2, track 0
movb 22(%bp),%cl

movb $0x02,%ah
movb 26(%bp),%al

int $0x13
jnc 1f
movw $0,%dx
movw $0,%ax
int $0x13
jmp 1b
1:
movw %bp,%sp
popw %bp
ret



//main.c
__asm__(".code16gcc\n");
//0x7c00
extern void asm_checkLBA();
extern int asm_message (char * str);//申明汇编函数
extern void asm_memmove(void* src,void* des,int icount);
extern void asm_readsector(void* des,int driver ,int head,int track,int sector,int iCount);
extern unsigned short asm_readDisksectors(int driver);



void entry(void)
{
__asm__("movw $0x9000,%bx");
__asm__("movw %bx,%ss");
__asm__("movw $0xFF00,%bx");
__asm__("movw %bx,%sp");
asm_checkLBA();
asm_message("Loading YoungOS......................");
asm_readsector((void*)0x80200,0x80,0,0,2,4);


__asm__("movw $0x8000,%bx");
__asm__("movw %bx,%ds");
__asm__("jmp $0x8000,$0x200");
}


虚拟机:bochs vmware


调试部分 gdb+vmware,bochs,其中gdb+vmware可以直接进行源码级调试,具体方法可以另外咨询我


先介绍几个命令


gcc -c -g -nostdinc -fno-leading-underscore -fno-builtin -fno-stack-protector


-g 保留调试信息,供gdb调试使用


-c 编译目标文件
-fno-builtin 不用自带的c/c++库函数
-fno-stack-protector 禁用堆栈保护


-fno-leading-underscore 函数导出不加下划线 ,当你申明一个test函数,导出会成_test


简化代码,把用汇编实现的都写成功能代码函数,然后供.c文件调用,知识点就是c语言和汇编互相调用


gcc -c -g -nostdinc -fno-leading-underscore -fno-builtin -fno-stack-protector main.c bootfun.s


ld --entry=entry -Ttext=0x7c00 -o ./out/boot.elf main.o bootfun.o -M >system.map //生成elf文件,此时elf带gdb调试信息 注意不要加-s,-s会删除调试信息


objcopy -I elf32-i386 -O binary ./out/boot.elf ./out/boot.bin //将elf转化成无格式的bin文件


windows 下 Bintool.exe boot.bin xxxx.img 0x000 (xxxx.img 为虚拟机的硬盘文件)// 注意 不要忘记 偏移510 511 写成55AA,我是用ultraedit写的,不然无法引导


源代码调试方法,gdb boot.elf 进入gdb命令符,然后target remote localhost:8832 这里要成功,自己网上搜一下 这么用gdb+vmware调试内核


代码部分


主要是


asm_message("Loading YoungOS......................");
asm_readsector((void*)0x80200,0x80,0,0,2,4);


__asm__("movw $0x8000,%bx");
__asm__("movw %bx,%ds");
__asm__("jmp $0x8000,$0x200");


这几句,其他应该没用,当初测

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇使用 C++ 的 StringBuilder 提升 .. 下一篇C# C++ 传递函数指针

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: