|
From: <ls...@us...> - 2007-05-12 10:29:03
|
Revision: 3187
http://jnode.svn.sourceforge.net/jnode/?rev=3187&view=rev
Author: lsantha
Date: 2007-05-12 03:28:59 -0700 (Sat, 12 May 2007)
Log Message:
-----------
First working GRUB installer.
Added Paths:
-----------
trunk/fs/src/fs/org/jnode/fs/jfat/command/MBRFormatter.java
Removed Paths:
-------------
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
Deleted: trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatBootSector.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatBootSector.java 2007-05-12 10:25:44 UTC (rev 3186)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatBootSector.java 2007-05-12 10:28:59 UTC (rev 3187)
@@ -1,47 +0,0 @@
-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);
- }
-
-
-
-
-
-}
Deleted: trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatFormatter.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatFormatter.java 2007-05-12 10:25:44 UTC (rev 3186)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/command/GrubJFatFormatter.java 2007-05-12 10:28:59 UTC (rev 3187)
@@ -1,267 +0,0 @@
-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);
- }
-}
Deleted: trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java 2007-05-12 10:25:44 UTC (rev 3186)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java 2007-05-12 10:28:59 UTC (rev 3187)
@@ -1,105 +0,0 @@
-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......");
- }
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Added: trunk/fs/src/fs/org/jnode/fs/jfat/command/MBRFormatter.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/command/MBRFormatter.java (rev 0)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/command/MBRFormatter.java 2007-05-12 10:28:59 UTC (rev 3187)
@@ -0,0 +1,510 @@
+/*
+ * $Id: MBRFormatter.java 7-5-2007 Tanmoy $
+ *
+ * JNode.org
+ * Copyright (C) 2003-2006 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+
+
+package org.jnode.fs.jfat.command;
+
+/**
+ * The MBRFormatter is the main class for writing the stage1 and stage1.5
+ * to the MBR.
+ */
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+import org.apache.log4j.Logger;
+import org.jnode.driver.ApiNotFoundException;
+import org.jnode.driver.Device;
+import org.jnode.driver.block.BlockDeviceAPI;
+import org.jnode.driver.bus.ide.IDEConstants;
+import org.jnode.fs.FileSystemException;
+import org.jnode.partitions.ibm.IBMPartitionTable;
+import org.jnode.partitions.ibm.IBMPartitionTableEntry;
+import org.jnode.util.FileUtils;
+import org.jnode.util.LittleEndian;
+
+/**
+ * @author tango
+ */
+
+public class MBRFormatter {
+ private static final Logger log = Logger.getLogger(MBRFormatter.class);
+ IBMPartitionTableEntry oldEntry;
+ 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/grub.s1";
+ final String stageResourceName2 = "/devices/sg0/boot/grub/fat.s15";
+ private static int installPartition = 0xFFFFFF;
+ private String configFile;
+
+ /**
+ *
+ * The reading of the OLD MBR
+ * @throws java.io.IOException
+ *
+ */
+ private void checkMBR(ByteBuffer MBR) throws IOException
+ {
+ if (!IBMPartitionTable.containsPartitionTable(MBR.array()))
+ throw new IOException("This device doesn't contain a valid MBR, use --initmbr.");
+ }
+
+ /**
+ * Reading the Grub stages from the Rescue Device.
+ *
+ * @param stage1ResourceName
+ * @return
+ * @throws java.io.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;
+ }
+
+ /**
+ * The Method for reading the stage1.5 from the Rescue Disk.
+ * @param stage2ResourceName
+ * @return
+ * @throws java.io.IOException
+ */
+ public byte[] getStage1_5(String stage2ResourceName) throws IOException {
+ if (stage1_5 == null) {
+ File file = new File(stage2ResourceName);
+ InputStream is = new FileInputStream(file);
+ byte[] buf = new byte[(int)file.length()];
+ FileUtils.copy(is, buf);
+ is.close();
+ stage1_5 = buf;
+ }
+ return stage1_5;
+
+ }
+
+ /**
+ * The method that will write the stage1.5 for the File System
+ * specific to the Boot-sector to the block device.
+ *
+ *
+ */
+ public final static void writeStage1_5(long stage1_5_start,
+ ByteBuffer stage1_5,
+ BlockDeviceAPI devApi) {
+ try {
+ devApi.write(stage1_5_start,(stage1_5));
+ }catch (IOException e) {
+ e.printStackTrace();
+
+ }
+ }
+
+ /**
+ * @throws org.jnode.fs.FileSystemException
+ * @throws org.jnode.fs.FileSystemException
+ * @throws org.jnode.fs.FileSystemException
+ * @throws java.io.IOException
+ * @throws java.io.IOException
+ * @see org.jnode.fs.fat.FatFormatter#format(org.jnode.driver.block.BlockDeviceAPI)
+ */
+ public void format(Device device) throws FileSystemException, IOException {
+ BlockDeviceAPI devApi;
+ try {
+ devApi = device.getAPI(BlockDeviceAPI.class);
+ } catch (ApiNotFoundException e) {
+ throw new FileSystemException("Device is not a partition!", e);
+ }
+
+ log.info("The MBR Old is checked successfully.");
+ ByteBuffer MBR=ByteBuffer.allocate(IDEConstants.SECTOR_SIZE);
+ devApi.read(0, MBR);
+ checkMBR(MBR);
+ log.info("The MBR Old is read successfully.");
+
+ /*int add=LittleEndian.getInt32(MBR.array(),0x44);
+ System.out.println("The value at the position 0x44 is-> " +Integer.toHexString(add));*/
+ byte[] partition=getPartitionTable(0x1be,64,MBR);
+
+ if(!isaValidBootSector(MBR.array())){
+ log.error("The OLD Boot Sector is not valid.");
+ }
+
+ stage1=getStage1(stageResourceName1);
+ /**
+ * The BPB stands for the Bios Parameter Block.As the BPB of
+ * a disk is fixed and it is written to the disk during the
+ * partitioning of the disk. The BPB is present between the
+ * position of 0x3 to 0x48 position.
+ *
+ * NOTE:
+ * 1) Here need to make the BPB more independently(ie without
+ * array of the BPB using it in MBR)
+ *
+ * 2)The next Inportant matter is here that in the MBR's
+ * <b> 0x44 th</b> position we setting the position of the
+ * stage1.5 or Stage2.here as i used the Stage1.5 at the Sector
+ * 1(second sector) so The Value is set here as 01 00 00 00
+ *
+ * 3)In the Position of the 0x40:
+ * The boot drive. If it is 0xFF, use a drive passed by BIOS.
+ * The value is 0x80 for HDD.I kept it default here.
+ *
+ * 4)0x42: The starting address of Stage 2 or Stage1.5.
+ * As here i used the Stage1.5;hence the value i set here 0x2000
+ * If it is Stage2 then it will be 0x8000.
+ *
+ * 5)0x48: The starting segment of Stage 2 or Stage1.5.
+ * Here for stage1.5 i used the value 0x20
+ * For stage2 it will be 0x80.
+ *
+ * TODO: In this portion we need to use dynamically the BPB values.
+ * And, that time at the stage1 buffer the EMBEDDED variables need to
+ * set here individually.
+ *
+ * BUGs REPORT: Using statically the value of the BPB.and setted
+ * the EMBEDDED variables in that array statically.It is not good.
+ * ;-)
+ *
+ */
+ setBPB(BPB,stage1);
+ /**
+ * The Partition table is the cruisal part of the HDD formatted with
+ * different FS.For the grub disk the Stage1 is kept upto the first
+ * 446bytes to the MBR.Then after the 64 bytes are kept for Setting
+ * the PArtition table.
+ *
+ * N.B. : The grub will be written actually always after the
+ * Partition Table written to the HDD.IT is very IMPORTANT.
+ *
+ */
+ setPartitionTable(0x1be,64,partition,stage1);
+
+ /**
+ * Checking the BootSector is Valid or not.
+ * Actually here need to check the Sector Signature.
+ * 0x55AA --->
+ *
+ */
+ if(!isaValidBootSector(stage1)){
+ log.error("The New Boot Sector Is Not Valid.");
+ }
+
+ try {
+ /**
+ * write the GRUB's stage1 to the MBR
+ */
+ System.out.print("Writing stage 1 ... ");
+ devApi.write(0,ByteBuffer.wrap(stage1));
+ devApi.flush();
+ System.out.println("done.");
+
+
+
+
+ System.out.println("The Stage1.5 is now embedding.");
+ stage1_5 = getStage1_5(stageResourceName2);
+ int size=stage1_5.length/IDEConstants.SECTOR_SIZE;
+ log.info("The Size of the stage1_5 is : "+size);
+
+
+
+ /**
+ * The most important stage of the GRUB BOOTING. THE stage1.5.
+ *
+ * The Embedded variables for the grub setting into
+ * the JNode's grub stage1.5
+ */
+
+
+ /**
+ * The Blocklists for JNode grub installer is setting to
+ * the (512-4)th position of the Sector1 of the Stage1.5.
+ * Blocklists is the size of the stage1.5 in the sectors unit.
+ *
+ **/
+ LittleEndian.setInt16(stage1_5,512-4 ,size);
+
+
+ /** Fixup the install partition */
+ LittleEndian.setInt32(stage1_5, 512 + 0x08, installPartition);
+
+
+ setConfigFile("/boot/grub/menu.lst");
+
+ /** The Saved Entry Number **/
+ LittleEndian.setInt32(stage1_5,512+0xc,0xe);
+
+ /**
+ * The most important section of the Grub
+ * The path of the stage2 in the stage1.5
+ *
+ * NOTE: Here at the ox19 offset of the second
+ * Sector of the stage1.5. the value of the Drive Path
+ * is kept where the stage2 is kept.
+ * Ex: as here the /dev/hd0 is used (ie the partition where
+ * the FATfs is kept and where the stage2 will keep.
+ * So here the value set as 0x00.
+ *
+ * The path of the stage2 is very important.Otherwise it will can
+ * create ERROR 17.
+ *
+ * Suppose (hd0,1)/boot/grub/stage2--
+ * (hd0,1) corresponds to linux partition /dev/hda2
+ * (or /dev/sda2, depending on bios).So hd0 is the first hard disk found by bios.
+ * The "1" stands for partition number starting from "0".
+ * Under linux partition numbers start with 1. Therefore,
+ * the number differs.When this path
+ * is patched into stage1.5 at position 512+0x12+5, then the device specification
+ * (hd0,1) is converted to binary, e.g. 0x8001ffff
+ * (0x80 first hard disk, 0x01 first partition, 0xffff
+ * only for BSD partition).The directory /boot/grub/stage2 is relative to the
+ * partition, so if you have a /boot partition, then the path would be just /grub/stage2.
+ * Normally grub should detect the mapping of unix partition to its own
+ * partition numbering scheme automatically. In some cases this does
+ * not work, e.g. if you have multiple hard disks, the numbering of your
+ * BIOS is hard to predict. Grub uses a file device.map where you can change
+ * the numbering manually.
+ *
+ *
+ * <b>BUGS:</b>1) As currently it is only statically written here the
+ * value of the 0x00; so the stage2 is need to only kept at
+ * the /devices/hdb0.For supporting it in the any partition
+ * here need to change once little bit logic.
+ *
+ * 2)Need to support the Device.map for MUltiple Disk supporting in
+ * the JNODE.
+ *
+ **/
+ LittleEndian.setInt8(stage1_5,512+0x19,0x00);
+
+ /**
+ * Fixup the config file
+ * TODO: here to be change that the Config File
+ * will write after skipping the /boot/grub/stage2
+ *
+ */
+ if (configFile != null) {
+ int ofs = 512 + 0x27;
+ 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;
+ }
+
+
+ /**
+ * The Method for writing the Stage1.5 to
+ * the Sector 1 actually to the second sector.
+ *
+ *
+ */
+ writeStage1_5(IDEConstants.SECTOR_SIZE, ByteBuffer.wrap(stage1_5), devApi);
+
+
+ } catch (IOException e) {
+ System.out.println("The Bootsector Failed....");
+ }
+
+
+ System.out.println("Writing stage 1 and stage 1.5 has been completed.");
+
+
+
+}
+
+ /**
+ * The Writing the BPB to the MBR to its Correct Position.
+ * @param bpb2
+ * @param stage12
+ */
+ private void setBPB(byte[] bpb2, byte[] stage12) {
+ System.arraycopy (bpb2 ,0, stage12, 0x3, bpb2.length );
+ }
+ /**
+ * The Reading the Partition Table.
+ * @param offset
+ * @param len
+ * @param MBR
+ * @return
+ */
+ protected byte[] getPartitionTable ( int offset, int len ,ByteBuffer MBR) {
+ byte[] v = new byte[len];
+ System.arraycopy (MBR.array() ,offset, v, 0, len );
+ return v;
+ }
+ /**
+ * The writting method of the Partition table to the MBR to
+ * 446bytes ...
[truncated message content] |
|
From: <ls...@us...> - 2007-05-12 10:29:56
|
Revision: 3188
http://jnode.svn.sourceforge.net/jnode/?rev=3188&view=rev
Author: lsantha
Date: 2007-05-12 03:29:55 -0700 (Sat, 12 May 2007)
Log Message:
-----------
First working GRUB installer.
Added Paths:
-----------
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/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-05-12 10:29:55 UTC (rev 3188)
@@ -0,0 +1,107 @@
+/*
+ * $Id: GrubJFatFormatter.java Tanmoy $
+ *
+ * JNode.org
+ * Copyright (C) 2007 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.jnode.fs.jfat.command;
+
+import java.io.*;
+import org.apache.log4j.Logger;
+import org.jnode.fs.FileSystemException;
+
+
+/**
+ * File :GrubFatFormatter.java
+ * <p/>
+ * The very important file for the Grub Installation. Here the
+ * methods for setting the Stage2 to the partition is kept.
+ *
+ * @author Tango Devian
+ */
+public class GrubJFatFormatter {
+ private static final Logger log = Logger.getLogger(GrubJFatFormatter.class);
+ private static final String GRUB_STAGE_2 = "/devices/sg0/boot/grub/grub.s2";
+ private static final String GRUB_MENU_LST = "/devices/sg0/boot/grub/menu.lst";
+
+ /**
+ * @throws org.jnode.fs.FileSystemException
+ *
+ * @throws org.jnode.fs.FileSystemException
+ *
+ * @throws org.jnode.fs.FileSystemException
+ *
+ * @throws java.io.IOException
+ * @throws java.io.IOException
+ * @see org.jnode.fs.fat.FatFormatter#format(org.jnode.driver.block.BlockDeviceAPI)
+ */
+ public void format(String path) throws FileSystemException, IOException {
+ // writting of the stage2 and menu.LST
+ try {
+ File destDir = new File(path + "/boot/grub/");
+ if(!destDir.exists()){
+ System.out.print("Creating directory: " + destDir.getAbsolutePath() + " ... ");
+ destDir.mkdirs();
+ System.out.println("done.");
+ }
+
+ System.out.print("Writing stage 2 ... ");
+ copyFAT(GRUB_STAGE_2, destDir.getAbsolutePath(), "stage2");
+ System.out.println("done.");
+
+ System.out.print("Writing menu.lst ... ");
+ copyFAT(GRUB_MENU_LST, destDir.getAbsolutePath(), "menu.lst");
+ System.out.println("done.");
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void copyFile(File srcFile, File destFile) throws IOException {
+
+ InputStream in = new FileInputStream(srcFile);
+ OutputStream out = new FileOutputStream(destFile);
+
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = in.read(buffer)) >= 0) {
+ out.write(buffer, 0, bytesRead);
+ }
+ out.close();
+ in.close();
+
+ }
+
+ private static void copyFAT(String srcFileCopy, String destFileCopy, String destFileName) throws IOException {
+
+ // make sure the source file is indeed a readable file
+ File srcFile = new File(srcFileCopy);
+ if (!srcFile.isFile() || !srcFile.canRead()) {
+ throw new IllegalArgumentException("Not a readable file: " + srcFile.getName());
+ }
+
+ // make sure the second argument is a directory
+ File destDir = new File(destFileCopy);
+
+ // create File object for destination file
+ File destFile = new File(destDir, destFileName);
+
+ // copy file, optionally creating a checksum
+ 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-05-12 10:29:55 UTC (rev 3188)
@@ -0,0 +1,99 @@
+/*
+ * $Id: FatConstants.java 2224 Tanmoy $
+ *
+ * JNode.org
+ * Copyright (C) 2003-2006 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+package org.jnode.fs.jfat.command;
+
+import java.io.*;
+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;
+
+/**
+ * <p/>
+ * The Grub Installer command for the JNODE.
+ * jnode/>grub hdb /devices/hdb0
+ *
+ * @HDA_TARGET /dev/hda0 or /dev/fd0
+ * <p/>
+ * TODO: Adding more options for supporting JGRUB with user specified File
+ * System wise.
+ * Adding more command support for grub insallation.
+ * @author Tango Devian
+ */
+public class JGrubInstallCommand implements Command {
+ static final DeviceArgument ARG_DEVICE = new DeviceArgument("device", "device where grub will be installed");
+ static final FileArgument ARG_DIR = new FileArgument("directory", "the directory for stage2 and menu.lst");
+ static final Help.Info HELP_INFO = new Help.Info("grub", "Install GRUB to the specified location.",
+ new Parameter(ARG_DEVICE, Parameter.MANDATORY),
+ new Parameter(ARG_DIR, 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);
+ File destDir = ARG_DIR.getFile(cmdLine);
+ DeviceManager dm = InitialNaming.lookup(DeviceManager.NAME);
+ Device dev = dm.getDevice(device);
+ String destDirName = destDir.getAbsolutePath();
+ out.println("Installing GRUB to: " + device + ", " + destDirName);
+ try {
+ new MBRFormatter().format(dev);
+ new GrubJFatFormatter().format(destDirName);
+ out.println("Restarting device: " + device);
+ dm.stop(dev);
+ dm.start(dev);
+ out.println("GRUB has been successflly installed to " + device + ".");
+ } catch (FileNotFoundException e) {
+ err.println("File not found: " + e.getMessage());
+ } catch (IOException e) {
+ err.println("I/O exception: " + e.getMessage());
+ }
+ } catch (NameNotFoundException e) {
+ err.println("Name not found: " + e.getMessage());
+ } catch (DeviceNotFoundException e) {
+ err.println("Device not found: " + e.getMessage());
+ } catch (DriverException e) {
+ err.println("The DriverException Occuered ..." + e.getMessage());
+ }
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-06-21 19:22:50
|
Revision: 3281
http://jnode.svn.sourceforge.net/jnode/?rev=3281&view=rev
Author: lsantha
Date: 2007-06-21 12:22:45 -0700 (Thu, 21 Jun 2007)
Log Message:
-----------
Grub installer improvements by Tango.
Modified Paths:
--------------
trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java
trunk/fs/src/fs/org/jnode/fs/jfat/command/MBRFormatter.java
Modified: trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java 2007-06-17 20:37:45 UTC (rev 3280)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/command/JGrubInstallCommand.java 2007-06-21 19:22:45 UTC (rev 3281)
@@ -36,6 +36,7 @@
import org.jnode.shell.help.ParsedArguments;
import org.jnode.shell.help.argument.DeviceArgument;
import org.jnode.shell.help.argument.FileArgument;
+import org.jnode.shell.help.argument.OptionArgument;
/**
* <p/>
@@ -52,10 +53,27 @@
public class JGrubInstallCommand implements Command {
static final DeviceArgument ARG_DEVICE = new DeviceArgument("device", "device where grub will be installed");
static final FileArgument ARG_DIR = new FileArgument("directory", "the directory for stage2 and menu.lst");
- static final Help.Info HELP_INFO = new Help.Info("grub", "Install GRUB to the specified location.",
- new Parameter(ARG_DEVICE, Parameter.MANDATORY),
- new Parameter(ARG_DIR, Parameter.MANDATORY));
+ static final OptionArgument TYPE = new OptionArgument("action",
+ "Type parameter",
+ new OptionArgument.Option[] { new OptionArgument.Option("-p",
+ "Set the partition point for installing Stage2,menu.lst") });
+ static final OptionArgument PS_VAL = new OptionArgument("Partition Value",
+ "Setting The Partition value like (-p 1) for the hdx1", new OptionArgument.Option[] {
+ new OptionArgument.Option("0", "hdX0"),
+ new OptionArgument.Option("1", "hdX1"),
+ new OptionArgument.Option("2", "hdX2"),
+ new OptionArgument.Option("3", "hdX3")
+ });
+
+
+
+ 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(TYPE,Parameter.MANDATORY),
+ new Parameter(PS_VAL,Parameter.MANDATORY),
+ new Parameter(ARG_DIR,Parameter.MANDATORY),
+ });
/**
* @param args
* @throws Exception
@@ -72,12 +90,19 @@
ParsedArguments cmdLine = HELP_INFO.parse(commandLine.toStringArray());
String device = ARG_DEVICE.getValue(cmdLine);
File destDir = ARG_DIR.getFile(cmdLine);
+
+ Integer bsize=null;
+ try {
+ bsize = Integer.valueOf(PS_VAL.getValue(cmdLine));
+ } catch (NumberFormatException nfe) {
+ System.out.println("ERROR: give the partition value as the 0 ,1,2,3"+"\n" +"This grub installer not support the Extended partition.");
+ }
DeviceManager dm = InitialNaming.lookup(DeviceManager.NAME);
Device dev = dm.getDevice(device);
String destDirName = destDir.getAbsolutePath();
out.println("Installing GRUB to: " + device + ", " + destDirName);
try {
- new MBRFormatter().format(dev);
+ new MBRFormatter().format(dev,bsize);
new GrubJFatFormatter().format(destDirName);
out.println("Restarting device: " + device);
dm.stop(dev);
Modified: trunk/fs/src/fs/org/jnode/fs/jfat/command/MBRFormatter.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/command/MBRFormatter.java 2007-06-17 20:37:45 UTC (rev 3280)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/command/MBRFormatter.java 2007-06-21 19:22:45 UTC (rev 3281)
@@ -18,10 +18,6 @@
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-
-
-
-
package org.jnode.fs.jfat.command;
/**
@@ -30,6 +26,7 @@
*/
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
@@ -60,8 +57,11 @@
*/
final String stageResourceName1 = "/devices/sg0/boot/grub/grub.s1";
final String stageResourceName2 = "/devices/sg0/boot/grub/fat.s15";
- private static int installPartition = 0xFFFFFF;
+ private static int INSTALL_PARTITION = 0xFFFFFF;
private String configFile;
+ //The Embedded Variables values in Jnode
+ final int SAVED_ENTRY_NUMBER=0xe;
+ final String CONFIG_FILE_NAME="/boot/grub/menu.lst";
/**
*
@@ -72,7 +72,7 @@
private void checkMBR(ByteBuffer MBR) throws IOException
{
if (!IBMPartitionTable.containsPartitionTable(MBR.array()))
- throw new IOException("This device doesn't contain a valid MBR, use --initmbr.");
+ throw new IOException("This device doesn't contain a valid MBR.");
}
/**
@@ -138,7 +138,7 @@
* @throws java.io.IOException
* @see org.jnode.fs.fat.FatFormatter#format(org.jnode.driver.block.BlockDeviceAPI)
*/
- public void format(Device device) throws FileSystemException, IOException {
+ public void format(Device device,int bsize) throws FileSystemException, IOException {
BlockDeviceAPI devApi;
try {
devApi = device.getAPI(BlockDeviceAPI.class);
@@ -146,11 +146,11 @@
throw new FileSystemException("Device is not a partition!", e);
}
- log.info("The MBR Old is checked successfully.");
+ log.info("Checking the old MBR...");
ByteBuffer MBR=ByteBuffer.allocate(IDEConstants.SECTOR_SIZE);
devApi.read(0, MBR);
checkMBR(MBR);
- log.info("The MBR Old is read successfully.");
+ log.info("done.");
/*int add=LittleEndian.getInt32(MBR.array(),0x44);
System.out.println("The value at the position 0x44 is-> " +Integer.toHexString(add));*/
@@ -159,8 +159,11 @@
if(!isaValidBootSector(MBR.array())){
log.error("The OLD Boot Sector is not valid.");
}
-
+ try{
stage1=getStage1(stageResourceName1);
+ }catch(FileNotFoundException e){
+ log.error("The stage1 is not available.");
+ }
/**
* The BPB stands for the Bios Parameter Block.As the BPB of
* a disk is fixed and it is written to the disk during the
@@ -171,7 +174,7 @@
* 1) Here need to make the BPB more independently(ie without
* array of the BPB using it in MBR)
*
- * 2)The next Inportant matter is here that in the MBR's
+ * 2)The next Important matter is here that in the MBR's
* <b> 0x44 th</b> position we setting the position of the
* stage1.5 or Stage2.here as i used the Stage1.5 at the Sector
* 1(second sector) so The Value is set here as 01 00 00 00
@@ -233,7 +236,11 @@
System.out.println("The Stage1.5 is now embedding.");
- stage1_5 = getStage1_5(stageResourceName2);
+ try{
+ stage1_5 = getStage1_5(stageResourceName2);
+ }catch(FileNotFoundException ex){
+ log.error("The Stage1.5 is not available.");
+ }
int size=stage1_5.length/IDEConstants.SECTOR_SIZE;
log.info("The Size of the stage1_5 is : "+size);
@@ -253,18 +260,21 @@
* Blocklists is the size of the stage1.5 in the sectors unit.
*
**/
- LittleEndian.setInt16(stage1_5,512-4 ,size);
+ setLittleEnd_BlockLists(stage1_5,size);
+
/** Fixup the install partition */
- LittleEndian.setInt32(stage1_5, 512 + 0x08, installPartition);
+ setLittleEnd_InstallPartition(stage1_5,INSTALL_PARTITION);
- setConfigFile("/boot/grub/menu.lst");
-
+
+ setConfigFile(CONFIG_FILE_NAME);
+
/** The Saved Entry Number **/
- LittleEndian.setInt32(stage1_5,512+0xc,0xe);
+ setLittleEnd_EntryNumber(stage1_5,SAVED_ENTRY_NUMBER);
+
/**
* The most important section of the Grub
* The path of the stage2 in the stage1.5
@@ -306,8 +316,9 @@
* the JNODE.
*
**/
- LittleEndian.setInt8(stage1_5,512+0x19,0x00);
+ setLittleEnd_DrivePath(stage1_5,bsize);
+
/**
* Fixup the config file
* TODO: here to be change that the Config File
@@ -346,8 +357,48 @@
}
-
/**
+ * The Install Partition setting
+ * @arch i386
+ * @param stage1_5
+ * @param installPartition2
+ */
+ private void setLittleEnd_InstallPartition(byte[] stage1_5, int installPartition) {
+ LittleEndian.setInt32(stage1_5, 512 + 0x08, installPartition);
+
+ }
+ /**
+ * The saved Entry Number setting.
+ * @arch i386
+ * @param stage1_5
+ * @param i
+ */
+ private void setLittleEnd_EntryNumber(byte[] stage1_5, int i) {
+ LittleEndian.setInt32(stage1_5,512+0xc,i);
+
+ }
+ /**
+ * The BlockLists if the stage1.5 is setting here.
+ * @arch:i386
+ * @param stage1_5
+ * @param size
+ */
+ private void setLittleEnd_BlockLists(byte[] stage1_5, int size) {
+ LittleEndian.setInt16(stage1_5,512-4 ,size);
+
+ }
+ /**
+ *
+ * Setting the Drive path to the stage1.5.Though it is BUGGY yet.
+ * @arch i386
+ * @param stage1_5
+ * @param i
+ */
+ private void setLittleEnd_DrivePath(byte[] stage1_5, int i) {
+ LittleEndian.setInt8(stage1_5,512+0x19,i);
+ }
+
+ /**
* The Writing the BPB to the MBR to its Correct Position.
* @param bpb2
* @param stage12
@@ -397,14 +448,14 @@
* @return
*/
public int getInstallPartition() {
- return installPartition;
+ return INSTALL_PARTITION;
}
/**
* The Writtting of the InstallPartition.
* @param installPartition1
*/
public static void setInstallPartition(int installPartition1) {
- installPartition = installPartition1;
+ INSTALL_PARTITION = installPartition1;
}
/**
*
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|