Browse Source

Add partition table support

pull/5/head
Mathieu Maret 4 weeks ago
parent
commit
2cfa67b8e2
  1. 5
      Makefile
  2. 13
      README.md
  3. 4
      custom_gdb_extension.py
  4. 9
      disk.sfdisk
  5. 112
      drivers/ata.c
  6. 31
      drivers/ata.h

5
Makefile

@ -34,8 +34,9 @@ fd.iso: kernel
@printf "menuentry \"myos\" {\n\tmultiboot /boot/kernel\n}" > isodir/boot/grub/grub.cfg
grub-mkrescue -o $@ isodir
disk.img:
qemu-img create -f qcow2 disk.img 32M
disk.img: disk.sfdisk
qemu-img create -f raw $@ 32M
sfdisk $@ < disk.sfdisk
%.o:%.asm
$(AS) $(ASFLAGS) -o $@ $<

13
README.md

@ -10,6 +10,7 @@ To generate iso image
* `mtools xorriso (which is libisoburn on ArchLinux)`
* gcc >= 6
* sfdisk (util-linux)
# Run it
@ -34,6 +35,17 @@ Then you can check some matos specific commands or pretty printing with
`help user-defined`
`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
* VGA Driver
@ -45,3 +57,4 @@ Then you can check some matos specific commands or pretty printing with
* Multithread (Full preempt)
* Mutex
* ATA
* basic userspace with syscall

4
custom_gdb_extension.py

@ -16,11 +16,11 @@ class KthreadPrettyPrinter(object):
line = gdb.execute(cmdline, to_string=True)
#line = gdb.find_pc_line(int(cpuState["eip"].cast(gdb.lookup_type("long").pointer()).referenced_value()))
currentThread = gdb.parse_and_eval("currentThread")
if self.val == currentThread:
if self.val.address == currentThread:
result += "->"
else:
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

9
disk.sfdisk

@ -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

@ -1,9 +1,17 @@
#include "alloc.h"
#include "ata.h"
#include "io.h"
#include "irq.h"
#include "kernel.h"
#include "klibc.h"
#include "list.h"
#include "thread.h"
#define PART_TABLE_OFFSET 0x1BE
static struct ata_partition *partitions;
static int nextPartitionId = 0;
// from
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ata/ns-ata-_identify_device_data
struct _IDENTIFY_DEVICE_DATA {
@ -378,6 +386,19 @@ struct _IDENTIFY_DEVICE_DATA {
uint16_t CheckSum : 8;
} __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] = {{
.id = 0,
.base = 0x1F0,
@ -455,8 +476,91 @@ int ATAGetDeviceInfo(struct ata_device *dev)
dev->sectors = deviceInfo->NumSectorsPerTrack;
printf("Disk Detected[%d][%d]: %d Ko\n", ctl->id, dev->id,
(dev->heads * dev->cyls * dev->sectors * DISK_SECTOR_SIZE) / 1024);
ATAReadPartition(dev);
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)
{
@ -488,12 +592,20 @@ int ATADetectController(struct ata_controller *controller)
int ATAInit()
{
list_init(partitions);
for (uint i = 0; i < MAX_ATA_CONTROLLER; i++) {
ATADetectController(&controllers[i]);
}
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)
{
struct ata_controller *ctl = dev->ctl;

31
drivers/ata.h

@ -17,7 +17,7 @@
// cmd details
// https://people.freebsd.org/~imp/asiabsdcon2015/works/d2161r5-ATAATAPI_Command_Set_-_3.pdf
#define ATA_PIO_CMD_IDENTIFY 0xEC /* get ATA params */
#define ATA_PIO_CMD_IDENTIFY 0xEC /* get ATA params */
#define ATA_PIO_CMD_ATAPI_IDENTIFY 0xA1 /* get ATAPI params*/
#define ATA_PIO_CMD_READ 0x20 /* read command */
#define ATA_PIO_CMD_WRITE 0x30 /* write command */
@ -26,11 +26,10 @@
#define ATA_PIO_CMD_SET_MULTI 0xC6 /* set multi size command */
#define ATA_PIO_CMD_PACKET_CMD 0xA0 /* set multi size command */
#define ATA_PIO_DRIVE_IBM 0xA0 /* bits that must be set */
#define ATA_PIO_DRIVE_LBA 0x40 /* use LBA ? */
#define ATA_PIO_DRIVE_MASTER 0x00 /* select master */
#define ATA_PIO_DRIVE_SLAVE 0x10 /* select slave */
#define ATA_PIO_DRIVE_IBM 0xA0 /* bits that must be set */
#define ATA_PIO_DRIVE_LBA 0x40 /* use LBA ? */
#define ATA_PIO_DRIVE_MASTER 0x00 /* select master */
#define ATA_PIO_DRIVE_SLAVE 0x10 /* select slave */
#define ATA_PIO_ERROR_ADDR_MARK_NOT_FOUND 0
#define ATA_PIO_ERROR_TRACK_ZERO_NOT_FOUND 1
@ -55,6 +54,14 @@
#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 {
ATA_DEV_UNKNOWN,
ATA_DEV_PATA,
@ -83,7 +90,19 @@ struct ata_controller {
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 ATAReadPartitionSector(struct ata_partition *part, int offset, 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);
struct ata_device *ATAGetDevice(int ctlId, int devId);
int ATAReadPartition(struct ata_device *dev);
struct ata_partition *ATAGetPartition(int id);

Loading…
Cancel
Save