idediskdriver.java

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

JAVA
240
字号
/*
 * $Id: IDEDiskDriver.java,v 1.4 2004/01/24 23:43:35 gbin Exp $
 */
package org.jnode.driver.ide;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import javax.naming.NameNotFoundException;

import org.apache.log4j.Logger;
import org.jnode.driver.Bus;
import org.jnode.driver.Device;
import org.jnode.driver.DeviceAlreadyRegisteredException;
import org.jnode.driver.DeviceManager;
import org.jnode.driver.Driver;
import org.jnode.driver.DriverException;
import org.jnode.driver.block.BlockAlignmentSupport;
import org.jnode.driver.block.BlockDeviceAPI;
import org.jnode.fs.partitions.ibm.IBMPartitionTable;
import org.jnode.fs.partitions.ibm.IBMPartitionTableEntry;
import org.jnode.naming.InitialNaming;

/**
 * Device driver for IDE disks.
 * 
 * @author epr
 */
public class IDEDiskDriver extends Driver implements IDEDeviceAPI, IDEConstants {

	/** My logger */
	private final Logger log = Logger.getLogger(getClass());
	/** The IDE device i'm driving */
	private IDEDevice drivedDevice;
	/** Number of addressable sectors */
	private long maxSector;
	/** Has LBA support? */
	//private boolean lba;
	/** Has DMA support? */
	//private boolean dma;
	/** Support 48-bit addressing? */
	private boolean s48bit;
	private IDEDiskBus diskBus;

	/**
	 * @see org.jnode.driver.Driver#startDevice()
	 */
	protected void startDevice() throws DriverException {
		final IDEDevice dev = this.drivedDevice;
		diskBus = new IDEDiskBus(dev);
		/* Register the IDEDevice API */
		drivedDevice.registerAPI(BlockDeviceAPI.class, new BlockAlignmentSupport(this, SECTOR_SIZE));
		/* Get basic configuration */
		final IDEDriveDescriptor descr = dev.getDescriptor();
		//lba = descr.supportsLBA();
		//dma = descr.supportsDMA();
		s48bit = descr.supports48bitAddressing();
		if (s48bit) {
			maxSector = descr.getSectorsIn48bitAddressing();
		} else {
			maxSector = descr.getSectorsIn28bitAddressing();
		}

		// Look for partitions
		try {
			// Find the devicemanager
			DeviceManager devMan = (DeviceManager)InitialNaming.lookup(DeviceManager.NAME);
			// Read the bootsector
			final byte[] bs = new byte[SECTOR_SIZE];
			read(0, bs, 0, SECTOR_SIZE);
			
			final IBMPartitionTable pt = new IBMPartitionTable(bs, dev);
						
			final int max = pt.getLength();
			for (int i = 0; i < max; i++) {
				final IBMPartitionTableEntry pte = (IBMPartitionTableEntry)pt.getEntry(i);
				if (pte.isValid()) {
					if (pte.isExtended()) {
						//now we should have an filled vector in the pt
						final Vector extendedPartitions  = pt.getExtendedPartitions();
						log.info("Have "+ extendedPartitions.size()+ " Extended partitions found");
						
						
					} else {
						// Create a partition device.
						final String id = drivedDevice.getId() + i;
						final IDEDiskPartitionDevice pdev =
							new IDEDiskPartitionDevice(
								diskBus,
								id,
								drivedDevice,
								pte,
								pte.getStartLba(),
								pte.getNrSectors());
						pdev.setDriver(new IDEDiskPartitionDriver());
						devMan.register(pdev);
					}
				}
			}
		} catch (DeviceAlreadyRegisteredException ex) {
			throw new DriverException("Partition device is already known???? Probably a bug", ex);
		} catch (IOException ex) {
			throw new DriverException("Cannot read partition table", ex);
		} catch (NameNotFoundException ex) {
			throw new DriverException("Cannot find DeviceManager", ex);
		}
	}

	/**
	 * @see org.jnode.driver.Driver#stopDevice()
	 */
	protected void stopDevice() throws DriverException {
		// find mounted partitions on this device and unregister them !
		try {
			DeviceManager devMan = (DeviceManager)InitialNaming.lookup(DeviceManager.NAME);
			Collection devices = devMan.getDevices();
			Vector toStop = new Vector();

			for (Iterator alldev = devices.iterator(); alldev.hasNext();) {
				Object device = alldev.next();
				if (device instanceof IDEDiskPartitionDevice) {
					IDEDiskPartitionDevice partition = (IDEDiskPartitionDevice)device;
					if (partition.getParent() == drivedDevice) {
						toStop.add(partition);
					}
				}

			}

			for (Iterator allDevToStop = toStop.iterator(); allDevToStop.hasNext();) {
				IDEDiskPartitionDevice partition = (IDEDiskPartitionDevice)allDevToStop.next();
				devMan.unregister(partition);
			}
		} catch (NameNotFoundException e) {
			throw new DriverException("Problem while stopping this IDE device", e);
		}

		drivedDevice.unregisterAPI(BlockDeviceAPI.class);
	}

	/**
	 * @see org.jnode.driver.Driver#afterConnect(org.jnode.driver.Device)
	 */
	protected void afterConnect(Device device) {
		this.drivedDevice = (IDEDevice)device;
		super.afterConnect(device);
	}

	/**
	 * @see org.jnode.driver.block.BlockDeviceAPI#flush()
	 */
	public void flush() {
		// Nothing to do yet
	}

	/**
	 * @see org.jnode.driver.block.BlockDeviceAPI#getLength()
	 */
	public long getLength() {
		return maxSector * SECTOR_SIZE;
	}

	/**
	 * @see org.jnode.driver.block.BlockDeviceAPI#read(long, byte[], int, int)
	 */
	public void read(long devOffset, byte[] dest, int destOffset, int length) throws IOException {
		if ((devOffset % SECTOR_SIZE) != 0) {
         throw new IOException("Non aligned devOffset not allowed. Size requested = " + devOffset + " Sector size = " + SECTOR_SIZE);
		}
		if ((length % SECTOR_SIZE) != 0) {
			throw new IOException("Non aligned length not allowed. Size requested = " + length + " Sector size = " + SECTOR_SIZE);
		}
		final long lbaStart = devOffset / SECTOR_SIZE;
		final int sectors = length / SECTOR_SIZE;

		if (lbaStart + sectors > this.maxSector) {
			throw new IOException("read beyond device sectors");
		}

		final IDEReadSectorsCommand cmd;
		cmd = new IDEReadSectorsCommand(drivedDevice.getTaskfile(), drivedDevice.isMaster(), lbaStart, sectors);
		try {
			drivedDevice.getController().executeAndWait(cmd);
		} catch (InterruptedException ex) {
			throw new IOException("IDE read interrupted", ex);
		}
		if (cmd.hasError()) {
			throw new IOException("IDE read error:" + cmd.getError());
		} else {
			System.arraycopy(cmd.getData(), 0, dest, destOffset, length);
		}
	}

	/**
	 * @see org.jnode.driver.block.BlockDeviceAPI#write(long, byte[], int, int)
	 */
	public void write(long devOffset, byte[] src, int srcOffset, int length) throws IOException {
		if ((devOffset % SECTOR_SIZE) != 0) {
			throw new IOException("Non aligned offsets not allowed");
		}
		if ((length % SECTOR_SIZE) != 0) {
			throw new IOException("Non aligned length not not allowed");
		}
		final long lbaStart = devOffset / SECTOR_SIZE;
		final int sectors = length / SECTOR_SIZE;

		if (lbaStart + sectors > this.maxSector) {
			throw new IOException("write beyond device sectors");
		}

		final IDEWriteSectorsCommand cmd;
		cmd =
			new IDEWriteSectorsCommand(
				drivedDevice.getTaskfile(),
				drivedDevice.isMaster(),
				lbaStart,
				sectors,
				src,
				srcOffset,
				length);
		try {
			drivedDevice.getController().executeAndWait(cmd);
		} catch (InterruptedException ex) {
			throw new IOException("IDE write interrupted", ex);
		}
		if (cmd.hasError()) {
			throw new IOException("IDE write error:" + cmd.getError());
		}
	}

	static class IDEDiskBus extends Bus {

		public IDEDiskBus(IDEDevice parent) {
			super(parent);
		}
	}
}

⌨️ 快捷键说明

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