您的位置:首页 > 其它

读书笔记《30天自制操作系统》day03

2013-02-18 14:26 344 查看
http://blog.csdn.net/ltbylc/article/details/8309257

0. 自己试着在win7下用NASM和minGW改写汇编和C混合编程,结果受挫了。还是先使用作者提供的工具构建吧。

1. 通过前2天的工作已经能使用NASM制作一个映像了,并且编写的汇编代码可以成为引导扇区代码。

2. 引导扇区代码中可以调用BIOS中断,读取软盘上其它扇区到内存中,根据FAT12文件系统格式得知,保存到软盘内的第一个文件的文件名一定从19逻辑扇区开始,且该文件的内容从逻辑扇区33开始。

3. 引导扇区可以将第一个保存的文件(kernel.sys=自己改的名字,功能是跳入保护模式并调用C语言编写的函数代码)读入内存并使之执行,找这个文件用到了一个技巧,不然通过文件系统结构分析出文件位置,并加载码就太复杂了。

4. 引导扇区代码如下ipl10.asm

[plain]
view plaincopy

; haribote-ipl  
; TAB=4  
  
CYLS    EQU     10                
  
        ORG     0x7c00            
  
        JMP     entry  
        DB      0x90  
        DB      "HARIBOTE"        
        DW      512               
        DB      1                 
        DW      1                 
        DB      2                 
        DW      224               
        DW      2880              
        DB      0xf0              
        DW      9                 
        DW      18                
        DW      2                 
        DD      0                 
        DD      2880              
        DB      0,0,0x29          
        DD      0xffffffff        
        DB      "HARIBOTEOS "     
        DB      "FAT12   "        
        RESB    18                
  
  
  
entry:  
        MOV     AX,0              
        MOV     SS,AX  
        MOV     SP,0x7c00  
        MOV     DS,AX  
  
  
        MOV     AX,0x0820  
        MOV     ES,AX  
        MOV     CH,0              
        MOV     DH,0              
        MOV     CL,2              
readloop:  
        MOV     SI,0              
retry:  
        MOV     AH,0x02           
        MOV     AL,1              
        MOV     BX,0  
        MOV     DL,0x00           
        INT     0x13              
        JNC     next              
        ADD     SI,1              
        CMP     SI,5              
        JAE     error             
        MOV     AH,0x00  
        MOV     DL,0x00           
        INT     0x13              
        JMP     retry  
next:  
        MOV     AX,ES             
        ADD     AX,0x0020  
        MOV     ES,AX             
        ADD     CL,1              
        CMP     CL,18             
        JBE     readloop          
        MOV     CL,1  
        ADD     DH,1  
        CMP     DH,2  
        JB      readloop          
        MOV     DH,0  
        ADD     CH,1  
        CMP     CH,CYLS  
        JB      readloop          
  
  
        MOV     [0x0ff0],CH       
        JMP     0xc200  
  
error:  
        MOV     SI,msg  
putloop:  
        MOV     AL,[SI]  
        ADD     SI,1              
        CMP     AL,0  
        JE      fin  
        MOV     AH,0x0e           
        MOV     BX,15             
        INT     0x10              
        JMP     putloop  
fin:  
        HLT                       
        JMP     fin               
msg:  
        DB      0x0a, 0x0a        
        DB      "load error"  
        DB      0x0a              
        DB      0  
  
        ;RESB   0x7dfe-$          
        times 510-($-$$) db 0  
  
        DB      0x55, 0xaa  

 

5. 跳入保护模式代码如下asmhead.nas

(1)准备GDT

(2)用LGDT加载gdtr

(3)打开A20

(4)设置CR0的PE位

(5)跳转进入保护模式

[plain]
view plaincopy

; haribote-os boot asm  
; TAB=4  
  
BOTPAK  EQU     0x00280000        
DSKCAC  EQU     0x00100000        
DSKCAC0 EQU     0x00008000        
  
  
CYLS    EQU     0x0ff0            
LEDS    EQU     0x0ff1  
VMODE   EQU     0x0ff2            
SCRNX   EQU     0x0ff4            
SCRNY   EQU     0x0ff6            
VRAM    EQU     0x0ff8            
  
        ORG     0xc200   ;让引导扇区加载后从这里开始运行         
  
  
  
        MOV     AL,0x13     ;保存信息     
        MOV     AH,0x00  
        INT     0x10  
        MOV     BYTE [VMODE],8    
        MOV     WORD [SCRNX],320  
        MOV     WORD [SCRNY],200  
        MOV     DWORD [VRAM],0x000a0000  
  
  
        MOV     AH,0x02  
        INT     0x16            ; keyboard BIOS  
        MOV     [LEDS],AL  
  
  
        MOV     AL,0xff  
            OUT     0x21,AL  
        NOP                       
        OUT     0xa1,AL  
  
        CLI                       
  
  
  
        CALL    waitkbdout  
        MOV     AL,0xd1  
        OUT     0x64,AL  
        CALL    waitkbdout  
        MOV     AL,0xdf         ; enable A20  
        OUT     0x60,AL  
        CALL    waitkbdout  
  
  
[INSTRSET "i486p"]                
  
        LGDT    [GDTR0]           
        MOV     EAX,CR0  
        AND     EAX,0x7fffffff    
        OR      EAX,0x00000001    
        MOV     CR0,EAX  
        JMP     pipelineflush  
pipelineflush:  
        MOV     AX,1*8            
        MOV     DS,AX  
        MOV     ES,AX  
        MOV     FS,AX  
        MOV     GS,AX  
        MOV     SS,AX  
  
  
  
        MOV     ESI,bootpack      
        MOV     EDI,BOTPAK        
        MOV     ECX,512*1024/4  
        CALL    memcpy  
  
  
  
        MOV     ESI,0x7c00        
        MOV     EDI,DSKCAC        
        MOV     ECX,512/4  
        CALL    memcpy  
  
  
        MOV     ESI,DSKCAC0+512   
        MOV     EDI,DSKCAC+512    
        MOV     ECX,0  
        MOV     CL,BYTE [CYLS]  
        IMUL    ECX,512*18*2/4    
        SUB     ECX,512/4         
        CALL    memcpy  
  
  
        MOV     EBX,BOTPAK  
        MOV     ECX,[EBX+16]  
        ADD     ECX,3             
        SHR     ECX,2             
        JZ      skip              
        MOV     ESI,[EBX+20]      
        ADD     ESI,EBX  
        MOV     EDI,[EBX+12]      
        CALL    memcpy  
skip:  
        MOV     ESP,[EBX+12]      
        JMP     DWORD 2*8:0x0000001b  
  
waitkbdout:  
        IN       AL,0x64  
        AND      AL,0x02  
        JNZ     waitkbdout        
        RET  
  
memcpy:  
        MOV     EAX,[ESI]  
        ADD     ESI,4  
        MOV     [EDI],EAX  
        ADD     EDI,4  
        SUB     ECX,1  
        JNZ     memcpy            
        RET  
  
  
        ALIGNB  16  
GDT0:  
        RESB    8                 
        DW      0xffff,0x0000,0x9200,0x00cf   
        DW      0xffff,0x0000,0x9a28,0x0047   
  
        DW      0  
GDTR0:  
        DW      8*3-1  
        DD      GDT0  
  
        ALIGNB  16  
bootpack:  

6. C语言代码如下bootpack.c

[cpp]
view plaincopy

void io_hlt(void);  
void write_mem8(int addr,int data);  
void HariMain(void)  
{  
    int i;  
    for(i=0xa0000;i<=0xaffff;i++)  
    {  
        write_mem8(i,15);  
    }  
    for(;;)  
    {  
        io_hlt();  
    }  
  
}  

7. C语言中调用的io_hlt和write_mem8函数放到了如下代码中func.asm

[plain]
view plaincopy

[FORMAT "WCOFF"]                  
[INSTRSET "i486p"]            
[BITS 32]                         
[FILE "naskfunc.nas"]             
global _io_hlt,_write_mem8  
[section .text]  
;void io_hlt(void);  
_io_hlt:  
    HLT  
    RET  
      
;void write_mem8(int addr,int data);  
_write_mem8:  
    MOV ECX,[ESP+4]  
    MOV AL,[ESP+8]  
    MOV [ECX],AL  
    RET  

8. 在toolset文件夹内建立一个新文件夹,将上面所有的文件放在里边,编译链接接上面的文件,写个bat文件如下

[plain]
view plaincopy

nasm -o ipl10.bin ipl10.asm  
nasm -o img.img img.asm  
..\z_tools\nask.exe asmhead.nas asmhead.bin  
..\z_tools\cc1.exe -I..\z_tools\haribote\ -Os -Wall -quiet -o bootpack.gas bootpack.c  
..\z_tools\gas2nask.exe -a bootpack.gas bootpack.nas  
..\z_tools\nask.exe bootpack.nas bootpack.obj  
..\z_tools\nask.exe func.asm func.obj  
..\z_tools\obj2bim.exe @..\z_tools\haribote\haribote.rul out:bootpack.bim stack:3136k map:bootpack.map bootpack.obj func.obj  
..\z_tools\bim2hrb.exe bootpack.bim bootpack.hrb 0  
copy /B asmhead.bin+bootpack.hrb kernel.sys  

9.这样除了中间文件外,生成img.img文件和kernel.sys文件。使用winImage打开img.img文件将kernel.sys文件加入到该img文件中。

10. 启动Bochs,呵呵看见屏幕白了,这可是从C代码里控制的啊!

11. asmhead中跳入保护模式的代码慢慢在深入掌握,不然会掉入细节里不能自拔了。

12. asmhead和C代码是通过copy /B进行链接的其中asmhead代码最后留了个标号bootpack,在这个标号后面C的目标代码被砍去文件头直接将代码链接到了这里,所以能实现从汇编跳转到C语言的目的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: