*--------------------------------------------------------------------------
*/
#include <fs.h>
+#include <ide.h>
#include <printk.h>
#include <stdlib.h>
#include <string.h>
printk("cmdline: %s\n", system.cmdline);
get_value("root", value);
- assert(value[0] == 'h' && value[1] == 'd' && value[2] == 'a');
- system.root_dev = MAKE_DEV(DEV_MAJOR_HDA, atoi(value + 3));
+
+ assert(strlen(value) >= 4);
+
+ assert(value[0] == 'h' && value[1] == 'd');
+ assert(value[2] >= 'a' && value[2] <= 'd');
+
+ int disk_drv_no = value[2] - 'a';
+
+ uint32_t part_no = atoi(value + 3);
+ assert(part_no >= 1);
+
+ system.root_dev = MAKE_DISK_DEV(disk_drv_no, part_no);
printk("root device %s [0x%08x]\n", value, system.root_dev);
get_value("delay", value);
buf[i] = 0;
}
-void ata_read_partions(ide_part_t *part, const char *buf) {
- int offset = PARTITION_TABLE_OFFSET;
- const char *p = buf + offset;
-
- for (int i = 0; i < 4; i++) {
- part->flags = (uint8_t)p[0];
- part->type = (uint8_t)p[4];
- part->lba_start = *((uint32_t *)(p + 8));
- uint32_t size = *((uint32_t *)(p + 12));
- part->lba_end = part->lba_start + size;
-
- printk("part[%d] %02X %02X %u %u\n", i, part->flags, part->type, part->lba_start,
- part->lba_end == 0 ? 0 : part->lba_end - 1);
-
- // 这里应该再判断一下part->flags,如果是扩展分区还需要再读取
- // 先这样实现
-
- p += 16; // 每个分区16个字节
- part++;
- }
-}
-
// 《AT Attachment 8 - ATA/ATAPI Command Set》
void ide_ata_init() {
for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) {
// 1~4代表各个主分区
// 5~15 代表各个逻辑分区
drv->partions[0].flags = 0x00;
+ drv->partions[0].type = 0x00;
drv->partions[0].lba_start = 0;
drv->partions[0].lba_end = drv->max_lba;
}
disk_request_t r;
char *sect = kmalloc(SECT_SIZE, 0);
- r.dev = MAKE_DEV(DEV_MAJOR_IDE0 + (drv->drv_no >> 1), drv->drv_no % 2);
+
+ // part_no == 0 代表整场硬盘
+ r.dev = MAKE_DISK_DEV(drv->drv_no, 0);
r.command = DISK_REQ_READ;
r.pos = base + offset_lba;
r.count = 1;
// MBR里的分区占据 [1,4]
part_id = 1;
} else {
- // 扩展分区里的逻辑分区占据 [5,MAX_IDE_PARTIONS)
+ // 扩展分区里的逻辑分区占据 [5,MAX_DISK_PARTIONS)
part_id = 5 + depth - 1;
}
const char *p = sect + PARTITION_TABLE_OFFSET;
for (int i = 0; i < 4; i++) {
- if (part_id >= MAX_IDE_PARTIONS) {
+ if (part_id >= MAX_DISK_PARTIONS) {
break;
}
part = drv->partions + part_id;
ext_lba = ext_lba != 0 ? ext_lba : part->lba_start;
read_partition_table(drv, ext_lba, part->lba_start, depth + 1);
} else {
- printk("part[%d] %02X %u %u\n", part_id + drv->drv_no * MAX_IDE_PARTIONS, part->type, part->lba_start,
+ printk("part[%d] %02X %u %u\n", part_id + drv->drv_no * MAX_DISK_PARTIONS, part->type, part->lba_start,
size);
}
// return st;
// }
+
+// void ata_read_partions(ide_part_t *part, const char *buf) {
+// int offset = PARTITION_TABLE_OFFSET;
+// const char *p = buf + offset;
+
+// for (int i = 0; i < 4; i++) {
+// part->flags = (uint8_t)p[0];
+// part->type = (uint8_t)p[4];
+// part->lba_start = *((uint32_t *)(p + 8));
+// uint32_t size = *((uint32_t *)(p + 12));
+// part->lba_end = part->lba_start + size;
+
+// printk("part[%d] %02X %02X %u %u\n", i, part->flags, part->type, part->lba_start,
+// part->lba_end == 0 ? 0 : part->lba_end - 1);
+
+// // 这里应该再判断一下part->flags,如果是扩展分区还需要再读取
+// // 先这样实现
+
+// p += 16; // 每个分区16个字节
+// part++;
+// }
+// }
blk_buffer_t *block_read(dev_t dev, uint32_t block) {
blk_buffer_t *bb = 0;
- assert(DEV_MAJOR(dev) == DEV_MAJOR_IDE0);
+ assert(DEV_MAJOR(dev) == DEV_MAJOR_DISK);
assert(DEV_MINOR(dev) == 1);
// 目前不提供hash表组强起来的缓冲功能
const int size = offset + 1024;
const int block = 1;
- blk_buffer_t *bb = block_read(MAKE_DEV(DEV_MAJOR_IDE0, 1), block);
+ blk_buffer_t *bb = block_read(system.root_dev, block);
ext2_sb_t *p = (ext2_sb_t *)(bb->data + offset);
printk("inodes count %u inodes per group %u free %u\n", p->s_inodes_count, p->s_inodes_per_group,
ide_drive_t *ide_get_drive(dev_t dev) {
int major = DEV_MAJOR(dev);
int minor = DEV_MINOR(dev);
- assert(major == DEV_MAJOR_IDE0 || major == DEV_MAJOR_IDE1);
- assert(minor < MAX_IDE_PARTIONS * 2); // 因为一个通道有两个硬盘,每个硬盘最大MAX_IDE_PARTIONS分区
- int channel = major == DEV_MAJOR_IDE0 ? 0 : 1;
- int index = minor / MAX_IDE_PARTIONS;
+ int drv_no = minor / MAX_DISK_PARTIONS;
- int drv_no = channel * 2 + index;
+ assert(major == DEV_MAJOR_DISK);
+ assert(minor >= 0);
+ assert(drv_no < MAX_IDE_DRIVE_CNT);
ide_drive_t *drv = ide_drives + drv_no;
// #define PARTITION_CNT 4
#define PARTITION_TABLE_OFFSET 0x1BE
-#define MAX_IDE_PARTIONS 16
+#define MAX_DISK_PARTIONS 16
+
+#define MAKE_DISK_DEV(drv_no, part_no) MAKE_DEV(DEV_MAJOR_DISK, (drv_no)*MAX_DISK_PARTIONS + (part_no))
// 分区定义
typedef struct ide_part_ {
ide_pci_controller_t *ide_pci_controller;
- ide_part_t partions[MAX_IDE_PARTIONS];
+ ide_part_t partions[MAX_DISK_PARTIONS];
} ide_drive_t;
#define MAX_IDE_DRIVE_CNT 4
-# kill qemu on gdb exit
-#define hook-quit
-# kill
-#end
+# 避免退出gdb时二次确认
+set confirm off
#b *0x7c00
#define DEV_MAJOR_UNUSED 0x0000
#define DEV_MAJOR_MEM 0x0001
#define DEV_MAJOR_TTY 0x0002
-#define DEV_MAJOR_IDE0 0x0003
-#define DEV_MAJOR_HDA DEV_MAJOR_IDE0
+#define DEV_MAJOR_DISK 0x0003
+// #define DEV_MAJOR_IDE0 0x0003
+// #define DEV_MAJOR_HDA DEV_MAJOR_IDE0
#define DEV_MAJOR_IDE1 0x0004
#define DEV_MAJOR_SCSI0 0x0005
#define DEV_MAJOR_SCSI2 0x0006
task_union *next = sel != 0 ? sel : root;
next->state = TASK_RUNNING;
+ next->reason = "";
if (prev != next) {
next->sched_cnt++;
boot_delay(DEFAULT_BOOT_DELAY_TICKS);
extern tty_t *const monitor_tty;
- // tty_switch(monitor_tty);
+ tty_switch(monitor_tty);
boot_delay(DEFAULT_BOOT_DELAY_TICKS);
asm("hlt;");
}
- // printk("wait request for hard disk %d\n", drv_no);
+ // printk("wait request for hard disk channel %d\n", channel);
down(&ide_ctrl->request_queue.sem);
- // printk("hard disk %d\n", drv_no);
+ // printk("hard disk channel %d\n", channel);
mutex_lock(&ide_ctrl->request_mutex);
disk_request_t *r;
atomic_inc(&ide_ctrl->consumed_cnt);
mutex_unlock(&ide_ctrl->request_mutex);
- // TODO dev -> drv
ide_drive_t *drv = ide_get_drive(r->dev);
int drv_no = drv->drv_no;
if (drv->present == 0) {
ata_dma_read_ext(drv_no, r->pos, r->count, r->buf);
break;
default:
+ panic("invalid disk request command");
break;
}
// 等待硬盘中断
- printk("down ide req\n");
+ // printk("down ide req\n");
down(&ide_ctrl->disk_intr_sem);
// 读数据
#include <disk.h>
#include <fcntl.h>
+#include <ide.h>
#include <io.h>
#include <irq.h>
#include <page.h>
memset(disk_buf1, 0, 512);
disk_request_t r;
- r.dev = 0;
+ r.dev = MAKE_DISK_DEV(0, 0);
r.command = DISK_REQ_READ;
r.pos = sect_nr;
r.count = 1;
r.buf = disk_buf1;
send_disk_request(&r);
- verify_hd_data(sect_nr, disk_buf1, current->name);
+ // verify_hd_data(sect_nr, disk_buf1, current->name);
for (int i = 0; i < 2; i++) {
asm("hlt;");
uint64_t sect_nr = get_next_deubug_sect_nr();
memset(disk_buf2, 0, 512);
disk_request_t r;
- r.dev = 2;
+ r.dev = MAKE_DISK_DEV(2, 0);
r.command = DISK_REQ_READ;
r.pos = sect_nr;
r.count = 1;
r.buf = disk_buf2;
send_disk_request(&r);
- verify_hd_data(sect_nr, disk_buf2, current->name);
+ // verify_hd_data(sect_nr, disk_buf2, current->name);
for (int i = 0; i < 1; i++) {
asm("hlt;");
// asm("hlt;");
// }
- // kernel_task("tskA", taskA_entry, NULL);
- // kernel_task("tskB", taskB_entry, NULL);
- // kernel_task("tskC", taskC_entry, NULL);
+#if 1
+ kernel_task("tskA", taskA_entry, NULL);
+ kernel_task("tskB", taskB_entry, NULL);
+ kernel_task("tskC", taskC_entry, NULL);
+#endif
current->priority = 1;
while (1) {
// 共享代码会利用保存在栈上的地址返回到sysexit_return_address处
"pushl $0;"
"pushl $0;"
- "movl $2, %%ebx;"
+ "movl $200, %%ebx;"
"pushl %%ebp;"
"movl %%esp, %%ebp;"
"sysenter;"
#insmod ext2
#set gfxpayload=1024x768x32
#insmod all_video
- multiboot2 /boot/Kernel root=hda0 delay=2
+ multiboot2 /boot/Kernel root=hda1 delay=2
boot
}