bootimagebuilder.java

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

JAVA
586
字号
/*
 * $Id: BootImageBuilder.java,v 1.16 2004/02/26 10:33:12 epr Exp $
 */
package org.jnode.build.x86;

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.tools.ant.Project;
import org.jnode.assembler.Label;
import org.jnode.assembler.NativeStream;
import org.jnode.assembler.UnresolvedObjectRefException;
import org.jnode.assembler.NativeStream.ObjectInfo;
import org.jnode.assembler.x86.Register;
import org.jnode.assembler.x86.X86Stream;
import org.jnode.boot.Main;
import org.jnode.build.AbstractBootImageBuilder;
import org.jnode.build.BuildException;
import org.jnode.linker.Elf;
import org.jnode.linker.ElfLinker;
import org.jnode.plugin.PluginRegistry;
import org.jnode.util.NumberUtils;
import org.jnode.vm.MathSupport;
import org.jnode.vm.MonitorManager;
import org.jnode.vm.SoftByteCodes;
import org.jnode.vm.Vm;
import org.jnode.vm.VmArchitecture;
import org.jnode.vm.VmProcessor;
import org.jnode.vm.VmSystem;
import org.jnode.vm.VmSystemObject;
import org.jnode.vm.VmThread;
import org.jnode.vm.classmgr.ObjectLayout;
import org.jnode.vm.classmgr.VmArray;
import org.jnode.vm.classmgr.VmClassType;
import org.jnode.vm.classmgr.VmInstanceField;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.classmgr.VmMethodCode;
import org.jnode.vm.classmgr.VmStaticField;
import org.jnode.vm.classmgr.VmStatics;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.x86.VmX86Architecture;
import org.jnode.vm.x86.VmX86Processor;
import org.jnode.vm.x86.X86CpuID;
import org.jnode.vm.x86.compiler.X86CompilerConstants;

/**
 * @author epr
 */
public class BootImageBuilder extends AbstractBootImageBuilder implements X86CompilerConstants {

	public static final int LOAD_ADDR = 1024 * 1024;
	public static final int INITIAL_OBJREFS_CAPACITY = 750000;
	public static final int INITIAL_SIZE = 40*1024*1024;
	
	private VmX86Processor processor;
	private String processorId;
	private final VmX86Architecture arch = new VmX86Architecture();
	private VmStatics statics;

	/** The offset in our (java) image file to the initial jump to our main-method */
	public static final int JUMP_MAIN_OFFSET = ObjectLayout.objectAlign((ObjectLayout.HEADER_SLOTS + 1) * VmX86Architecture.SLOT_SIZE);

	public static final int INITIALIZE_METHOD_OFFSET = 8;

	//private final Label vmInvoke = new Label("vm_invoke");
	private final Label vmFindThrowableHandler = new Label("vm_findThrowableHandler");
	private final Label vmReschedule = new Label("VmProcessor_reschedule");
	private final Label sbcSystemException = new Label("SoftByteCodes_systemException");
	private final Label vmThreadRunThread = new Label("VmThread_runThread");
	private final Label vmCurProcessor = new Label("vmCurProcessor");

	/**
	 * Construct a new BootImageBuilder
	 */
	public BootImageBuilder() {
	}

	/**
	 * Create a platform specific native stream.
	 * 
	 * @return The native stream
	 */
	protected NativeStream createNativeStream() {
		return new X86Stream(getCPUID(), LOAD_ADDR, INITIAL_OBJREFS_CAPACITY, INITIAL_SIZE, INITIAL_SIZE);
	}

	/**
	 * Create the default processor for this architecture.
	 * 
	 * @return The processor
	 * @throws BuildException
	 */
	protected VmProcessor createProcessor(VmStatics statics) throws BuildException {
		this.statics = statics;
		if (processor == null) {
			processor = new VmX86Processor(0, arch, statics, getCPUID());
		}
		return processor;
	}

	/**
	 * Gets the target architecture.
	 * 
	 * @return The target architecture
	 * @throws BuildException
	 */
	protected VmArchitecture getArchitecture() throws BuildException {
		return arch;
	}

	/**
	 * Copy the kernel native code into the native stream.
	 * 
	 * @param os
	 * @throws BuildException
	 */
	protected void copyKernel(NativeStream os) throws BuildException {
		try {
			Elf elf = Elf.newFromFile(getKernelFile().getCanonicalPath());
			new ElfLinker((X86Stream) os).loadElfObject(elf);
		} catch (IOException ex) {
			throw new BuildException(ex);
		}
	}

	/**
	 * Align the stream on a page boundary
	 * 
	 * @param os
	 * @throws BuildException
	 */
	protected void pageAlign(NativeStream os) throws BuildException {
		((X86Stream) os).align(4096);
	}

	/**
	 * Emit code to bootstrap the java image
	 * 
	 * @param os
	 * @param clInitCaller
	 * @param pluginRegistry
	 * @throws BuildException
	 */
	protected void initImageHeader(NativeStream os, Label clInitCaller, Vm vm, PluginRegistry pluginRegistry) throws BuildException {
		try {
			int startLength = os.getLength();

			VmType vmCodeClass = loadClass(VmMethodCode.class);
			final X86Stream.ObjectInfo initObject = os.startObject(vmCodeClass);
			final int offset = os.getLength() - startLength;
			if (offset != JUMP_MAIN_OFFSET) {
				throw new BuildException("JUMP_MAIN_OFFSET is incorrect [" + offset + "] (set to Object headersize)");
			}

			final X86Stream os86 = (X86Stream) os;
			final Label introCode = new Label("$$introCode");
			
			os86.setObjectRef(new Label("$$jmp-introCode"));
			os86.writeJMP(introCode);
			initObject.markEnd();

			// The loading of class can emit object in between, so first load
			// all required classes here.
			loadClass(Main.class);
			loadClass(MathSupport.class);
			loadClass(MonitorManager.class);
			loadClass(SoftByteCodes.class);
			loadClass(Vm.class);
			loadClass(VmMethod.class);
			loadClass(VmProcessor.class);
			loadClass(VmThread.class);
			loadClass(VmType.class);
			loadClass(VmSystem.class);
			loadClass(VmSystemObject.class);
			
			final X86Stream.ObjectInfo initCodeObject = os.startObject(vmCodeClass);
			os86.setObjectRef(introCode);
			initMain(os86, pluginRegistry);
			initVm(os86, vm);
			//initHeapManager(os86, vm);
			initVmThread(os86);

			os.setObjectRef(new Label("$$Initial call to clInitCaller"));
			os86.writeCALL(clInitCaller);

			initCallMain(os86);

			initCodeObject.markEnd();
			
		} catch (ClassNotFoundException ex) {
			throw new BuildException(ex);
		}
	}

	/**
	 * Link all undefined symbols from the kernel native code.
	 * 
	 * @param os
	 * @throws ClassNotFoundException
	 * @throws UnresolvedObjectRefException
	 */
	protected void linkNativeSymbols(NativeStream os) throws ClassNotFoundException, UnresolvedObjectRefException {
		NativeStream.ObjectRef refJava;

		/* Link VmMethod_compile */
		VmType vmMethodClass = loadClass(VmMethod.class);
		refJava = os.getObjectRef(vmMethodClass.getMethod("recompile", "()V"));
		os.getObjectRef(new Label("VmMethod_recompile")).link(refJava);

		/* Link VmMethod_Class */
		refJava = os.getObjectRef(vmMethodClass);
		os.getObjectRef(new Label("VmMethod_Class")).link(refJava);

		/* Link SoftByteCodes_systemException */
		VmType sbcClass = loadClass(SoftByteCodes.class);
		refJava = os.getObjectRef(sbcClass.getMethod("systemException", "(II)Ljava/lang/Throwable;"));
		os.getObjectRef(sbcSystemException).link(refJava);

		/* Link SoftByteCodes_resolveClass */
		refJava = os.getObjectRef(sbcClass.getMethod("resolveClass", "(Lorg/jnode/vm/classmgr/VmConstClass;)Lorg/jnode/vm/classmgr/VmType;"));
		os.getObjectRef(new Label("SoftByteCodes_resolveClass")).link(refJava);

		/* Link SoftByteCodes_resolveField */
		refJava = os.getObjectRef(sbcClass.getMethod("resolveField", "(Lorg/jnode/vm/classmgr/VmMethod;Lorg/jnode/vm/classmgr/VmConstFieldRef;Z)Lorg/jnode/vm/classmgr/VmField;"));
		os.getObjectRef(new Label("SoftByteCodes_resolveField")).link(refJava);

		/* Link SoftByteCodes_resolveMethod */
		refJava =
			os.getObjectRef(sbcClass.getMethod("resolveMethod", "(Lorg/jnode/vm/classmgr/VmMethod;Lorg/jnode/vm/classmgr/VmConstMethodRef;)Lorg/jnode/vm/classmgr/VmMethod;"));
		os.getObjectRef(new Label("SoftByteCodes_resolveMethod")).link(refJava);

		/* Link SoftByteCodes_allocArray */
		refJava = os.getObjectRef(sbcClass.getMethod("allocArray", "(Lorg/jnode/vm/classmgr/VmType;I)Ljava/lang/Object;"));
		os.getObjectRef(new Label("SoftByteCodes_allocArray")).link(refJava);

		/* Link SoftByteCodes_allocMultiArray */
		refJava = os.getObjectRef(sbcClass.getMethod("allocMultiArray", "(Lorg/jnode/vm/classmgr/VmType;[I)Ljava/lang/Object;"));
		os.getObjectRef(new Label("SoftByteCodes_allocMultiArray")).link(refJava);

		/* Link SoftByteCodes_allocObject */
		refJava = os.getObjectRef(sbcClass.getMethod("allocObject", "(Lorg/jnode/vm/classmgr/VmType;I)Ljava/lang/Object;"));
		os.getObjectRef(new Label("SoftByteCodes_allocObject")).link(refJava);

		/* Link SoftByteCodes_allocPrimitiveArray */
		refJava = os.getObjectRef(sbcClass.getMethod("allocPrimitiveArray", "(II)Ljava/lang/Object;"));
		os.getObjectRef(new Label("SoftByteCodes_allocPrimitiveArray")).link(refJava);

		/* Link SoftByteCodes_anewarray */
		refJava = os.getObjectRef(sbcClass.getMethod("anewarray", "(Lorg/jnode/vm/classmgr/VmMethod;Lorg/jnode/vm/classmgr/VmType;I)Ljava/lang/Object;"));
		os.getObjectRef(new Label("SoftByteCodes_anewarray")).link(refJava);

		/* Link SoftByteCodes_unknownOpcode */
		refJava = os.getObjectRef(sbcClass.getMethod("unknownOpcode", "(II)V"));
		os.getObjectRef(new Label("SoftByteCodes_unknownOpcode")).link(refJava);

		final VmType vmThreadClass = loadClass(VmThread.class);

		/* Link VmThread_runThread */
		refJava = os.getObjectRef(vmThreadClass.getMethod("runThread", "(Lorg/jnode/vm/VmThread;)V"));
		os.getObjectRef(vmThreadRunThread).link(refJava);

		/* Link VmProcessor_reschedule */
		VmType vmProcClass = loadClass(VmProcessor.class);
		refJava = os.getObjectRef(vmProcClass.getMethod("reschedule", "()V"));
		os.getObjectRef(vmReschedule).link(refJava);

		/* Link vmCurProcessor */
		refJava = os.getObjectRef(processor);
		os.getObjectRef(vmCurProcessor).link(refJava);

		/* Set statics index of VmSystem_currentTimeMillis */
		final VmType vmSystemClass = loadClass(VmSystem.class);
		final int staticsIdx = ((VmStaticField) vmSystemClass.getField("currentTimeMillis")).getStaticsIndex();
		final X86Stream os86 = (X86Stream)os;
		os86.set32(os.getObjectRef(new Label("currentTimeMillisStaticsIdx")).getOffset(), staticsIdx);

		/* Link vm_findThrowableHandler */
		refJava = os.getObjectRef(vmSystemClass.getMethod("findThrowableHandler", "(Ljava/lang/Throwable;Lorg/jnode/vm/Address;Lorg/jnode/vm/Address;)Lorg/jnode/vm/Address;"));
		os.getObjectRef(vmFindThrowableHandler).link(refJava);

		/* Link MonitorManager_monitorEnter */
		VmType monMgrClass = loadClass(MonitorManager.class);
		refJava = os.getObjectRef(monMgrClass.getMethod("monitorEnter", "(Ljava/lang/Object;)V"));
		os.getObjectRef(new Label("MonitorManager_monitorEnter")).link(refJava);

		/* Link MonitorManager_monitorExit */
		refJava = os.getObjectRef(monMgrClass.getMethod("monitorExit", "(Ljava/lang/Object;)V"));
		os.getObjectRef(new Label("MonitorManager_monitorExit")).link(refJava);

		/* Link MathSupport_ldiv */
		VmType mathSupportClass = loadClass(MathSupport.class);
		refJava = os.getObjectRef(mathSupportClass.getMethod("ldiv", "(JJ)J"));
		os.getObjectRef(new Label("MathSupport_ldiv")).link(refJava);

⌨️ 快捷键说明

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