• 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
    ");
    //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");
    }
    


    linux.0.11 抠代码心得,实现多任务输出,这篇只是刚刚开始,只是说了引导部分~~~~~~~~还有后续心得~~~~~
    代码阅读工具:scitools understand(用了这个感觉 source insight 是浮云,个人感觉,别喷)
    代码编译工:起初是vmware+ubuntu,后来才知道可以直接用cygwin
    自己用VS2010写的二进制写磁盘工具,bintool.exe 源文件,目标文件,目标文件偏移    (原来 linux dd命令就可以实现了,windows 有merge ,dd for windows)

    虚拟机: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");

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

    从磁盘2号扇区连续读4个扇区内容到0x80200处,跳转到0x80200



    走过,路过,有手的捧个手场,不是撸,只要给个评论,给个赐教!!!!!!!!!!

  • 相关阅读:
    php-浅谈php底层机制
    Apache-三种工作模式(prefork/ worker/Event)
    java入门了解01
    webserivce通过httppost方式调用
    sqlserver 打开 database diagrams 报错:error code 0x54b
    redhat7,redhat6 替换yum
    虚拟机网络配置的一点总结
    搭建sqlserver AlwaysOn
    NSSM-将服务变为window service
    JavaMelody-监控jvm性能
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3317891.html
Copyright © 2020-2023  润新知