Handle disk partitioning
This commit is contained in:
15
kernel/diskpart/diskpart.c
Normal file
15
kernel/diskpart/diskpart.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "storedev/storedev.h"
|
||||
#include "mbr.h"
|
||||
#include "util/util.h"
|
||||
#include "kprintf.h"
|
||||
|
||||
void diskpart_init(void) {
|
||||
LOG("diskpart", "probing for disks with partitions\n");
|
||||
|
||||
StoreDev *sd, *sdtmp;
|
||||
LL_FOREACH_SAFE(STOREDEV_LIST.head, sd, sdtmp) {
|
||||
diskpart_mbr_probe(sd);
|
||||
}
|
||||
}
|
||||
6
kernel/diskpart/diskpart.h
Normal file
6
kernel/diskpart/diskpart.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef DISKPART_DISKPART_H_
|
||||
#define DISKPART_DISKPART_H_
|
||||
|
||||
void diskpart_init(void);
|
||||
|
||||
#endif // DISKPART_DISKPART_H_
|
||||
77
kernel/diskpart/mbr.c
Normal file
77
kernel/diskpart/mbr.c
Normal file
@ -0,0 +1,77 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "storedev/storedev.h"
|
||||
#include "mbr.h"
|
||||
#include "diskpart.h"
|
||||
#include "compiler/attr.h"
|
||||
#include "errors.h"
|
||||
#include "kprintf.h"
|
||||
#include "hal/hal.h"
|
||||
#include "util/util.h"
|
||||
#include "dev/dev.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t driveattrs;
|
||||
uint8_t chs_start_addr[3];
|
||||
uint8_t parttype;
|
||||
uint8_t chs_last_sect_addr[3];
|
||||
uint32_t startlba;
|
||||
uint32_t sectorcount;
|
||||
} PACKED PTE;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bootcode[440];
|
||||
uint8_t signature[4];
|
||||
uint8_t resv[2];
|
||||
PTE pte1;
|
||||
PTE pte2;
|
||||
PTE pte3;
|
||||
PTE pte4;
|
||||
uint8_t validsign[2];
|
||||
} PACKED MBR;
|
||||
|
||||
void diskpart_mbr_expose_partitions(StoreDev *sd, MBR *mbr) {
|
||||
PTE *parts[4] = { &mbr->pte1, &mbr->pte2, &mbr->pte3, &mbr->pte4 };
|
||||
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
char *name = NULL;
|
||||
spinlock_acquire(&DEVTABLE.spinlock);
|
||||
for (size_t i = 0; i < LEN(DEVTABLE.devs); i++) {
|
||||
Dev *dev = &DEVTABLE.devs[i];
|
||||
if (dev->extra == sd) {
|
||||
name = (char *)dev->ident;
|
||||
}
|
||||
}
|
||||
spinlock_release(&DEVTABLE.spinlock);
|
||||
|
||||
PartSdInitExtra extra = {
|
||||
.parent = sd,
|
||||
.sectorcount = parts[i]->sectorcount,
|
||||
.startsector = parts[i]->startlba,
|
||||
};
|
||||
|
||||
char name1[100];
|
||||
ksprintf(name1, "%s-part%zu", name, i+1);
|
||||
kprintf("%s\n", name1);
|
||||
storedev_create(STOREDEV_PARTSD, name1, &extra);
|
||||
}
|
||||
}
|
||||
|
||||
bool diskpart_mbr_probe(StoreDev *sd) {
|
||||
LOG("diskpart", "probing for MBR\n");
|
||||
|
||||
MBR mbr;
|
||||
hal_memset(&mbr, 0, sizeof(mbr));
|
||||
sd->read(sd, (uint8_t *const)&mbr, 0, 0, sizeof(mbr));
|
||||
|
||||
if (!(mbr.validsign[0] == 0x55 && mbr.validsign[1] == 0xAA)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("diskpart", "got valid MBR on %s\n", storedev_strings[sd->sdtype]);
|
||||
|
||||
diskpart_mbr_expose_partitions(sd, &mbr);
|
||||
|
||||
return true;
|
||||
}
|
||||
9
kernel/diskpart/mbr.h
Normal file
9
kernel/diskpart/mbr.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef DISKPART_MBR_H_
|
||||
#define DISKPART_MBR_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "storedev/storedev.h"
|
||||
|
||||
bool diskpart_mbr_probe(StoreDev *sd);
|
||||
|
||||
#endif // DISKPART_MBR_H_
|
||||
Reference in New Issue
Block a user