Пример #1
0
  public static void bootFromURIWithDT(
      ARMv5 cpu, RAM ramMain, String dtree, String kimage, String initrd, String cmdline) {
    byte[] cmdlb = cmdline.getBytes();
    // +1: need null char at the end of line
    byte[] cmdalign = new byte[(cmdlb.length + 1 + 3) & ~0x3];
    System.arraycopy(cmdlb, 0, cmdalign, 0, cmdlb.length);

    final int addrRAM = 0x00000000;
    final int addrDT = addrRAM + 0x800000;
    int sizeDT = 0;
    final int addrImage = addrRAM + 0x008000;
    int sizeImage = 0;
    final int addrInitrd = addrRAM + 0x00810000;
    int sizeInitrd = 0;
    boolean initrdExist = !initrd.equals("");

    // tentative boot loader for ARM Linux with Device Tree
    try {
      // load Device Tree Blob
      sizeDT = loadURIResource(new URI(dtree), cpu, addrDT);
      // load Image file
      sizeImage = loadURIResource(new URI(kimage), cpu, addrImage);
      // load Initrd/InitramFS file
      if (initrdExist) {
        sizeInitrd = loadURIResource(new URI(initrd), cpu, addrInitrd);
      }
    } catch (URISyntaxException e) {
      e.printStackTrace(System.err);
      return;
    }

    // report address mapping
    System.out.printf(
        "Address mapping:\n"
            + "  RAM       : 0x%08x\n"
            + "  DeviceTree: 0x%08x - 0x%08x\n"
            + "  Kernel    : 0x%08x - 0x%08x\n"
            + "  InitramFS : 0x%08x - 0x%08x\n",
        addrRAM,
        addrDT,
        addrDT + sizeDT - 1,
        addrImage,
        addrImage + sizeImage - 1,
        addrInitrd,
        addrInitrd + sizeInitrd - 1);

    // r0: 0
    cpu.setReg(0, 0);

    // r1: Do not care.
    cpu.setReg(1, 0);

    // r2: Device tree blob pointer.
    cpu.setReg(2, addrDT);

    // pc: entry of stext
    cpu.setPC(addrImage);
    cpu.setJumped(false);
  }
Пример #2
0
  public static void bootFromURI(
      ARMv5 cpu, RAM ramMain, String kimage, String initrd, String cmdline) {
    byte[] cmdlb = cmdline.getBytes();
    // +1: need null char at the end of line
    byte[] cmdalign = new byte[(cmdlb.length + 1 + 3) & ~0x3];
    System.arraycopy(cmdlb, 0, cmdalign, 0, cmdlb.length);

    final int addrRAM = 0x00000000;
    final int addrAtagsStart = addrRAM + 0x800000;
    int addrAtags = addrAtagsStart;
    final int addrImage = addrRAM + 0x00008000;
    int sizeImage = 0;
    final int addrInitrd = addrRAM + 0x00810000;
    int sizeInitrd = 0;
    boolean initrdExist = !initrd.equals("");

    // tentative boot loader for ARM Linux
    try {
      // load Image file
      sizeImage = loadURIResource(new URI(kimage), cpu, addrImage);
      // load Initrd/InitramFS file
      if (initrdExist) {
        sizeInitrd = loadURIResource(new URI(initrd), cpu, addrInitrd);
      }
    } catch (URISyntaxException e) {
      e.printStackTrace(System.err);
      return;
    }

    // report address mapping
    System.out.printf(
        "Address mapping:\n"
            + "  RAM   : 0x%08x\n"
            + "  Kernel: 0x%08x - 0x%08x\n"
            + "  Initrd: 0x%08x - 0x%08x\n"
            + "  ATAGS : 0x%08x - 0x%08x\n",
        addrRAM,
        addrImage,
        addrImage + sizeImage - 1,
        addrInitrd,
        addrInitrd + sizeInitrd - 1,
        addrAtags,
        addrAtags + 4096 - 1);

    // r0: 0
    cpu.setReg(0, 0);

    // r1: machine type
    // ARM-Versatile PB
    cpu.setReg(1, 0x00000183);
    // ARM-Versatile AB
    // cpu.setReg(1, 0x0000025e);

    // r2: ATAGS pointer.
    cpu.setReg(2, addrAtags);
    {
      // ATAG_CORE, size, tag, [flags, pagesize, rootdev]
      cpu.write32_a32(addrAtags + 0x00, 0x00000005);
      cpu.write32_a32(addrAtags + 0x04, ATAG_CORE);
      // bit 0: read only
      cpu.write32(addrAtags + 0x08, 0x00000001);
      cpu.write32(addrAtags + 0x0c, 0x00001000);
      cpu.write32(addrAtags + 0x10, 0x00000000);
      addrAtags += 0x14;

      // ATAG_MEM, size, tag, size, start
      cpu.write32_a32(addrAtags + 0x00, 0x00000004);
      cpu.write32_a32(addrAtags + 0x04, ATAG_MEM);
      cpu.write32_a32(addrAtags + 0x08, ramMain.getSize());
      cpu.write32_a32(addrAtags + 0x0c, addrRAM);
      addrAtags += 0x10;

      // ATAG_INITRD2, size, tag, size, start
      if (initrdExist) {
        cpu.write32_a32(addrAtags + 0x00, 0x00000004);
        cpu.write32_a32(addrAtags + 0x04, ATAG_INITRD2);
        cpu.write32_a32(addrAtags + 0x08, addrInitrd);
        cpu.write32_a32(addrAtags + 0x0c, sizeInitrd);
        addrAtags += 0x10;
      }

      // ATAG_CMDLINE
      cpu.write32_a32(addrAtags + 0x00, 0x00000002 + cmdalign.length / 4);
      cpu.write32_a32(addrAtags + 0x04, ATAG_CMDLINE);
      for (int i = 0; i < cmdalign.length; i++) {
        cpu.write8_a32(addrAtags + 0x08 + i, cmdalign[i]);
      }
      addrAtags += 0x08 + cmdalign.length;

      // ATAG_SERIAL, size, tag, low, high
      cpu.write32_a32(addrAtags + 0x00, 0x00000004);
      cpu.write32_a32(addrAtags + 0x04, ATAG_SERIAL);
      cpu.write32_a32(addrAtags + 0x08, 0x00000020);
      cpu.write32_a32(addrAtags + 0x0c, 0x00000030);
      addrAtags += 0x10;

      // ATAG_REVISION, size, tag, rev
      cpu.write32_a32(addrAtags + 0x00, 0x00000003);
      cpu.write32_a32(addrAtags + 0x04, ATAG_REVISION);
      cpu.write32_a32(addrAtags + 0x08, 0x00000010);
      addrAtags += 0x0c;

      // ATAG_NONE, size, tag
      // It is unique in that its size field in the header
      // should be set to 0 (not 2).
      cpu.write32_a32(addrAtags + 0x00, 0x00000000);
      cpu.write32_a32(addrAtags + 0x04, ATAG_NONE);
      addrAtags += 0x08;
    }

    // pc: entry of stext
    cpu.setPC(addrImage);
    cpu.setJumped(false);
  }