Add partition table support
This commit is contained in:
parent
f81a515514
commit
2cfa67b8e2
5
Makefile
5
Makefile
@ -34,8 +34,9 @@ fd.iso: kernel
|
|||||||
@printf "menuentry \"myos\" {\n\tmultiboot /boot/kernel\n}" > isodir/boot/grub/grub.cfg
|
@printf "menuentry \"myos\" {\n\tmultiboot /boot/kernel\n}" > isodir/boot/grub/grub.cfg
|
||||||
grub-mkrescue -o $@ isodir
|
grub-mkrescue -o $@ isodir
|
||||||
|
|
||||||
disk.img:
|
disk.img: disk.sfdisk
|
||||||
qemu-img create -f qcow2 disk.img 32M
|
qemu-img create -f raw $@ 32M
|
||||||
|
sfdisk $@ < disk.sfdisk
|
||||||
|
|
||||||
%.o:%.asm
|
%.o:%.asm
|
||||||
$(AS) $(ASFLAGS) -o $@ $<
|
$(AS) $(ASFLAGS) -o $@ $<
|
||||||
|
13
README.md
13
README.md
@ -10,6 +10,7 @@ To generate iso image
|
|||||||
|
|
||||||
* `mtools xorriso (which is libisoburn on ArchLinux)`
|
* `mtools xorriso (which is libisoburn on ArchLinux)`
|
||||||
* gcc >= 6
|
* gcc >= 6
|
||||||
|
* sfdisk (util-linux)
|
||||||
|
|
||||||
# Run it
|
# Run it
|
||||||
|
|
||||||
@ -34,6 +35,17 @@ Then you can check some matos specific commands or pretty printing with
|
|||||||
`help user-defined`
|
`help user-defined`
|
||||||
`info pretty-printer` (Should contains matos_pretty_printers)
|
`info pretty-printer` (Should contains matos_pretty_printers)
|
||||||
|
|
||||||
|
# Change Disk partition
|
||||||
|
|
||||||
|
You can either modify the disk.sfdisk file
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
modify the disk image woth your favorit tool (e.g. gparted) and re-generate disk.sfdisk
|
||||||
|
|
||||||
|
sfdisk -d > disk.sfdisk
|
||||||
|
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
|
|
||||||
* VGA Driver
|
* VGA Driver
|
||||||
@ -45,3 +57,4 @@ Then you can check some matos specific commands or pretty printing with
|
|||||||
* Multithread (Full preempt)
|
* Multithread (Full preempt)
|
||||||
* Mutex
|
* Mutex
|
||||||
* ATA
|
* ATA
|
||||||
|
* basic userspace with syscall
|
||||||
|
@ -16,11 +16,11 @@ class KthreadPrettyPrinter(object):
|
|||||||
line = gdb.execute(cmdline, to_string=True)
|
line = gdb.execute(cmdline, to_string=True)
|
||||||
#line = gdb.find_pc_line(int(cpuState["eip"].cast(gdb.lookup_type("long").pointer()).referenced_value()))
|
#line = gdb.find_pc_line(int(cpuState["eip"].cast(gdb.lookup_type("long").pointer()).referenced_value()))
|
||||||
currentThread = gdb.parse_and_eval("currentThread")
|
currentThread = gdb.parse_and_eval("currentThread")
|
||||||
if self.val == currentThread:
|
if self.val.address == currentThread:
|
||||||
result += "->"
|
result += "->"
|
||||||
else:
|
else:
|
||||||
result += " "
|
result += " "
|
||||||
result += "Addr: 0x%x, name: %s, state: %s, PC: %s" % (self.val, name, state, line)
|
result += "Addr: 0x%x, name: %s, state: %s, PC: %s" % (self.val.address, name, state, line)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
9
disk.sfdisk
Normal file
9
disk.sfdisk
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
label: dos
|
||||||
|
label-id: 0x9ec19bcc
|
||||||
|
device: disk.img
|
||||||
|
unit: sectors
|
||||||
|
sector-size: 512
|
||||||
|
|
||||||
|
disk.img1 : start= 2048, size= 10240, type=83
|
||||||
|
disk.img2 : start= 12288, size= 10240, type=b
|
||||||
|
disk.img3 : start= 22528, size= 43008, type=e
|
112
drivers/ata.c
112
drivers/ata.c
@ -1,9 +1,17 @@
|
|||||||
|
#include "alloc.h"
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "irq.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
|
#include "list.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
|
#define PART_TABLE_OFFSET 0x1BE
|
||||||
|
|
||||||
|
static struct ata_partition *partitions;
|
||||||
|
static int nextPartitionId = 0;
|
||||||
|
|
||||||
// from
|
// from
|
||||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ata/ns-ata-_identify_device_data
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ata/ns-ata-_identify_device_data
|
||||||
struct _IDENTIFY_DEVICE_DATA {
|
struct _IDENTIFY_DEVICE_DATA {
|
||||||
@ -378,6 +386,19 @@ struct _IDENTIFY_DEVICE_DATA {
|
|||||||
uint16_t CheckSum : 8;
|
uint16_t CheckSum : 8;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct part_table_entry{
|
||||||
|
uint32_t status:8;
|
||||||
|
uint32_t head_start:8;
|
||||||
|
uint32_t sector_start:6;
|
||||||
|
uint32_t cyl_start:10;
|
||||||
|
uint32_t type:8;
|
||||||
|
uint32_t head_end:8;
|
||||||
|
uint32_t sector_end:6;
|
||||||
|
uint32_t cyl_end:10;
|
||||||
|
uint32_t lba;
|
||||||
|
uint32_t size;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
static struct ata_controller controllers[MAX_ATA_CONTROLLER] = {{
|
static struct ata_controller controllers[MAX_ATA_CONTROLLER] = {{
|
||||||
.id = 0,
|
.id = 0,
|
||||||
.base = 0x1F0,
|
.base = 0x1F0,
|
||||||
@ -455,8 +476,91 @@ int ATAGetDeviceInfo(struct ata_device *dev)
|
|||||||
dev->sectors = deviceInfo->NumSectorsPerTrack;
|
dev->sectors = deviceInfo->NumSectorsPerTrack;
|
||||||
printf("Disk Detected[%d][%d]: %d Ko\n", ctl->id, dev->id,
|
printf("Disk Detected[%d][%d]: %d Ko\n", ctl->id, dev->id,
|
||||||
(dev->heads * dev->cyls * dev->sectors * DISK_SECTOR_SIZE) / 1024);
|
(dev->heads * dev->cyls * dev->sectors * DISK_SECTOR_SIZE) / 1024);
|
||||||
|
ATAReadPartition(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
const char *partTypeToStr(unsigned int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case PART_TYPE_EXTENDED:
|
||||||
|
return "Extended";
|
||||||
|
case PART_TYPE_FAT16:
|
||||||
|
case PART_TYPE_FAT16_LBA:
|
||||||
|
return "FAT16";
|
||||||
|
case PART_TYPE_FAT32:
|
||||||
|
case PART_TYPE_FAT32_LBA:
|
||||||
|
return "FAT32";
|
||||||
|
case PART_TYPE_LINUX_SWAP:
|
||||||
|
return "Linux Swap";
|
||||||
|
case PART_TYPE_LINUX:
|
||||||
|
return "Linux";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ata_partition *ATAGetPartition(int id)
|
||||||
|
{
|
||||||
|
struct ata_partition *part;
|
||||||
|
int count;
|
||||||
|
list_foreach(partitions, part, count)
|
||||||
|
{
|
||||||
|
if (part->id == id)
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ata_partition *ATAPartitionCreate(uint type, uint size, uint32_t lba,
|
||||||
|
struct ata_device *dev)
|
||||||
|
{
|
||||||
|
struct ata_partition *part =
|
||||||
|
(struct ata_partition *)malloc(sizeof(struct ata_partition));
|
||||||
|
if (part == NULL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
part->id = nextPartitionId++;
|
||||||
|
part->type = type;
|
||||||
|
part->size = size;
|
||||||
|
part->lba = lba;
|
||||||
|
part->device = dev;
|
||||||
|
|
||||||
|
uint32_t flags;
|
||||||
|
disable_IRQs(flags);
|
||||||
|
|
||||||
|
list_add_tail(partitions, part);
|
||||||
|
restore_IRQs(flags);
|
||||||
|
|
||||||
|
err:
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ATAReadPartition(struct ata_device *dev)
|
||||||
|
{
|
||||||
|
char buf[DISK_SECTOR_SIZE];
|
||||||
|
int ret = ATAReadSector(dev, 0, 1, buf);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
struct part_table_entry *parts = (struct part_table_entry *)(buf + PART_TABLE_OFFSET);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (parts[i].size == 0)
|
||||||
|
continue;
|
||||||
|
if (parts[i].type == PART_TYPE_EXTENDED) {
|
||||||
|
printf("Unsupported Partition extended\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("Got partition %d type %s(0x%x) size %d kb lba 0x%x\n", i,
|
||||||
|
partTypeToStr(parts[i].type), parts[i].type, (parts[i].size * DISK_SECTOR_SIZE) >> 10, parts[i].lba);
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int ATADetectController(struct ata_controller *controller)
|
int ATADetectController(struct ata_controller *controller)
|
||||||
{
|
{
|
||||||
@ -488,12 +592,20 @@ int ATADetectController(struct ata_controller *controller)
|
|||||||
|
|
||||||
int ATAInit()
|
int ATAInit()
|
||||||
{
|
{
|
||||||
|
list_init(partitions);
|
||||||
for (uint i = 0; i < MAX_ATA_CONTROLLER; i++) {
|
for (uint i = 0; i < MAX_ATA_CONTROLLER; i++) {
|
||||||
ATADetectController(&controllers[i]);
|
ATADetectController(&controllers[i]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ATAReadPartitionSector(struct ata_partition *part, int offset, uint nbSector, void *buf)
|
||||||
|
{
|
||||||
|
int lba = part->lba + offset;
|
||||||
|
|
||||||
|
return ATAReadSector(part->device, lba, nbSector, buf);
|
||||||
|
}
|
||||||
|
|
||||||
int ATAReadSector(struct ata_device *dev, int lba, uint nb_sector, void *buf)
|
int ATAReadSector(struct ata_device *dev, int lba, uint nb_sector, void *buf)
|
||||||
{
|
{
|
||||||
struct ata_controller *ctl = dev->ctl;
|
struct ata_controller *ctl = dev->ctl;
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#define ATA_PIO_DRIVE_MASTER 0x00 /* select master */
|
#define ATA_PIO_DRIVE_MASTER 0x00 /* select master */
|
||||||
#define ATA_PIO_DRIVE_SLAVE 0x10 /* select slave */
|
#define ATA_PIO_DRIVE_SLAVE 0x10 /* select slave */
|
||||||
|
|
||||||
|
|
||||||
#define ATA_PIO_ERROR_ADDR_MARK_NOT_FOUND 0
|
#define ATA_PIO_ERROR_ADDR_MARK_NOT_FOUND 0
|
||||||
#define ATA_PIO_ERROR_TRACK_ZERO_NOT_FOUND 1
|
#define ATA_PIO_ERROR_TRACK_ZERO_NOT_FOUND 1
|
||||||
#define ATA_PIO_ERROR_ABORTED 2
|
#define ATA_PIO_ERROR_ABORTED 2
|
||||||
@ -55,6 +54,14 @@
|
|||||||
|
|
||||||
#define DISK_SECTOR_SIZE 512
|
#define DISK_SECTOR_SIZE 512
|
||||||
|
|
||||||
|
#define PART_TYPE_EXTENDED 0x5
|
||||||
|
#define PART_TYPE_FAT16 0x6
|
||||||
|
#define PART_TYPE_FAT16_LBA 0xe
|
||||||
|
#define PART_TYPE_FAT32 0xb
|
||||||
|
#define PART_TYPE_FAT32_LBA 0xc
|
||||||
|
#define PART_TYPE_LINUX_SWAP 0x82
|
||||||
|
#define PART_TYPE_LINUX 0x83
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ATA_DEV_UNKNOWN,
|
ATA_DEV_UNKNOWN,
|
||||||
ATA_DEV_PATA,
|
ATA_DEV_PATA,
|
||||||
@ -83,7 +90,19 @@ struct ata_controller {
|
|||||||
int last_device_used;
|
int last_device_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ata_partition {
|
||||||
|
int id;
|
||||||
|
uint type;
|
||||||
|
uint size;
|
||||||
|
uint32_t lba;
|
||||||
|
struct ata_device *device;
|
||||||
|
struct ata_partition *prev, *next;
|
||||||
|
};
|
||||||
|
|
||||||
int ATAInit();
|
int ATAInit();
|
||||||
|
int ATAReadPartitionSector(struct ata_partition *part, int offset, uint nbSector, void *buf);
|
||||||
int ATAReadSector(struct ata_device *dev, int lba, uint nbSector, void *buf);
|
int ATAReadSector(struct ata_device *dev, int lba, uint nbSector, void *buf);
|
||||||
int ATAWriteSector(struct ata_device *dev, int lba, uint nbSector, void *buf);
|
int ATAWriteSector(struct ata_device *dev, int lba, uint nbSector, void *buf);
|
||||||
struct ata_device *ATAGetDevice(int ctlId, int devId);
|
struct ata_device *ATAGetDevice(int ctlId, int devId);
|
||||||
|
int ATAReadPartition(struct ata_device *dev);
|
||||||
|
struct ata_partition *ATAGetPartition(int id);
|
||||||
|
Loading…
Reference in New Issue
Block a user