bootimagebuilder.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 586 行 · 第 1/2 页

JAVA
586
字号

		/* Link MathSupport_lrem */
		refJava = os.getObjectRef(mathSupportClass.getMethod("lrem", "(JJ)J"));
		os.getObjectRef(new Label("MathSupport_lrem")).link(refJava);

		// Link Luser_esp
		refJava = os.getObjectRef(initialStackPtr);
		os.getObjectRef(new Label("Luser_esp")).link(refJava);

		// Link freeMemoryStart
		refJava = os.getObjectRef(imageEnd);
		os.getObjectRef(new Label("freeMemoryStart")).link(refJava);

		// Link bootHeapStart
		refJava = os.getObjectRef(bootHeapStart);
		os.getObjectRef(new Label("bootHeapStart")).link(refJava);

		// Link bootHeapEnd
		refJava = os.getObjectRef(bootHeapEnd);
		os.getObjectRef(new Label("bootHeapEnd")).link(refJava);

	}

	/**
	 * Emit code to call Main.vmMain
	 * 
	 * @param os
	 * @throws BuildException
	 * @throws ClassNotFoundException
	 */
	protected void initCallMain(X86Stream os) throws BuildException, ClassNotFoundException {
		final VmType vmMethodClass = loadClass(VmMethod.class);
		final VmType vmMainClass = loadClass(Main.class);
		final VmMethod mainMethod = vmMainClass.getMethod(Main.MAIN_METHOD_NAME, Main.MAIN_METHOD_SIGNATURE);
		final VmInstanceField nativeCodeField = (VmInstanceField) vmMethodClass.getField("nativeCode");

		os.writeMOV_Const(Register.EAX, mainMethod);
		os.writeCALL(Register.EAX, nativeCodeField.getOffset());
		os.writeRET(); // RET instruction
	}

	/**
	 * Emit code to initialize VmThread.
	 * 
	 * @param os
	 * @throws BuildException
	 * @throws ClassNotFoundException
	 */
	protected void initVmThread(X86Stream os) throws BuildException, ClassNotFoundException {
		final VmType vmThreadClass = loadClass(VmThread.class);
		final VmInstanceField threadStackField = (VmInstanceField) vmThreadClass.getField("stack");
		final VmInstanceField stackEndField = (VmInstanceField) vmThreadClass.getField("stackEnd");
		final VmThread initialThread = processor.getCurrentThread();

		os.setObjectRef(new Label("$$Setup initial thread"));
		os.writeMOV_Const(Register.EBX, initialThread);

		/** Initialize initialStack.stack to Luser_stack */
		//os.writeMOV(Register.ECX, threadStackField.getOffset());
		os.writeMOV_Const(Register.EDX, initialStack);
		os.writeMOV(INTSIZE, Register.EBX, threadStackField.getOffset(), Register.EDX);
		// Calculate and set stackEnd
		os.writeLEA(Register.EDX, Register.EDX, VmThread.STACK_OVERFLOW_LIMIT);
		os.writeMOV(INTSIZE, Register.EBX, stackEndField.getOffset(), Register.EDX);
	}

	/**
	 * Create the initial stack space.
	 * 
	 * @param os
	 * @param stackLabel
	 *            Label to the start of the stack space (low address)
	 * @param stackPtrLabel
	 *            Label to the initial stack pointer (on x86 high address)
	 * @throws BuildException
	 * @throws ClassNotFoundException
	 * @throws UnresolvedObjectRefException
	 */
	protected void createInitialStack(NativeStream os, Label stackLabel, Label stackPtrLabel) throws BuildException, ClassNotFoundException, UnresolvedObjectRefException {
		ObjectInfo objectInfo = os.startObject(loadClass(VmSystemObject.class));
		int stackOffset = os.setObjectRef(stackLabel).getOffset();
		int stackAddr = stackOffset + (int) os.getBaseAddr();
		// Low stack address
		os.write32(stackAddr + VmThread.STACK_OVERFLOW_LIMIT);
		// High stack address
		os.write32(stackAddr + VmThread.DEFAULT_STACK_SIZE);
		// The actual stack space
		for (int i = 8; i < VmThread.DEFAULT_STACK_SIZE; i++) {
			os.write8(0);
		}
		os.setObjectRef(stackPtrLabel);
		objectInfo.markEnd();
	}

	/**
	 * Emit code to initialize Vm.
	 * 
	 * @param os
	 * @throws BuildException
	 * @throws ClassNotFoundException
	 */
	protected void initVm(X86Stream os, Vm vm) throws BuildException, ClassNotFoundException {
		os.setObjectRef(new Label("$$Initialize Vm"));
		VmType vmClass = loadClass(Vm.class);
		VmStaticField vmField = (VmStaticField) vmClass.getField("instance");
		
		// Setup STATICS register (EDI)
		os.writeMOV_Const(Register.EDI, statics.getTable());

		/* Set Vm.instance */
		os.writeMOV_Const(Register.EBX, vm);
		final int vmOffset = (VmArray.DATA_OFFSET + vmField.getStaticsIndex()) << 2;
		log("vmOffset " + NumberUtils.hex(vmOffset), Project.MSG_VERBOSE);
		os.writeMOV(INTSIZE, Register.EDI, vmOffset, Register.EBX);
	}

	/**
	 * Emit code to initialize org.jnode.boot.Main.
	 * 
	 * @param os
	 * @param registry
	 * @throws BuildException
	 * @throws ClassNotFoundException
	 */
	protected void initMain(X86Stream os, PluginRegistry registry) throws BuildException, ClassNotFoundException {
		os.setObjectRef(new Label("$$Initialize Main"));
		final VmType mainClass = loadClass(Main.class);
		final VmStaticField registryField = (VmStaticField) mainClass.getField(Main.REGISTRY_FIELD_NAME);

		// Setup STATICS register (EDI)
		os.writeMOV_Const(Register.EDI, statics.getTable());

		/* Set Main.pluginRegistry */
		os.writeMOV_Const(Register.EBX, registry);
		final int rfOffset = (VmArray.DATA_OFFSET + registryField.getStaticsIndex()) << 2;
		log("rfOffset " + NumberUtils.hex(rfOffset), Project.MSG_VERBOSE);
		os.writeMOV(INTSIZE, Register.EDI, rfOffset, Register.EBX);
	}

	protected void emitStaticInitializerCalls(NativeStream nativeOs, VmType[] bootClasses, Object clInitCaller) throws ClassNotFoundException {

		final X86Stream os = (X86Stream) nativeOs;
		X86Stream.ObjectInfo initCallerObject = os.startObject(loadClass(VmMethodCode.class));

		os.setObjectRef(clInitCaller);

		// Call VmClass.loadFromBootClassArray
		final VmType vmClassClass = loadClass(VmType.class);
		final VmMethod lfbcaMethod = vmClassClass.getMethod("loadFromBootClassArray", "([Lorg/jnode/vm/classmgr/VmType;)V");
		final VmType vmMethodClass = loadClass(VmMethod.class);
		final VmInstanceField nativeCodeField = (VmInstanceField) vmMethodClass.getField("nativeCode");

		os.writeMOV_Const(Register.EAX, bootClasses);
		os.writePUSH(Register.EAX);
		os.writeMOV_Const(Register.EAX, lfbcaMethod);
		os.writeCALL(Register.EAX, nativeCodeField.getOffset());

		// Now call all static initializers
		for (int i = 0;(i < bootClasses.length); i++) {
			VmType vmClass = bootClasses[i];
			if ((vmClass instanceof VmClassType) && (((VmClassType) vmClass).getInstanceCount() > 0)) {
				VmMethod clInit = vmClass.getMethod("<clinit>", "()V");
				if (clInit != null) {
					os.setObjectRef(clInitCaller + "$$" + vmClass.getName());
					log("Missing static initializer in class " + vmClass.getName(), Project.MSG_WARN);
					/*
					 * os.writeMOV(X86Constants.rEAX, clInit);
					 */

				}
			}
		}
		os.writeRET(); // RET
		os.align(4096);

		initCallerObject.markEnd();
	}

	/**
	 * Save the native stream to destFile.
	 * 
	 * @param os
	 * @throws BuildException
	 */
	protected void storeImage(NativeStream os) throws BuildException {
		try {
			log("Creating image");
			FileOutputStream fos = new FileOutputStream(getDestFile());
			fos.write(os.getBytes(), 0, os.getLength());
			fos.close();

			/*
			 * log.info("Creating ELF image"); final long start = System.currentTimeMillis(); final
			 * Elf elf = ((X86Stream)os).toElf(); final long end = System.currentTimeMillis();
			 * log.info("... took " + (end-start) + "ms");
			 * elf.store(getDestFile().getAbsolutePath() + ".elf");
			 */

		} catch (IOException ex) {
			throw new BuildException(ex);
		}
	}

	/**
	 * Patch the Multiboot header
	 */
	private static final int MB_MAGIC = 0x1BADB002;
	private static final int MB_LOAD_ADDR = 4 * 4;
	private static final int MB_LOAD_END_ADDR = 5 * 4;
	private static final int MB_BSS_END_ADDR = 6 * 4;

	/**
	 * Patch any fields in the header, just before the image is written to disk.
	 * 
	 * @param nativeOs
	 * @throws BuildException
	 */
	protected void patchHeader(NativeStream nativeOs) throws BuildException {
		final X86Stream os = (X86Stream) nativeOs;
		int mb_hdr = -1;
		for (int i = 0; i < 1024; i += 4) {
			if (os.get32(i) == MB_MAGIC) {
				mb_hdr = i;
				break;
			}
		}
		if (mb_hdr < 0) {
			throw new BuildException("Cannot find Multiboot header");
		}

		int loadAddr = os.get32(mb_hdr + MB_LOAD_ADDR);
		if (loadAddr != os.getBaseAddr()) {
			throw new BuildException("Non-matching load address, found 0x" + Integer.toHexString(loadAddr) + ", expected 0x" + Long.toHexString(os.getBaseAddr()));
		}

		os.set32(mb_hdr + MB_LOAD_END_ADDR, (int) os.getBaseAddr() + os.getLength());
		os.set32(mb_hdr + MB_BSS_END_ADDR, (int) os.getBaseAddr() + os.getLength());
	}

	/**
	 * @return Returns the processorId.
	 */
	public final String getCpu() {
		return this.processorId;
	}

	/**
	 * @param processorId
	 *            The processorId to set.
	 */
	public final void setCpu(String processorId) {
		this.processorId = processorId;
	}

	protected X86CpuID getCPUID() {
		return X86CpuID.createID(processorId);
	}

	protected void logStatistics(NativeStream os) {
		final X86Stream os86 = (X86Stream)os;
		final int count = os86.getObjectRefsCount();
		if (count > INITIAL_OBJREFS_CAPACITY) {
			log("Increase BootImageBuilder.INITIAL_OBJREFS_CAPACITY to " + count + " for faster build.", Project.MSG_WARN);
		}
		final int size = os86.getLength();
		if (size > INITIAL_SIZE) {
			log("Increase BootImageBuilder.INITIAL_SIZE to " + size + " for faster build.", Project.MSG_WARN);
		}
	}
    /**
     * @see org.jnode.build.AbstractBootImageBuilder#setupCompileHighOptLevelPackages()
     */
    protected void setupCompileHighOptLevelPackages() {
        super.setupCompileHighOptLevelPackages();
        addCompileHighOptLevel("org.jnode.assembler.x86");
        addCompileHighOptLevel("org.jnode.system.x86");
        addCompileHighOptLevel("org.jnode.vm.x86");
        addCompileHighOptLevel("org.jnode.vm.x86.compiler");
        addCompileHighOptLevel("org.jnode.vm.x86.compiler.l0c");
        addCompileHighOptLevel("org.jnode.vm.x86.compiler.l1");
        addCompileHighOptLevel("org.jnode.vm.x86.compiler.l2");
    }
    
    /**
     * @see org.jnode.build.AbstractBootImageBuilder#cleanup()
     */
    protected void cleanup() {
        super.cleanup();
        this.processor = null;
        this.statics = null;
    }
}

⌨️ 快捷键说明

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