Ver Fonte

:new: 读取fat32文件系统的基础信息

fslongjin há 3 anos atrás
pai
commit
979bb35599

+ 5 - 2
kernel/Makefile

@@ -82,6 +82,9 @@ cpu.o: common/cpu.c
 softirq.o: exception/softirq.c
 	gcc $(CFLAGS) -c exception/softirq.c -o exception/softirq.o
 
+fat32.o: filesystem/fat32/fat32.c
+	gcc $(CFLAGS) -c filesystem/fat32/fat32.c -o filesystem/fat32/fat32.o
+
 # IPI的代码
 ifeq ($(ARCH), x86_64)
 OBJ_LIST += ipi.o
@@ -142,9 +145,9 @@ all: kernel
 	objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
 #
 
-kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o $(OBJ_LIST)
+kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o fat32.o $(OBJ_LIST)
 	ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \
-	common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o sched/sched.o	\
+	common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o sched/sched.o	filesystem/fat32/fat32.o \
 	driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o driver/timers/timer.o \
 	$(LD_LIST)	\
 	-T link.lds

+ 1 - 1
kernel/common/printk.h

@@ -21,7 +21,7 @@
 #define ORANGE 0x00ff8000 //橙
 #define YELLOW 0x00ffff00 //黄
 #define GREEN 0x0000ff00  //绿
-#define BLUE 0x000000ff   //蓝
+#define ORANGEBLUE 0x000000ff   //蓝
 #define INDIGO 0x0000ffff //靛
 #define PURPLE 0x008000ff //紫
 

+ 0 - 1
kernel/driver/disk/ahci/ahci.c

@@ -279,7 +279,6 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
         return E_PORT_HUNG;
     }
 
-    kdebug("slot=%d", slot);
     port->ci = 1 << slot; // Issue command
 
     sched_cfs();

+ 44 - 0
kernel/filesystem/MBR.h

@@ -0,0 +1,44 @@
+/**
+ * @file MBR.h
+ * @author fslongjin (longjin@RinGoTek.cn)
+ * @brief MBR分区表
+ * @version 0.1
+ * @date 2022-04-19
+ *
+ * @copyright Copyright (c) 2022
+ *
+ */
+#pragma once
+#include <common/glib.h>
+
+/**
+ * @brief MBR硬盘分区表项的结构
+ *
+ */
+struct MBR_disk_partition_table_entry_t
+{
+    uint8_t flags;                  // 引导标志符,标记此分区为活动分区
+    uint8_t starting_head;          // 起始磁头号
+    uint16_t starting_sector : 6, // 起始扇区号
+        starting_cylinder : 10;   // 起始柱面号
+    uint8_t type;   // 分区类型ID
+    uint8_t ending_head;    // 结束磁头号
+
+    uint16_t ending_sector:6,   // 结束扇区号
+                ending_cylinder:10; // 结束柱面号
+    
+    uint32_t starting_LBA;  // 起始逻辑扇区
+    uint32_t total_sectors; // 分区占用的磁盘扇区数
+
+}__attribute__((packed));
+
+/**
+ * @brief MBR磁盘分区表结构体
+ * 
+ */
+struct MBR_disk_partition_table_t
+{
+    uint8_t reserved[446];
+    struct MBR_disk_partition_table_entry_t DPTE[4];    // 磁盘分区表项
+    uint16_t BS_TrailSig;
+}__attribute__((packed));

+ 42 - 0
kernel/filesystem/fat32/fat32.c

@@ -0,0 +1,42 @@
+#include "fat32.h"
+#include <common/kprint.h>
+#include <driver/disk/ahci/ahci.h>
+
+/**
+ * @brief 读取指定磁盘上的第0个分区的fat32文件系统
+ * 
+ * @param disk_num 
+ */
+void fat32_FS_init(int disk_num)
+{
+    int i;
+    unsigned char buf[512];
+    struct MBR_disk_partition_table_t DPT;
+    struct fat32_BootSector_t fat32_bootsector;
+    struct fat32_FSInfo_t fat32_fsinfo;
+
+    memset(buf, 0, 512);
+    ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, 0, 1, (uint64_t)&buf, 0, 0);
+    DPT = *(struct MBR_disk_partition_table_t *)buf;
+    //	for(i = 0 ;i < 512 ; i++)
+    //		color_printk(PURPLE,WHITE,"%02x",buf[i]);
+    printk_color(ORANGE, BLACK, "DPTE[0] start_LBA:%#018lx\ttype:%#018lx\n", DPT.DPTE[0].starting_LBA, DPT.DPTE[0].type);
+
+    memset(buf, 0, 512);
+
+    ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, DPT.DPTE[0].starting_LBA, 1, (uint64_t)&buf, 0, 0);
+
+    fat32_bootsector = *(struct fat32_BootSector_t *)buf;
+    //	for(i = 0 ;i < 512 ; i++)
+    //		printk_color(PURPLE,WHITE,"%02x",buf[i]);
+    printk_color(ORANGE, BLACK, "FAT32 Boot Sector\n\tBPB_FSInfo:%#018lx\n\tBPB_BkBootSec:%#018lx\n\tBPB_TotSec32:%#018lx\n", fat32_bootsector.BPB_FSInfo, fat32_bootsector.BPB_BkBootSec, fat32_bootsector.BPB_TotSec32);
+
+    memset(buf, 0, 512);
+        ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, DPT.DPTE[0].starting_LBA+ fat32_bootsector.BPB_FSInfo, 1, (uint64_t)&buf, 0, 0);
+
+    
+    fat32_fsinfo = *(struct fat32_FSInfo_t *)buf;
+    //	for(i = 0 ;i < 512 ; i++)
+    //		printk_color(PURPLE,WHITE,"%02x",buf[i]);
+    printk_color(ORANGE, BLACK, "FAT32 FSInfo\n\tFSI_LeadSig:%#018lx\n\tFSI_StrucSig:%#018lx\n\tFSI_Free_Count:%#018lx\n", fat32_fsinfo.FSI_LeadSig, fat32_fsinfo.FSI_StrucSig, fat32_fsinfo.FSI_Free_Count);
+}

+ 77 - 0
kernel/filesystem/fat32/fat32.h

@@ -0,0 +1,77 @@
+/**
+ * @file fat32.h
+ * @author fslongjin (longjin@RinGoTek.cn)
+ * @brief fat32文件系统
+ * @version 0.1
+ * @date 2022-04-19
+ *
+ * @copyright Copyright (c) 2022
+ *
+ */
+
+#pragma once
+
+#include <filesystem/MBR.h>
+
+/**
+ * @brief fat32文件系统引导扇区结构体
+ *
+ */
+struct fat32_BootSector_t
+{
+    uint8_t BS_jmpBoot[3];    // 跳转指令
+    uint8_t BS_OEMName[8];    // 生产厂商名
+    uint16_t BPB_BytesPerSec; // 每扇区字节数
+    uint8_t BPB_SecPerClus;   // 每簇扇区数
+    uint16_t BPB_RsvdSecCnt;  // 保留扇区数
+    uint8_t BPB_NumFATs;      // FAT表数量
+    uint16_t BPB_RootEntCnt;  // 根目录文件数最大值
+    uint16_t BPB_TotSec16;    // 16位扇区总数
+    uint8_t BPB_Media;        // 介质描述符
+    uint16_t BPB_FATSz16;     // FAT12/16每FAT扇区数
+    uint16_t BPB_SecPerTrk;   // 每磁道扇区数
+    uint16_t BPB_NumHeads;    // 磁头数
+    uint32_t BPB_HiddSec;     // 隐藏扇区数
+    uint32_t BPB_TotSec32;    // 32位扇区总数
+
+    uint32_t BPB_FATSz32;   // FAT32每FAT扇区数
+    uint16_t BPB_ExtFlags;  // 扩展标志
+    uint16_t BPB_FSVer;     // 文件系统版本号
+    uint32_t BPB_RootClus;  // 根目录起始簇号
+    uint16_t BPB_FSInfo;    // FS info结构体的扇区号
+    uint16_t BPB_BkBootSec; // 引导扇区的备份扇区号
+    uint8_t BPB_Reserved0[12];
+
+    uint8_t BS_DrvNum; // int0x13的驱动器号
+    uint8_t BS_Reserved1;
+    uint8_t BS_BootSig;       // 扩展引导标记
+    uint32_t BS_VolID;        // 卷序列号
+    uint8_t BS_VolLab[11];    // 卷标
+    uint8_t BS_FilSysType[8]; // 文件系统类型
+
+    uint8_t BootCode[420]; // 引导代码、数据
+
+    uint16_t BS_TrailSig; // 结束标志0xAA55
+} __attribute__((packed));
+
+/**
+ * @brief fat32文件系统的FSInfo扇区结构体
+ * 
+ */
+struct fat32_FSInfo_t
+{
+    uint32_t FSI_LeadSig;         // FS info扇区标志符 数值为0x41615252
+    uint8_t FSI_Reserved1[480]; // 保留使用,全部置为0
+    uint32_t FSI_StrucSig;        // 另一个标志符,数值为0x61417272
+    uint32_t FSI_Free_Count;      // 上一次记录的空闲簇数量,这是一个参考值
+    uint32_t FSI_Nxt_Free;        // 空闲簇的起始搜索位置,这是为驱动程序提供的参考值
+    uint8_t FSI_Reserved2[12];  // 保留使用,全部置为0
+    uint32_t FSI_TrailSig;        // 结束标志,数值为0xaa550000
+} __attribute__((packed));
+
+/**
+ * @brief 读取指定磁盘上的第0个分区的fat32文件系统
+ * 
+ * @param disk_num 
+ */
+void fat32_FS_init(int disk_num);

+ 5 - 8
kernel/main.c

@@ -17,6 +17,8 @@
 #include <smp/ipi.h>
 #include <sched/sched.h>
 
+#include <filesystem/fat32/fat32.h>
+
 #include "driver/multiboot2/multiboot2.h"
 #include "driver/acpi/acpi.h"
 #include "driver/keyboard/ps2_keyboard.h"
@@ -181,14 +183,9 @@ void Start_Kernel(void)
     system_initialize();
 
     
-    uint64_t buf[100];
-    ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, 0, 1, (uint64_t)&buf, 0, 0);
-    kdebug("buf[0]=%#010lx",(uint32_t)buf[0]);
-    buf[0] = 0xffd3;
-    ahci_operation.transfer(ATA_CMD_WRITE_DMA_EXT, 0, 1, (uint64_t)&buf, 0, 0);
-
-    ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, 0, 1, (uint64_t)&buf, 0, 0);
-    kdebug("buf[0]=%#010lx",(uint32_t)buf[0]);
+    fat32_FS_init(0);
+
+
     
     // show_welcome();
     // test_mm();

+ 9 - 12
kernel/process/process.c

@@ -84,23 +84,20 @@ void user_level_function()
                          : "0"(1), "D"(string)
                          : "memory");
                          */
+    long err_code;
+    ul addr = (ul)string;
+    __asm__ __volatile__(
+        "movq %2, %%r8 \n\t"
+        "int $0x80   \n\t"
+        : "=a"(err_code)
+        : "a"(SYS_PRINTF), "m"(addr)
+        : "memory", "r8");
 
-    for (int i = 0;; ++i)
-    {
-        long err_code;
-        ul addr = (ul)string;
-        __asm__ __volatile__(
-            "movq %2, %%r8 \n\t"
-            "int $0x80   \n\t"
-            : "=a"(err_code)
-            : "a"(SYS_PRINTF), "m"(addr)
-            : "memory", "r8");
-    }
     // enter_syscall_int(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0);
     //  kinfo("Return from syscall id 15...");
 
     while (1)
-        ;
+        pause();
 }
 /**
  * @brief 使当前进程去执行新的代码

+ 1 - 0
run.sh

@@ -93,6 +93,7 @@ if [ $flag_can_run -eq 1 ]; then
         bochs -q -f ${bochsrc} -rc ./tools/bochsinit
     else
         qemu-system-x86_64 -cdrom ${iso} -m 512M -smp 2,cores=2,threads=1,sockets=1 \
+        -boot order=d   \
         -monitor stdio -d cpu_reset,guest_errors,trace:check_exception,exec,cpu,out_asm,in_asm -s -S -cpu IvyBridge --enable-kvm -rtc clock=host,base=localtime -serial file:serial_opt.txt \
         -drive id=disk,file=bin/disk.img,if=none \
         -device ahci,id=ahci \

+ 2 - 2
tools/create_hdd_image.sh

@@ -1,4 +1,4 @@
 echo "Creating virtual disk image..."
-qemu-img create -f qcow2 disk.img 16M
-mkfs.vfat disk.img
+qemu-img create -f raw disk.img 16M
+mkfs.vfat -f 32 disk.img
 echo "Successfully created disk image, please move it to folder ../bin/"