📄 diskpart.c
字号:
/****************************************************************************** File Name : diskpart.c Description : internal functions for manipulating the partition table******************************************************************************//* Includes ---------------------------------------------------------------- */#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include <assert.h>#include "stddefs.h"#include "sttbx.h"#include "diskpart.h"#include "hal.h"/* Private Types ----------------------------------------------------------- *//* Private Constants ------------------------------------------------------- *//* Private Variables ------------------------------------------------------- */static char Buffer[DISK_SECTOR_SIZE];static BOOL InitialisedLock = FALSE;static semaphore_t PartTableLock; /* This locks access to the partition table on disk */ /* This does not protect against other drivers *//* Private Macros ---------------------------------------------------------- *//* Private Function Prototypes --------------------------------------------- */static void AquireTheLock (void);/* Functions --------------------------------------------------------------- *//******************************************************************************Function Name : stavfs_ReadPartitionTable Description : Reads the partition table from disk (1st sector) and returns the entry corresponding to the device passed. Parameters :******************************************************************************/ST_ErrorCode_t stavfs_ReadPartitionTable (stavfs_Device_t *Device_p, stavfs_DiskPartitionTable_t *PartitionInfo){ ST_ErrorCode_t Error = ST_NO_ERROR; char *TableOffset_p; U64 LBA64; /* Points to the first sector */ I64_SetValue(0, 0, LBA64); if ((0 > Device_p->Partition) || (Device_p->Partition > 3)) { STTBX_Print(("Bad partition number\n")); Error = ST_ERROR_BAD_PARAMETER; } else if (ST_NO_ERROR != (Error = stavfs_HalRead(Device_p->HALData, &LBA64, 1, Buffer, FALSE))) { STTBX_Print(("Unable to read the partition table.\n")); Error = STAVFS_ERROR_UNREADABLE_DISK; } /* Check the partition tables magic numbers */ else if ((Buffer[DISK_SECTOR_SIZE-2] != 0X55) || (Buffer[DISK_SECTOR_SIZE-1] != 0XAA)) { /* Invalid partition table */ Error = STAVFS_ERROR_IN_PARTITION; STTBX_Print(("Invalid partition table\n")); } else { /* Sets up the TableOffset pointer point to the start place for a particular partition entry in the buffer */ TableOffset_p = Buffer + BOOT_LOADER_SIZE + (16 * Device_p->Partition); /* Copies the relevent buffer section to the partions table */ memcpy((unsigned char *) PartitionInfo, (unsigned char *) TableOffset_p, sizeof(stavfs_DiskPartitionTable_t)); } return (ST_NO_ERROR);}/******************************************************************************Function Name : stavfs_WritePartitionTable Description : Reads the partition table from disk (1st sector) and writes the entry corresponding to the device passed. Parameters :******************************************************************************/ST_ErrorCode_t stavfs_WritePartitionTable (stavfs_Device_t *Device_p, stavfs_DiskPartitionTable_t *PartitionInfo){ ST_ErrorCode_t Error = ST_NO_ERROR; char *TableOffset_p; U64 LBA64; /* Points to the first sector */ I64_SetValue(0, 0, LBA64); AquireTheLock (); if ((0 > Device_p->Partition) || (Device_p->Partition > 3)) { STTBX_Print(("Bad partition number\n")); Error = ST_ERROR_BAD_PARAMETER; } else if (ST_NO_ERROR != (Error = stavfs_HalRead(Device_p->HALData, &LBA64, 1, Buffer, FALSE))) { STTBX_Print(("Unable to read the partition table.\n")); Error = STAVFS_ERROR_UNREADABLE_DISK; } /* Check the partition tables magic numbers */ else if ((Buffer[DISK_SECTOR_SIZE-2] != 0X55) || (Buffer[DISK_SECTOR_SIZE-1] != 0XAA)) { /* Invalid partition table */ Error = STAVFS_ERROR_IN_PARTITION; STTBX_Print(("Invalid partition table\n")); } else { /* Sets up the TableOffset pointer point to the start place for a particular partition entry in the buffer */ TableOffset_p = Buffer + BOOT_LOADER_SIZE + (16 * Device_p->Partition); /* Copies the partition info into relevent buffer section */ memcpy((unsigned char *) TableOffset_p, (unsigned char *) PartitionInfo, sizeof(stavfs_DiskPartitionTable_t)); if (ST_NO_ERROR != (Error = stavfs_HalWrite(Device_p->HALData, &LBA64, 1, Buffer, FALSE))) { STTBX_Print(("Unable to write the partition table.\n")); Error = STAVFS_ERROR_UNWRITABLE_DISK; } } semaphore_signal (&(PartTableLock)); return (ST_NO_ERROR);}/******************************************************************************Function Name : stavfs_SetThePartitionEntry Description : Mark the indicated partition as in use, with the given position and size Parameters :******************************************************************************/ST_ErrorCode_t stavfs_SetThePartitionEntry(stavfs_Device_t *Device_p, U64 const *Position_p, U64 *SpaceInSectors_p){ ST_ErrorCode_t Error = ST_NO_ERROR; stavfs_DiskPartitionTable_t PartitionTable[NUM_OF_PARTITIONS]; /* Sets up the TableOffset pointer to ignore the boot loader section of the first sector */ char *TableOffset_p = Buffer + BOOT_LOADER_SIZE; U64 LBA64; int j; /* Points to the first sector */ I64_SetValue (0, 0, LBA64); /* Read the existing partition table in */ AquireTheLock (); if ((0 > Device_p->Partition) || (Device_p->Partition > 3)) { STTBX_Print(("Bad partition number\n")); Error = ST_ERROR_BAD_PARAMETER; } else if (ST_NO_ERROR != stavfs_HalRead (Device_p->HALData, &LBA64, 1, Buffer, FALSE)) { STTBX_Print (("Unable to read the partition table\n")); Error = STAVFS_ERROR_UNREADABLE_DISK; } /* Check the partition tables magic numbers */ else if ((Buffer[DISK_SECTOR_SIZE-2] != 0X55) || (Buffer[DISK_SECTOR_SIZE-1] != 0XAA)) { /* Invalid partition table */ Error = STAVFS_ERROR_IN_PARTITION; STTBX_Print(("Invalid partition table\n")); } else { U64 DiskSize; U64 MaxPosn; U64 MinPosn; /* Reserve the first two sectors */ I64_SetValue(2, 0, MinPosn); /* Get the disk size */ if (ST_NO_ERROR != (Error = stavfs_HalDiskSize(Device_p->HALData, &DiskSize))) { STTBX_Print (("Can't get the disk size\n")); Error = STAVFS_ERROR_UNREADABLE_DISK; } /* Check the partition is in the disk */ else if (I64_IsLessThan(DiskSize, *Position_p) || I64_IsLessThan(*Position_p, MinPosn)) { STTBX_Print (("Start position for new partition (%d) is out-of-range for this disk\n", Device_p->Partition)); Error = ST_ERROR_BAD_PARAMETER; } else { /* Sets up the TableOffset pointer to ignore the boot loader section of the first sector */ /* Resize the position to fit into the disk. */ I64_Add(*Position_p, *SpaceInSectors_p, MaxPosn); if (I64_IsLessThan(DiskSize, MaxPosn)) { STTBX_Print(("Shrinking new partition (%d) to fit within the disk size\n", Device_p->Partition)); I64_Sub(DiskSize, *Position_p, *SpaceInSectors_p); } /* Copy the relevent buffer section to the partition table */ memcpy ((unsigned char *) PartitionTable, (unsigned char *) TableOffset_p, sizeof (PartitionTable)); /* Check for overlapping with an existing partition */ for (j = 0; j < NUM_OF_PARTITIONS; j++) { if ((PartitionTable[j].Type != 0x00) && (Device_p->Partition != j)) { if ((Position_p->LSW < PartitionTable[j].StartLBA + PartitionTable[j].SizeLBA) && (PartitionTable[j].StartLBA < Position_p->LSW + SpaceInSectors_p->LSW)) { STTBX_Print (("New partition (%d) space overlaps with partition %d\n", Device_p->Partition,j)); Error = ST_ERROR_BAD_PARAMETER; } } } } if (Error == ST_NO_ERROR) { int Partition = Device_p->Partition; /* Set the partition table up as required */ PartitionTable[Partition].Active = 0X00; /* Active flag */ PartitionTable[Partition].StartCHS[0] = 0; PartitionTable[Partition].StartCHS[1] = 0; PartitionTable[Partition].StartCHS[2] = 0; PartitionTable[Partition].Type = AVFS_PARTITION; /* Partition type */ PartitionTable[Partition].SizeCHS[0] = 0; PartitionTable[Partition].SizeCHS[1] = 0; PartitionTable[Partition].SizeCHS[2] = 0; PartitionTable[Partition].StartLBA = Position_p->LSW; PartitionTable[Partition].SizeLBA = SpaceInSectors_p->LSW; /* Set the magic numbers */ Buffer[DISK_SECTOR_SIZE-2] = 0X55; Buffer[DISK_SECTOR_SIZE-1] = 0XAA; /* Copy the partition table back to the buffer and onto the disk */ memcpy ((unsigned char *) TableOffset_p, (unsigned char *) PartitionTable, sizeof (PartitionTable)); if (ST_NO_ERROR != stavfs_HalWrite (Device_p->HALData, &LBA64, 1, Buffer, FALSE)) { STTBX_Print (("Unable to write the partition table\n")); Error = STAVFS_ERROR_UNWRITABLE_DISK; } } } semaphore_signal (&(PartTableLock)); return (Error);}/******************************************************************************Function Name : AquireTheLock Description : Aquire the access lock, or create it if this is the first call Parameters :******************************************************************************/static void AquireTheLock (){ task_lock (); if (InitialisedLock) { task_unlock (); semaphore_wait (&(PartTableLock)); } else { /* Initialise the re-entrant lock semaphore */ InitialisedLock = TRUE; semaphore_init_fifo (&(PartTableLock), 0); task_unlock (); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -