|
From: <ls...@us...> - 2007-04-03 20:21:43
|
Revision: 3153
http://jnode.svn.sourceforge.net/jnode/?rev=3153&view=rev
Author: lsantha
Date: 2007-04-03 13:21:40 -0700 (Tue, 03 Apr 2007)
Log Message:
-----------
GRUB installer inplementation in progress, by Tango. I've applied some refactorings on it.
Added Paths:
-----------
trunk/fs/src/fs/org/jnode/fs/jfat/command/
trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatBootSector.java
trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatFormatter.java
trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java
Added: trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatBootSector.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatBootSector.java (rev 0)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatBootSector.java 2007-04-03 20:21:40 UTC (rev 3153)
@@ -0,0 +1,47 @@
+package org.jnode.fs.jfat.command;
+
+import org.jnode.fs.jfat.BootSector;
+
+/**
+ *
+ * @author Tango Devian
+ *
+ */
+/**
+ * This file will contain the differetn value se
+ *
+ */
+
+
+class GrubJFatBootSector extends BootSector{
+
+ public GrubJFatBootSector(byte[] sector) {
+ super(sector);
+ }
+ /**
+ * Constructor for GrubBootSector.
+ * @param size
+ */
+ public GrubJFatBootSector(int size) {
+ super(size);
+ }
+ /**
+ * Gets the first sector of stage1_5
+ * @return long
+ */
+ public long getStage1_5Sector() {
+ return get32(0x44);
+ }
+
+ /**
+ * Sets the first sector of stage1_5
+ */
+ public void setStage1_5Sector(long v) {
+ set32(0x44, v);
+ }
+
+
+
+
+
+}
Added: trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatFormatter.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatFormatter.java (rev 0)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatFormatter.java 2007-04-03 20:21:40 UTC (rev 3153)
@@ -0,0 +1,267 @@
+package org.jnode.fs.jfat.command;
+
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.util.zip.CRC32;
+import org.apache.log4j.Logger;
+import org.jnode.driver.ApiNotFoundException;
+import org.jnode.driver.Device;
+import org.jnode.driver.block.BlockDeviceAPI;
+import org.jnode.fs.FileSystemException;
+import org.jnode.fs.jfat.BootSector;
+import org.jnode.util.FileUtils;
+import org.jnode.util.LittleEndian;
+
+/**
+ * File :GrubFatFormatter.java
+ * <p/>
+ * The very important file for the Grub Installation. Here the methods for write
+ * to the MBR and the setting the Stage2 are kept.
+ *
+ * @author Tango Devian
+ */
+class GrubJFatFormatter {
+ private static final Logger log = Logger.getLogger(GrubJFatFormatter.class);
+
+ // The variables parameters declaration
+ byte[] stage1;
+
+ byte[] stage1_5;
+ /**
+ * The Source path for the Grub in CD://devices/sg0/boot/grub/STAGE1.
+ * Because the grub can installed from the Live Boot CD.
+ */
+ final String stageResourceName1 = "//devices/sg0/BOOT/GRUB/STAGE1.";
+
+ final String stageResourceName1_5 = "//devices/sg0/BOOT/GRUB/FAT1_5.";
+
+ private static int installPartition = 0xFFFFFFFF;
+
+ private String configFile;
+
+ private int bootSectorOffset;
+ private static boolean clock = true;
+ private static boolean verify = true;
+
+ /**
+ * Create the actual bootsector.
+ */
+ private BootSector createBootSector(String stage1Name, String stage1_5Name,
+ BlockDeviceAPI devApi) throws Exception {
+ System.out.println("The createbootsector entered.");
+ if (stage1Name == null) {
+ System.out.println("hi i am in createbotsector....");
+ stage1Name = "//devices/sg0/BOOT/GRUB/STAGE1.";
+ }
+ if (stage1_5Name == null) {
+ stage1_5Name = "//devices/sg0/BOOT/GRUB/FAT1_5.";
+ }
+ try {
+ stage1 = getStage1(stage1Name);
+ stage1_5 = getStage1_5(stage1_5Name);
+ return new GrubJFatBootSector(getStage1(stageResourceName1));
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ }
+
+ /**
+ * Reading the Grub stages from the device
+ *
+ * @param stage1ResourceName
+ * @return
+ * @throws IOException
+ */
+ public byte[] getStage1(String stage1ResourceName) throws IOException {
+ if (stage1 == null) {
+ File file = new File(stage1ResourceName);
+ InputStream is = new FileInputStream(file);
+ byte[] buf = new byte[512];
+ FileUtils.copy(is, buf);
+ is.close();
+ stage1 = buf;
+ }
+ return stage1;
+ }
+
+ public byte[] getStage1_5(String stage1_5ResourceName) throws IOException {
+ if (stage1_5 == null) {
+ File file = new File(stage1_5ResourceName);
+ InputStream in = new FileInputStream(file);
+ byte[] buf = new byte[(int) file.length()];
+ FileUtils.copy(in, buf);
+ in.close();
+ stage1_5 = buf;
+ }
+ return stage1_5;
+
+ }
+
+ /**
+ * The method that will write the stage1.5 for the fat specific to the
+ * Boot-sector to the block device.
+ */
+ public final static void writeStage1_5(long stage1_5_start, byte[] stage1_5,
+ BlockDeviceAPI devApi) {
+ try {
+ devApi.write(stage1_5_start, ByteBuffer.wrap(stage1_5));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @throws FileSystemException
+ * @throws FileSystemException
+ * @throws FileSystemException
+ * @throws IOException
+ * @throws IOException
+ * @see org.jnode.fs.fat.FatFormatter#format(BlockDeviceAPI)
+ */
+ public final void format(Device device, String path) throws FileSystemException, IOException {
+
+ System.out.println("The format(device) entered.");
+ BlockDeviceAPI devApi;
+ try {
+
+ devApi = device.getAPI(BlockDeviceAPI.class);
+ System.out.println("The devAPI initialization successfully....");
+ } catch (ApiNotFoundException e) {
+ throw new FileSystemException("Device is not a partition!", e);
+ }
+ System.out.println("The GrubJFatBootSector starting now......");
+ try {
+ GrubJFatBootSector bs = (GrubJFatBootSector) createBootSector(
+ stageResourceName1, stageResourceName1_5, devApi);
+
+ try {
+ bs.write(devApi);
+ // write the GRUB's stage1 to the MBR
+ // Writing Stage1
+ devApi.flush();
+
+ System.out.println("The stage1 is written successfully...");
+
+ stage1_5 = getStage1_5(stageResourceName1_5);
+
+ System.out.println("The stage1_5 buffer is created successfully....");
+ // writting the stage1.5;Here it is FatStage1_5
+ LittleEndian.setInt32(stage1_5, 512 - 8, bootSectorOffset + 2);
+ /* Fixup the install partition */
+ LittleEndian.setInt32(stage1_5, 512 + 0x08, installPartition);
+
+ setConfigFile("/boot/grub/menu.lst");
+ /* Fixup the config file */
+ if (configFile != null) {
+ int ofs = 512 + 0x12;
+ while (stage1_5[ofs] != 0) {
+ ofs++;
+ }
+ ofs++; /* Skip '\0' */
+ for (int i = 0; i < configFile.length(); i++) {
+ stage1_5[ofs++] = (byte) configFile.charAt(i);
+ }
+ stage1_5[ofs] = 0;
+ }
+ System.out.println("grub version [");
+ int i;
+ for (i = 512 + 0x12; stage1_5[i] != 0; i++) {
+ System.out.print((char) stage1_5[i]);
+ }
+ System.out.println("[ config ]");
+ i++;
+ for (; stage1_5[i] != 0; i++) {
+ System.out.println((char) stage1_5[i]);
+ }
+ // writting the stage1.5
+ System.out.println("the stage1_5 is writing now...pls wait...");
+
+ writeStage1_5(bs.getBytesPerSector(), stage1_5, devApi);
+ } catch (IOException e) {
+ System.out.println("The Bootsector Failed....");
+ }
+ } catch (Exception e) {
+ System.out.println("The exception at format()");
+ }
+
+ System.out.println("Thanks...The stage1_5 is written successfully.....");
+
+ // writting of the stage2 and menu.LST
+ System.out.println("The Stage2 is now writing....");
+ copyFAT("//devices/sg0/BOOT/GRUB/STAGE2_E.", path + "/boot/grub/");
+ System.out.println("The Menu.LSt is now writting....");
+ copyFAT("//devices/sg0/BOOT/GRUB/MENU.LST", path + "/boot/grub/");
+ System.out.println("The Stage2 is successfully created....");
+ }
+
+ public String getConfigFile() {
+ return configFile;
+ }
+
+ private void setConfigFile(String configFile) {
+ this.configFile = configFile;
+ }
+
+ public int getInstallPartition() {
+ return installPartition;
+ }
+
+ public static void setInstallPartition(int installPartition1) {
+ installPartition = installPartition1;
+ }
+
+ public static Long copyFile(File srcFile, File destFile) throws IOException {
+
+ InputStream in = new FileInputStream(srcFile);
+ OutputStream out = new FileOutputStream(destFile);
+ long millis = System.currentTimeMillis();
+ CRC32 checksum = null;
+ if (verify) {
+ checksum = new CRC32();
+ checksum.reset();
+ }
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = in.read(buffer)) >= 0) {
+ if (verify) {
+ checksum.update(buffer, 0, bytesRead);
+ }
+ out.write(buffer, 0, bytesRead);
+ }
+ out.close();
+ in.close();
+ if (clock) {
+ millis = System.currentTimeMillis() - millis;
+ System.out.println("Second(s): " + (millis / 1000L));
+ }
+ if (verify) {
+ return new Long(checksum.getValue());
+ } else {
+ return null;
+ }
+ }
+
+ public static void copyFAT(String srcFileCopy, String destFileCopy) throws IOException {
+
+ // make sure the source file is indeed a readable file
+ File srcFile = new File(srcFileCopy);
+ if (!srcFile.isFile() || !srcFile.canRead()) {
+ System.err.println("Not a readable file: " + srcFile.getName());
+ System.exit(1);
+ }
+ // make sure the second argument is a directory
+ File destDir = new File(destFileCopy);
+ if (!destDir.exists()) {
+ destDir.mkdirs();
+ System.out.println("The BOOT/GRUB/ Directory is created...");
+ }
+ // create File object for destination file
+ File destFile = new File(destDir, srcFile.getName());
+
+ // copy file, optionally creating a checksum
+ Long checksumSrc = copyFile(srcFile, destFile);
+ }
+}
Added: trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java (rev 0)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java 2007-04-03 20:21:40 UTC (rev 3153)
@@ -0,0 +1,105 @@
+package org.jnode.fs.jfat.command;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+
+import javax.naming.NameNotFoundException;
+
+import org.jnode.driver.Device;
+import org.jnode.driver.DeviceManager;
+import org.jnode.driver.DeviceNotFoundException;
+import org.jnode.driver.DriverException;
+import org.jnode.naming.InitialNaming;
+import org.jnode.shell.Command;
+import org.jnode.shell.CommandLine;
+import org.jnode.shell.help.Help;
+import org.jnode.shell.help.Parameter;
+import org.jnode.shell.help.ParsedArguments;
+import org.jnode.shell.help.argument.DeviceArgument;
+import org.jnode.shell.help.argument.FileArgument;
+
+/**
+ * The Grub Installer command for the JNODE.
+ * jnode/>jgrub HDA_TARGET
+ * HDA_TARGET /dev/hda0 or /dev/fd0
+ *
+ * @author Tango Devian
+ */
+public class JGrubInstallCommand implements Command {
+
+ static final DeviceArgument ARG_DEVICE = new DeviceArgument("device", "device to where the Grub will install");
+
+ static final FileArgument ARG_DIR = new FileArgument("directory", "the directory where you set the Stage2 and Menu.Lst");
+
+ static final Help.Info HELP_INFO = new Help.Info("grub", "Install the grub to the specified location.", new Parameter[]{
+ new Parameter(ARG_DEVICE, Parameter.MANDATORY),
+ new Parameter(ARG_DIR, Parameter.MANDATORY)});
+
+ //static final Parameter PARAM_DEVICE = new Parameter(ARG_DEVICE,
+ //Parameter.MANDATORY);
+ /**
+ * @param args
+ * @throws Exception
+ */
+ public static void main(String[] args) throws Exception {
+ new JGrubInstallCommand().execute(new CommandLine(args), System.in, System.out, System.err);
+ }
+
+ /**
+ *
+ */
+ public void execute(CommandLine commandLine, InputStream in, PrintStream out, PrintStream err) throws Exception {
+ try {
+ ParsedArguments cmdLine = HELP_INFO.parse(commandLine.toStringArray());
+ String device = ARG_DEVICE.getValue(cmdLine);
+ //i am not sure yet
+ File destDir = ARG_DIR.getFile(cmdLine);
+
+ out.println("grub The dm is now initialized.");
+ DeviceManager dm = InitialNaming.lookup(DeviceManager.NAME);
+
+ out.println("The getdevice() method invoking now.");
+ Device dev = dm.getDevice(device);
+
+ out.println("The device is successfully initialized.");
+ out.println("The Grub Installer is started......wait");
+ try {
+ try {
+ new GrubJFatFormatter().format(dev, destDir.getAbsolutePath());
+ } catch (FileNotFoundException e) {
+ err.println("The ERROR at GRUB FAT FORMAT method.");
+ }
+ } catch (IOException e) {
+ err.println("The ERROR at the FAT FORMAT method...");
+ }
+ //restart the device
+ dm.stop(dev);
+ out.println("The device is stopped....");
+ dm.start(dev);
+ out.println("The Grub successflly installed.");
+ } catch (NameNotFoundException e) {
+ out.println("The NameNotFoundException occured...");
+ } catch (DeviceNotFoundException e) {
+ err.println("The Device Not Found...");
+ } catch (DriverException e) {
+ out.println("The DriverException Occuered......");
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|