zoukankan      html  css  js  c++  java
  • xv6/bootasm.S + xv6/bootmain.c

    xv6/bootasm.S

     1 #include "asm.h"
     2 #include "memlayout.h"
     3 #include "mmu.h"
     4 
     5 # Start the first CPU: switch to 32-bit protected mode, jump into C.
     6 # The BIOS loads this code from the first sector of the hard disk into
     7 # memory at physical address 0x7c00 and starts executing in real mode
     8 # with %cs=0 %ip=7c00.
     9 
    10 .code16 # Assemble for 16-bit mode
    11 .globl start
    12 start:
    13 cli # BIOS enabled interrupts; disable
    14 
    15 # Zero data segment registers DS, ES, and SS.
    16 xorw %ax,%ax # Set %ax to zero
    17 movw %ax,%ds # -> Data Segment
    18 movw %ax,%es # -> Extra Segment
    19 movw %ax,%ss # -> Stack Segment
    20 
    21 # Physical address line A20 is tied to zero so that the first PCs
    22 # with 2 MB would run software that assumed 1 MB. Undo that.
    23 seta20.1:
    24 inb $0x64,%al # Wait for not busy
    25 testb $0x2,%al
    26 jnz seta20.1
    27 
    28 movb $0xd1,%al # 0xd1 -> port 0x64
    29 outb %al,$0x64
    30 
    31 seta20.2:
    32 inb $0x64,%al # Wait for not busy
    33 testb $0x2,%al
    34 jnz seta20.2
    35 
    36 movb $0xdf,%al # 0xdf -> port 0x60
    37 outb %al,$0x60
    38 
    39 # Switch from real to protected mode. Use a bootstrap GDT that makes
    40 # virtual addresses map directly to physical addresses so that the
    41 # effective memory map doesn’t change during the transition.
    42 lgdt gdtdesc
    43 movl %cr0, %eax
    44 orl $CR0_PE, %eax
    45 movl %eax, %cr0
    46 
    47 
    48 
    49 
    50 
    51 # Complete transition to 32-bit protected mode by using long jmp
    52 # to reload %cs and %eip. The segment descriptors are set up with no
    53 # translation, so that the mapping is still the identity mapping.
    54 ljmp $(SEG_KCODE<<3), $start32
    55 
    56 .code32 # Tell assembler to generate 32-bit code now.
    57 start32:
    58 # Set up the protected-mode data segment registers
    59 movw $(SEG_KDATA<<3), %ax # Our data segment selector
    60 movw %ax, %ds # -> DS: Data Segment
    61 movw %ax, %es # -> ES: Extra Segment
    62 movw %ax, %ss # -> SS: Stack Segment
    63 movw $0, %ax # Zero segments not ready for use
    64 movw %ax, %fs # -> FS
    65 movw %ax, %gs # -> GS
    66 
    67 # Set up the stack pointer and call into C.
    68 movl $start, %esp
    69 call bootmain
    70 
    71 # If bootmain returns (it shouldn’t), trigger a Bochs
    72 # breakpoint if running under Bochs, then loop.
    73 movw $0x8a00, %ax # 0x8a00 -> port 0x8a00
    74 movw %ax, %dx
    75 outw %ax, %dx
    76 movw $0x8ae0, %ax # 0x8ae0 -> port 0x8a00
    77 outw %ax, %dx
    78 spin:
    79 jmp spin
    80 
    81 # Bootstrap GDT
    82 .p2align 2 # force 4 byte alignment
    83 gdt:
    84 SEG_NULLASM # null seg
    85 SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
    86 SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
    87 
    88 gdtdesc:
    89 .word (gdtdesc - gdt - 1) # sizeof(gdt) - 1
    90 .long gdt # address gdt

    xv6/bootmain.c

     1 // Boot loader.
     2 //
     3 // Part of the boot sector, along with bootasm.S, which calls bootmain().
     4 // bootasm.S has put the processor into protected 32-bit mode.
     5 // bootmain() loads an ELF kernel image from the disk starting at
     6 // sector 1 and then jumps to the kernel entry routine.
     7 
     8 #include "types.h"
     9 #include "elf.h"
    10 #include "x86.h"
    11 #include "memlayout.h"
    12 
    13 #define SECTSIZE 512
    14 
    15 void readseg(uchar*, uint, uint);
    16 
    17 void
    18 bootmain(void)
    19 {
    20     struct elfhdr *elf;
    21     struct proghdr *ph, *eph;
    22     void (*entry)(void);
    23     uchar* pa;
    24 
    25     elf = (struct elfhdr*)0x10000; // scratch space
    26 
    27     // Read 1st page off disk
    28     readseg((uchar*)elf, 4096, 0);
    29 
    30     // Is this an ELF executable?
    31     if(elf->magic != ELF_MAGIC)
    32         return; // let bootasm.S handle error
    33 
    34     // Load each program segment (ignores ph flags).
    35     ph = (struct proghdr*)((uchar*)elf + elf->phoff);
    36     eph = ph + elf->phnum;
    37     for(; ph < eph; ph++){
    38         pa = (uchar*)ph->paddr;
    39         readseg(pa, ph->filesz, ph->off);
    40         if(ph->memsz > ph->filesz)
    41             stosb(pa + ph->filesz, 0, ph->memsz - ph->filesz);
    42     }
    43 
    44     // Call the entry point from the ELF header.
    45     // Does not return!
    46     entry = (void(*)(void))(elf->entry);
    47     entry();
    48 }
    49 
    50 
    51 void
    52 waitdisk(void)
    53 {
    54     // Wait for disk ready.
    55     while((inb(0x1F7) & 0xC0) != 0x40)
    56         ;
    57 }
    58 
    59 // Read a single sector at offset into dst.
    60 void
    61 readsect(void *dst, uint offset)
    62 {
    63     // Issue command.
    64     waitdisk();
    65     outb(0x1F2, 1); // count = 1
    66     outb(0x1F3, offset);
    67     outb(0x1F4, offset >> 8);
    68     outb(0x1F5, offset >> 16);
    69     outb(0x1F6, (offset >> 24) | 0xE0);
    70     outb(0x1F7, 0x20); // cmd 0x20 - read sectors
    71 
    72     // Read data.
    73     waitdisk();
    74     insl(0x1F0, dst, SECTSIZE/4);
    75 }
    76 
    77 // Read ’count’ bytes at ’offset’ from kernel into physical address ’pa’.
    78 // Might copy more than asked.
    79 void
    80 readseg(uchar* pa, uint count, uint offset)
    81 {
    82     uchar* epa;
    83 
    84     epa = pa + count;
    85 
    86     // Round down to sector boundary.
    87     pa -= offset % SECTSIZE;
    88 
    89     // Translate from bytes to sectors; kernel starts at sector 1.
    90     offset = (offset / SECTSIZE) + 1;
    91 
    92     // If this is too slow, we could read lots of sectors at a time.
    93     // We’d write more to memory than asked, but it doesn’t matter --
    94     // we load in increasing order.
    95     for(; pa < epa; pa += SECTSIZE, offset++)
    96         readsect(pa, offset);
    97 }
  • 相关阅读:
    javascript入门笔记8-window对象
    javascript入门笔记7-计时器
    一篇RxJava友好的文章(二)
    Android 最新学习资料收集
    一篇RxJava友好的文章(一)
    瓣呀,一个基于豆瓣api仿网易云音乐的开源项目
    UStore-自定义JDF文件格式输出
    UStore-添加自定义工作流(JDF)到产品
    XMPie部署与创建过程
    XMPie Tracking 操作
  • 原文地址:https://www.cnblogs.com/LinKArftc/p/5814503.html
Copyright © 2011-2022 走看看