⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootmain.c

📁 类unix x86平台的简单操作系统
💻 C
字号:
// This a dirt simple boot loader, whose sole job is to boot// an elf kernel image from the first IDE hard disk.//// DISK LAYOUT//  * This program(boot.S and main.c) is the bootloader.  It should//    be stored in the first sector of the disk.////  * The 2nd sector onward holds the kernel image.////  * The kernel image must be in ELF format.//// BOOT UP STEPS//  * when the CPU boots it loads the BIOS into memory and executes it////  * the BIOS intializes devices, sets of the interrupt routines, and//    reads the first sector of the boot device(e.g., hard-drive)//    into memory and jumps to it.////  * Assuming this boot loader is stored in the first sector of the//    hard-drive, this code takes over...////  * control starts in bootloader.S -- which sets up protected mode,//    and a stack so C code then run, then calls cmain()////  * cmain() in this file takes over, //    reads in the kernel and jumps to it.#include "types.h"#include "elf.h"#include "x86.h"#define SECTSIZE  512#define ELFHDR    ((struct elfhdr*) 0x10000) // scratch spacevoid readsect(void*, uint);void readseg(uint, uint, uint);voidcmain(void){  struct proghdr *ph, *eph;  // read 1st page off disk  readseg((uint) ELFHDR, SECTSIZE*8, 0);  // is this a valid ELF?  if(ELFHDR->magic != ELF_MAGIC)    goto bad;  // load each program segment (ignores ph flags)  ph = (struct proghdr*) ((uchar*) ELFHDR + ELFHDR->phoff);  eph = ph + ELFHDR->phnum;  for(; ph < eph; ph++)    readseg(ph->va, ph->memsz, ph->offset);  // call the entry point from the ELF header  // note: does not return!  ((void(*)(void)) (ELFHDR->entry & 0xFFFFFF))();bad:  outw(0x8A00, 0x8A00);  outw(0x8A00, 0x8E00);  for(;;)    ;}// Read 'count' bytes at 'offset' from kernel into virtual address 'va'.// Might copy more than askedvoidreadseg(uint va, uint count, uint offset){  uint end_va;  va &= 0xFFFFFF;  end_va = va + count;  // round down to sector boundary  va &= ~(SECTSIZE - 1);  // translate from bytes to sectors, and kernel starts at sector 1  offset = (offset / SECTSIZE) + 1;  // If this is too slow, we could read lots of sectors at a time.  // We'd write more to memory than asked, but it doesn't matter --  // we load in increasing order.  while(va < end_va) {    readsect((uchar*) va, offset);    va += SECTSIZE;    offset++;  }}voidwaitdisk(void){  // wait for disk reaady  while((inb(0x1F7) & 0xC0) != 0x40)    ;}voidreadsect(void *dst, uint offset){  // wait for disk to be ready  waitdisk();  outb(0x1F2, 1);   // count = 1  outb(0x1F3, offset);  outb(0x1F4, offset >> 8);  outb(0x1F5, offset >> 16);  outb(0x1F6, (offset >> 24) | 0xE0);  outb(0x1F7, 0x20);  // cmd 0x20 - read sectors  // wait for disk to be ready  waitdisk();  // read a sector  insl(0x1F0, dst, SECTSIZE/4);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -