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 + -
显示快捷键?