《自己动手写操作系统》1

对已早期的 linux内核,由于gcc不支持16位的汇编代码,故而 boot.s 是采用 intel的汇编形式如下:

!   boot.s
!
! It then loads the system at 0x10000, using BIOS interrupts. Thereafter
! it disables all interrupts, changes to protected mode, and calls the 
                                    
BOOTSEG = 0x07c0
SYSSEG  = 0x1000            ! system loaded at 0x10000 (65536).
SYSLEN  = 17                ! sectors occupied.
                                    
entry start
start:
    jmpi    go,#BOOTSEG
go: mov ax,cs
    mov ds,ax
    mov ss,ax
    mov sp,#0x400       ! arbitrary value >>512
                                    
! ok, we've written the message, now
load_system:
    mov dx,#0x0000
    mov cx,#0x0002
    mov ax,#SYSSEG
    mov es,ax
    xor bx,bx
    mov ax,#0x200+SYSLEN
    int     0x13
    jnc ok_load
die:    jmp die
                                    
! now we want to move to protected mode ...
ok_load:
    cli         ! no interrupts allowed !
    mov ax, #SYSSEG
    mov ds, ax
    xor ax, ax
    mov es, ax
    mov cx, #0x2000
    sub si,si
    sub di,di
    rep
    movw
    mov ax, #BOOTSEG
    mov ds, ax
    lidt    idt_48      ! load idt with 0,0
    lgdt    gdt_48      ! load gdt with whatever appropriate
                                    
! absolute address 0x00000, in 32-bit protected mode.
    mov ax,#0x0001  ! protected mode (PE) bit
    lmsw    ax      ! This is it!
    jmpi    0,8     ! jmp offset 0 of segment 8 (cs)
                                    
gdt:    .word   0,0,0,0     ! dummy
                                    
    .word   0x07FF      ! 8Mb - limit=2047 (2048*4096=8Mb)
    .word   0x0000      ! base address=0x00000
    .word   0x9A00      ! code read/exec
    .word   0x00C0      ! granularity=4096, 386
                                    
    .word   0x07FF      ! 8Mb - limit=2047 (2048*4096=8Mb)
    .word   0x0000      ! base address=0x00000
    .word   0x9200      ! data read/write
    .word   0x00C0      ! granularity=4096, 386
                                    
idt_48: .word   0       ! idt limit=0
    .word   0,0     ! idt base=0L
gdt_48: .word   0x7ff       ! gdt limit=2048, 256 GDT entries
    .word   0x7c00+gdt,0    ! gdt base = 07xxx
.org 510
    .word   0xAA55
现在gnu的 as 和汇编都已经支持16位的汇编 ,为了统一 方便以后学习,现在将其改为at&t的语法格式:

#boot.s rewrite with at&t assemble  (c) Aleishus 2013
#注意在16位汇编下 逻辑地址的段地址*16+逻辑地址的偏移量=物理地址,bois将程序加载到物理地址0x7c00  , 因此 逻辑段的地址就是BOOTSEG= 0x07c0
BOOTSEG = 0x07c0   
SYSSEG = 0x1000
SYSLEN  = 17
                
.code16
.global start
.text
start:
     ljmp $BOOTSEG,$go
go:
    movw %cs ,%ax
    movw %ax ,%ds
    movw %ax ,%ss
    movw $0x500 ,%sp
                
                
#ok loading system ...
                
load_system:
    xorw  %dx ,%dx
    movw $0x0002 ,%cx
    movw $SYSSEG ,%ax
    movw %ax ,%es
    xorw  %bx ,%bx
    movw $0x200+SYSLEN,%ax
    int  $0x13
    jnc  ok_load
die:jmp die
                
#ok we  move to protected mode
                
ok_load:
    cli
    movw $SYSSEG ,%ax
    movw %ax ,%ds
    xorw %ax ,%ax
    movw %ax ,%es
    movw $0x2000 ,%cx
    xorw %si ,%si
    xorw %di ,%di
    rep  movsw
    movw $BOOTSEG ,%ax
    movw %ax ,%ds
    lidt idt_48-BOOTSEG
    lgdt gdt_48-BOOTSEG
    movw $0x0001 ,%ax
    lmsw %ax 
    ljmp $8 ,$0
                
                
gdt:  .quad 0x0000000000000000 
      .quad 0x00c09a00000007ff
      .quad 0x00c09200000007ff
                
idt_48: .word 0
        .long 0
                
gdt_48: .word 0x03f
        .long 0x7c00+gdt
                
                
#org表示重 地510个字节开始 基地之 偏移地址0x1fe开始 填充引导标志共bois识别,刚好占一个扇区 512bit
.org 510  
    .word 0xaa55
下面是Makefile 文件

# Makefile for the simple example kernel.
     
     
#AS86   =as86 -0 -a
#LD86   =ld86 -0
AS  =as
LD  =ld
#LDFLAGS0 =-m elf_i386 -Ttext 0 -e startup_32 -s -x -M  
     
LDFLAGS0 =--oformat binary  -e startup_32 -Ttext 0 
LDFALGS1 =--oformat binary  -e start -Ttext 0 
     
     
all:    Image
     
#Image: boot system
#   dd bs=512 if=boot of=Image 
#   objcopy -O binary system head
#   cat head >> Image
     
Image: boot head
    dd bs=512 if=boot of=Image 
    cat head >> Image
     
disk: Image
    dd bs=8192 if=Image of=/dev/fd0
    sync;sync;sync
     
head.o: head.s
    $(AS)  -o head.o head.s
         
     
#system:    head.o 
#   $(LD) $(LDFLAGS0) head.o  -o system > System.map
     
head:   head.o 
    $(LD) $(LDFLAGS0) head.o  -o head
     
boot.o: boot.s
    $(AS) -o boot.o boot.s
boot:boot.o
    $(LD) $(LDFALGS1) -o boot boot.o
     
clean:
    rm -f Image  boot head *.o

你可能感兴趣的:(《自己动手写操作系统》1)