diff --git a/.gitignore b/.gitignore index 60fc945..22ce033 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ cmake-build-debug/ isodir/ +OSMain/ + crashpowerdos-x86-nodesktop-rebuild-0.2.0.iso \ No newline at end of file diff --git a/build.py b/build.py index d3cfb17..487bf0f 100644 --- a/build.py +++ b/build.py @@ -1,4 +1,5 @@ import os +import sys gcc = '/i686_elf_tools/bin/i686-elf-gcc.exe -std=gnu99 -I include/ -std=gnu99 -ffreestanding -O2 -c -Wincompatible-pointer-types' asm = '/i686_elf_tools/bin/i686-elf-as.exe' @@ -6,11 +7,15 @@ nasm = "nasm -f elf32" ld = '/i686_elf_tools/bin/i686-elf-ld.exe' cd = os.getcwd() # 获取当前执行目录 'D:\CrashPowerDOS-main\' out = "target" + + def clean(): print("Clean target folder") for file in os.listdir(cd + "\\target"): # 遍历指定文件夹下所有文件 os.remove(cd + "\\target\\" + file) return 0 + + def build_boot(): # 构建引导程序 print("Building boot source code...") status = True @@ -95,4 +100,10 @@ a = linker() if a != 0: exit(-1) print("Launching i386 vm...") -os.system("qemu-system-i386 -vga std -kernel isodir\\sys\\kernel.elf -drive format=qcow2,file=cpos.qcow2") + +if len(sys.argv) == 0 or sys.argv[1] == 'vga': + print("Graphics MODE [VGA]") + os.system("qemu-system-i386 -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -drive format=qcow2,file=cpos.qcow2") +elif sys.argv[1] == 'vbe': + print("Graphics MODE [VBE]") + os.system("qemu-system-i386 -vga std -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -drive format=qcow2,file=cpos.qcow2") \ No newline at end of file diff --git a/driver/acpi.c b/driver/acpi.c index 779fe56..119d402 100644 --- a/driver/acpi.c +++ b/driver/acpi.c @@ -170,14 +170,18 @@ static int AcpiPowerHandler(registers_t *irq) { } static void AcpiPowerInit() { - uint32_t len = facp->PM1_EVT_LEN / 2; + if(!facp) return; + + uint8_t len = facp->PM1_EVT_LEN / 2; uint32_t *PM1a_ENABLE_REG = facp->PM1a_EVT_BLK + len; uint32_t *PM1b_ENABLE_REG = facp->PM1b_EVT_BLK + len; - if (!facp) - return; + if(PM1b_ENABLE_REG == len) + PM1b_ENABLE_REG = 0; - io_out16((uint16_t)PM1a_ENABLE_REG, (uint8_t)(1 << 8)); + printf("[acpi]: Setting Power event listener...\n"); + + io_out16(PM1a_ENABLE_REG, (1 << 8)); if (PM1b_ENABLE_REG) { io_out16((uint16_t)PM1b_ENABLE_REG, (uint8_t)(1 << 8)); } diff --git a/driver/pci.c b/driver/pci.c new file mode 100644 index 0000000..306bd52 --- /dev/null +++ b/driver/pci.c @@ -0,0 +1,157 @@ +#include "../include/pci.h" +#include "../include/memory.h" +#include "../include/io.h" +#include "../include/printf.h" + +unsigned int PCI_ADDR_BASE; + +uint8_t pci_get_drive_irq(uint8_t bus, uint8_t slot, uint8_t func) { + return (uint8_t)read_pci(bus, slot, func, 0x3c); +} + +uint32_t pci_get_port_base(uint8_t bus, uint8_t slot, uint8_t func) { + uint32_t io_port = 0; + for(int i = 0;i<6;i++) { + base_address_register bar = get_base_address_register(bus,slot,func,i); + if(bar.type == input_output) { + io_port = (uint32_t)bar.address; + } + } + return io_port; +} + +void PCI_GET_DEVICE(uint16_t vendor_id, uint16_t device_id, uint8_t* bus, uint8_t* slot, uint8_t* func) { + unsigned char* pci_drive = PCI_ADDR_BASE; + for (;; pci_drive += 0x110 + 4) { + if (pci_drive[0] == 0xff) { + struct pci_config_space_public* pci_config_space_puclic; + pci_config_space_puclic = + (struct pci_config_space_public*)(pci_drive + 0x0c); + if (pci_config_space_puclic->VendorID == vendor_id && + pci_config_space_puclic->DeviceID == device_id) { + *bus = pci_drive[1]; + *slot = pci_drive[2]; + *func = pci_drive[3]; + return; + } + } else { + break; + } + } +} + +uint32_t read_bar_n(uint8_t bus, uint8_t device, uint8_t function, uint8_t bar_n) { + uint32_t bar_offset = 0x10 + 4 * bar_n; + return read_pci(bus, device, function, bar_offset); +} + +void write_pci(uint8_t bus, uint8_t device, uint8_t function, uint8_t registeroffset, uint32_t value) { + uint32_t id = 1 << 31 | ((bus & 0xff) << 16) | ((device & 0x1f) << 11) | + ((function & 0x07) << 8) | (registeroffset & 0xfc); + io_out32(PCI_COMMAND_PORT, id); + io_out32(PCI_DATA_PORT, value); +} + +uint32_t pci_read_command_status(uint8_t bus, uint8_t slot, uint8_t func) { + return read_pci(bus, slot, func, 0x04); +} + +void pci_write_command_status(uint8_t bus, uint8_t slot, uint8_t func, uint32_t value) { + write_pci(bus, slot, func, 0x04, value); +} + +uint32_t read_pci(uint8_t bus, uint8_t device, uint8_t function, uint8_t registeroffset) { + uint32_t id = 1 << 31 | ((bus & 0xff) << 16) | ((device & 0x1f) << 11) | + ((function & 0x07) << 8) | (registeroffset & 0xfc); + io_out32(PCI_COMMAND_PORT, id); + uint32_t result = io_in32(PCI_DATA_PORT); + return result >> (8 * (registeroffset % 4)); +} + +base_address_register get_base_address_register(uint8_t bus, uint8_t device, uint8_t function, uint8_t bar) { + base_address_register result; + + uint32_t headertype = read_pci(bus, device, function, 0x0e) & 0x7e; + int max_bars = 6 - 4 * headertype; + if (bar >= max_bars) + return result; + + uint32_t bar_value = read_pci(bus, device, function, 0x10 + 4 * bar); + result.type = (bar_value & 1) ? input_output : mem_mapping; + + if (result.type == mem_mapping) { + switch ((bar_value >> 1) & 0x3) { + case 0: // 32 + case 1: // 20 + case 2: // 64 + break; + } + result.address = (uint8_t*)(bar_value & ~0x3); + result.prefetchable = 0; + } else { + result.address = (uint8_t*)(bar_value & ~0x3); + result.prefetchable = 0; + } + return result; +} + +void pci_config(unsigned int bus, unsigned int f, unsigned int equipment, unsigned int adder) { + unsigned int cmd = 0; + cmd = 0x80000000 + (unsigned int)adder + ((unsigned int)f << 8) + + ((unsigned int)equipment << 11) + ((unsigned int)bus << 16); + // cmd = cmd | 0x01; + io_out32(PCI_COMMAND_PORT, cmd); +} + +void init_pci(){ + printf("[\035kernel\036]: Loading pci device...\n"); + + PCI_ADDR_BASE = kmalloc(1 * 1024 * 1024); + unsigned int i, BUS, Equipment, F, ADDER, *i1; + unsigned char *PCI_DATA = PCI_ADDR_BASE, *PCI_DATA1; + + for (BUS = 0; BUS < 256; BUS++) { //查询总线 + for (Equipment = 0; Equipment < 32; Equipment++) { //查询设备 + for (F = 0; F < 8; F++) { //查询功能 + pci_config(BUS, F, Equipment, 0); + if (io_in32(PCI_DATA_PORT) != 0xFFFFFFFF) { + //当前插槽有设备 + //把当前设备信息映射到PCI数据区 + int key = 1; + while (key) { + PCI_DATA1 = PCI_DATA; + *PCI_DATA1 = 0xFF; //表占用标志 + PCI_DATA1++; + *PCI_DATA1 = BUS; //总线号 + PCI_DATA1++; + *PCI_DATA1 = Equipment; //设备号 + PCI_DATA1++; + *PCI_DATA1 = F; //功能号 + PCI_DATA1++; + PCI_DATA1 = PCI_DATA1 + 8; + for (ADDER = 0; ADDER < 256; ADDER = ADDER + 4) { + pci_config(BUS, F, Equipment, ADDER); + i = io_in32(PCI_DATA_PORT); + i1 = i; + //*i1 = PCI_DATA1; + memcpy(PCI_DATA1, &i, 4); + PCI_DATA1 = PCI_DATA1 + 4; + } + for (uint8_t barNum = 0; barNum < 6; barNum++) { + base_address_register bar = + get_base_address_register(BUS, Equipment, F, barNum); + if (bar.address && (bar.type == input_output)) { + PCI_DATA1 += 4; + int i = ((uint32_t)(bar.address)); + memcpy(PCI_DATA1, &i, 4); + printf("[pci]: Device Address: %08x Size: %d\n",bar.address,bar.size); + } + } + PCI_DATA = PCI_DATA + 0x110 + 4; + key = 0; + } + } + } + } + } +} diff --git a/driver/pcnet.c b/driver/pcnet.c new file mode 100644 index 0000000..3d93780 --- /dev/null +++ b/driver/pcnet.c @@ -0,0 +1,227 @@ +#include "../include/pcnet.h" +#include "../include/io.h" +#include "../include/description_table.h" +#include "../include/pci.h" +#include "../include/timer.h" +#include "../include/memory.h" +#include "../include/printf.h" + +uint8_t bus = 255, dev = 255, func = 255; + +extern unsigned int PCI_ADDR_BASE; +extern idt_ptr_t idt_ptr; +static int io_base = 0; +static uint8_t sendBufferDescMemory[2048 + 15]; +static uint8_t sendBuffers[8][2048 + 15]; +static uint8_t currentSendBuffer; +static uint8_t recvBufferDescMemory[2048 + 15]; +static uint8_t recvBuffers[8][2048 + 15]; +static uint8_t currentRecvBuffer; +uint8_t mac0, mac1, mac2, mac3, mac4, mac5; +struct InitializationBlock initBlock; +static struct BufferDescriptor* sendBufferDesc; +static struct BufferDescriptor* recvBufferDesc; +int recv = 0; + +static void set_handler(int IRQ, int addr) { + register_interrupt_handler(0x20 + IRQ, (int)addr); +} + +void into_32bitsRW() { + io_out16(io_base + RAP16, BCR18); + uint16_t tmp = io_in16(io_base + BDP16); + tmp |= 0x80; + io_out16(io_base + RAP16, BCR18); + io_out16(io_base + BDP16, tmp); + // 此时就处于32位读写模式了 +} +void into_16bitsRW() { + // 切换到16位读写模式 与切换到32位读写模式相反 + io_out32(io_base + RAP32, BCR18); + uint32_t tmp = io_in32(io_base + BDP32); + tmp &= ~0x80; + io_out32(io_base + RAP32, BCR18); + io_out32(io_base + BDP32, tmp); +} + +void reset_card() { + // PCNET卡复位(约等于切换到16位读写模式 + io_in16(io_base + RESET16); + io_out16(io_base + RESET16, 0x00); + // 执行完后需等待(sleep(1)) +} + +void Activate() { + // 激活PCNET IRQ中断 + io_out16(io_base + RAP16, CSR0); + io_out16(io_base + RDP16, 0x41); + + io_out16(io_base + RAP16, CSR4); + uint32_t temp = io_in16(io_base + RDP16); + io_out16(io_base + RAP16, CSR4); + io_out16(io_base + RDP16, temp | 0xc00); + + io_out16(io_base + RAP16, CSR0); + io_out16(io_base + RDP16, 0x42); +} + +int pcnet_find_card() { + //printk("pcnet_find:"); + PCI_GET_DEVICE(CARD_VENDOR_ID, CARD_DEVICE_ID, &bus, &dev, &func); + if (bus == 255) { + //printk("false\n"); + return 0; + } + //printk("true"); + return 1; +} +/* +static void init_Card_all() { + currentSendBuffer = 0; + currentRecvBuffer = 0; + + // 获取MAC地址并保存 + mac0 = io_in8(io_base + APROM0); + mac1 = io_in8(io_base + APROM1); + mac2 = io_in8(io_base + APROM2); + mac3 = io_in8(io_base + APROM3); + mac4 = io_in8(io_base + APROM4); + mac5 = io_in8(io_base + APROM5); + // printk("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac0, mac1, mac2, + // mac3, + // mac4, mac5); + // 这里约等于 into_16bitsRW(); + reset_card(); + clock_sleep(1); + + io_out16(io_base + RAP16, BCR20); + io_out16(io_base + BDP16, 0x102); + io_out16(io_base + RAP16, CSR0); + io_out16(io_base + RDP16, 0x0004); // 暂时停止所有传输(用于初始化PCNET网卡 + + // initBlock传输初始化(CSR1=IB地址低16位,CSR2=IB地址高16位) + // & + // Send/Recv环形缓冲区的初始化 + initBlock.mode = 0; + initBlock.reserved1numSendBuffers = + (0 << 4) | 3; // 高4位是reserved1 低4位是numSendBuffers + initBlock.reserved2numRecvBuffers = + (0 << 4) | 3; // 高4位是reserved2 低4位是numRecvBuffers + initBlock.mac0 = mac0; + initBlock.mac1 = mac1; + initBlock.mac2 = mac2; + initBlock.mac3 = mac3; + initBlock.mac4 = mac4; + initBlock.mac5 = mac5; + initBlock.reserved3 = 0; + initBlock.logicalAddress = 0; + + sendBufferDesc = + (struct BufferDescriptor*)(((uint32_t)&sendBufferDescMemory[0] + 15) & + 0xfffffff0); + initBlock.sendBufferDescAddress = (uint32_t)sendBufferDesc; + recvBufferDesc = + (struct BufferDescriptor*)(((uint32_t)&recvBufferDescMemory[0] + 15) & + 0xfffffff0); + initBlock.recvBufferDescAddress = (uint32_t)recvBufferDesc; + + for (uint8_t i = 0; i < 8; i++) { + sendBufferDesc[i].address = (((uint32_t)&sendBuffers[i] + 15) & 0xfffffff0); + sendBufferDesc[i].flags = 0xf7ff; + sendBufferDesc[i].flags2 = 0; + sendBufferDesc[i].avail = 0; + + recvBufferDesc[i].address = (((uint32_t)&recvBuffers[i] + 15) & 0xfffffff0); + recvBufferDesc[i].flags = 0xf7ff | 0x80000000; + recvBufferDesc[i].flags2 = 0; + recvBufferDesc[i].avail = 0; + memclean(recvBufferDesc[i].address, 2048); + } + // CSR1,CSR2赋值(initBlock地址 + io_out16(io_base + RAP16, CSR1); + io_out16(io_base + RDP16, (uint16_t)&initBlock); + io_out16(io_base + RAP16, CSR2); + io_out16(io_base + RDP16, (uint32_t)&initBlock >> 16); + + Activate(); + + initBlock.logicalAddress = 0xFFFFFFFF; + ip = 0xFFFFFFFF; + gateway = 0xFFFFFFFF; + submask = 0xFFFFFFFF; + dns = 0xFFFFFFFF; + dhcp_discovery(&mac0); + while (gateway == 0xFFFFFFFF && submask == 0xFFFFFFFF && dns == 0xFFFFFFFF && + ip == 0xFFFFFFFF) { + initBlock.logicalAddress = ip; + } + + // 初始化ARP表 + + + // DNSParseIP("baidu.com"); + + // UDPProviderSend(0x761ff8d7, initBlock.logicalAddress, 52949, 38, + // "来自Powerint DOS 386的消息:我是周志昊!!!", strlen("来自Powerint DOS + // 386的消息:我是周志昊!!!")); +} +*/ +void init_pcnet_card() { + printf("[\035kernel\036]: Loading pcnet driver.\n"); + // 允许PCNET网卡产生中断 + // 1.注册中断 + register_interrupt_handler(pci_get_drive_irq(bus, dev, func),PCNET_IRQ); + // 2,写COMMAND和STATUS寄存器 + uint32_t conf = pci_read_command_status(bus, dev, func); + conf &= 0xffff0000; // 保留STATUS寄存器,清除COMMAND寄存器 + conf |= 0x7; // 设置第0~2位(允许PCNET网卡产生中断 + pci_write_command_status(bus, dev, func, conf); + io_base = pci_get_port_base(bus, dev, func); + //init_Card_all(); +} + +void PCNET_IRQ(registers_t *reg) { + + io_out16(io_base + RAP16, CSR0); + uint16_t temp = io_in16(io_base + RDP16); + + if ((temp & 0x0400) == 0x0400) + Recv(); + + io_out16(io_base + RAP16, CSR0); + io_out16(io_base + RDP16, temp); // 通知PCNET网卡 中断处理完毕 + + if ((temp & 0x0100) == 0x0100) + printf("PCNET INIT DONE\n"); + return; +} + +void Recv() { + recv = 1; + //printk("\nPCNET RECV: "); + for (; (recvBufferDesc[currentRecvBuffer].flags & 0x80000000) == 0; + currentRecvBuffer = (currentRecvBuffer + 1) % 8) { + if (!(recvBufferDesc[currentRecvBuffer].flags & 0x40000000) && + (recvBufferDesc[currentRecvBuffer].flags & 0x03000000) == 0x03000000) { + uint32_t size = recvBufferDesc[currentRecvBuffer].flags & 0xfff; + if (size > 128) + size -= 4; + + uint8_t* buffer = (uint8_t*)(recvBufferDesc[currentRecvBuffer].address); + for (int i = 0; i < (size > 128 ? 128 : size); i++) { + //printk("%02x ", buffer[i]); + } + //printk("\n"); + } + recv = 0; + currentRecvBuffer = 0; + //TODO Card_Recv_Handler(recvBufferDesc[currentRecvBuffer].address); + + memclean(recvBufferDesc[currentRecvBuffer].address, 2048); + recvBufferDesc[currentRecvBuffer].flags2 = 0; + recvBufferDesc[currentRecvBuffer].flags = 0x8000f7ff; + } + currentRecvBuffer = 0; + +} + diff --git a/driver/rtl8139.c b/driver/rtl8139.c new file mode 100644 index 0000000..61d531a --- /dev/null +++ b/driver/rtl8139.c @@ -0,0 +1,15 @@ +/* + * rtl8139.c + * Realtek rtl8139 网卡驱动 + * Copyright (C) zhouzhihao 2023 + */ + +#include "../include/rtl8139.h" + +static uint8_t bus, dev, func; +static uint32_t io_base; +static uint8_t *sendBuffer[4]; +static uint8_t *recvBuffer; +static uint8_t currentSendBuffer; + +extern uint8_t mac0, mac1, mac2, mac3, mac4, mac5; diff --git a/driver/vbe.c b/driver/vbe.c index 1ef11b6..c019f07 100644 --- a/driver/vbe.c +++ b/driver/vbe.c @@ -1,45 +1,17 @@ #include "../include/graphics.h" #include "../include/io.h" -unsigned int vesa_fb_width, vesa_fb_height, vesa_fb_bpp, vesa_fb_pitch; -uint8_t *vesa_fb_addr; -extern int status; - -void putPix(unsigned int x, unsigned int y, uint32_t color) { - if (status != 1) - return; - color_rgba col; - col.r = color >> 16; - col.g = color >> 8; - col.b = color; - col.a = 0xFF; - - if (x >= vesa_fb_width || y >= vesa_fb_height) - return; - unsigned where = x * (vesa_fb_bpp / 8) + y * vesa_fb_pitch; - vesa_fb_addr[where + 0] = col.b; - vesa_fb_addr[where + 1] = col.g; - vesa_fb_addr[where + 2] = col.r; +int isVBEDisplayMode(uint16_t vbe_mode_info) { + if (vbe_mode_info & (1 << 12)) { + return 1; + } else { + return 0; + } } void initVBE(multiboot_t *mboot) { - vesa_fb_addr = (uint8_t * )( - int)(mboot->framebuffer_addr); - vesa_fb_pitch = mboot->framebuffer_pitch; - vesa_fb_bpp = mboot->framebuffer_bpp; - vesa_fb_width = mboot->framebuffer_width; - vesa_fb_height = mboot->framebuffer_height; - - printf("[\035VBE driver\036]: Framebuffer address: 0x%08x\n",vesa_fb_addr); - printf("[\035VBE driver\036]: Screen Size: width:%d - height:%d\n",mboot->framebuffer_width,mboot->framebuffer_height); - // TODO: insert into devtable -} - - -void vbe_putchar(char c) { - -} - -void vbe_clear() { + if(isVBEDisplayMode(mboot->vbe_mode_info)){ + printf("[\035kernel\036]: Graphics mode: \037VBE\036\n"); + } else printf("[\035kernel\036]: Graphics mode: \037VGA\036\n"); } diff --git a/driver/vdisk.c b/driver/vdisk.c new file mode 100644 index 0000000..9cf4ed2 --- /dev/null +++ b/driver/vdisk.c @@ -0,0 +1,113 @@ +/* + * Plants-OS VDiskDriver + * Copyright by min0911. + */ + +#include "../include/vdisk.h" +#include "../include/printf.h" + +int getReadyDisk(); + +vdisk vdisk_ctl[10]; + +int init_vdisk() { + for (int i = 0; i < 10; i++) { + vdisk_ctl[i].flag = 0; // 设置为未使用 + } + printf("[\035kernel\036]: VDisk driver load success!\n"); + return 0; +} + +int register_vdisk(vdisk vd) { + for (int i = 0; i < 10; i++) { + if (!vdisk_ctl[i].flag) { + vdisk_ctl[i] = vd; // 找到了! + return i + ('A'); // 注册成功,返回drive + } + } + printf("[vdisk]not found\n"); + return 0; // 注册失败 +} + +int logout_vdisk(char drive) { + int indx = drive - ('A'); + if (indx > 10) { + return 0; // 失败 + } + if (vdisk_ctl[indx].flag) { + vdisk_ctl[indx].flag = 0; // 设置为没有 + return 1; // 成功 + } else { + return 0; // 失败 + } +} + +int rw_vdisk(char drive, unsigned int lba, unsigned char *buffer, + unsigned int number, int read) { + int indx = drive - ('A'); + if (indx > 10) { + return 0; // 失败 + } + if (vdisk_ctl[indx].flag) { + if (read) { + vdisk_ctl[indx].Read(drive, buffer, number, lba); + //for(;;); + } else { + vdisk_ctl[indx].Write(drive, buffer, number, lba); + } + return 1; // 成功 + } else { + return 0; // 失败 + } +} + +int have_vdisk(char drive) { + int indx = drive - 'A'; + if (indx > 10) { + return 0; // 失败 + } + if (vdisk_ctl[indx].flag) { + return 1; // 成功 + } else { + return 0; // 失败 + } +} + +void Disk_Read(unsigned int lba, unsigned int number, void *buffer, + char drive) { + if (have_vdisk(drive)) { + for (int i = 0; i < number; i += SECTORS_ONCE) { + int sectors = + ((number - i) >= SECTORS_ONCE) ? SECTORS_ONCE : (number - i); + rw_vdisk(drive, lba + i, buffer + i * 512, sectors, 1); + } + } +} + +int disk_Size(char drive) { + unsigned char drive1 = drive; + if (have_vdisk(drive1)) { + int indx = drive1 - 'A'; + return vdisk_ctl[indx].size; + } else { + print("Disk Not Ready.\n"); + return 0; + } + + return 0; +} + +int DiskReady(char drive) { return have_vdisk(drive); } + +int getReadyDisk() { return 0; } + +void Disk_Write(unsigned int lba, unsigned int number, void *buffer, + char drive) { + if (have_vdisk(drive)) { + for (int i = 0; i < number; i += SECTORS_ONCE) { + int sectors = + ((number - i) >= SECTORS_ONCE) ? SECTORS_ONCE : (number - i); + rw_vdisk(drive, lba + i, buffer + i * 512, sectors, 0); + } + } +} diff --git a/driver/vga.c b/driver/vga.c index c07ac30..621d47d 100644 --- a/driver/vga.c +++ b/driver/vga.c @@ -47,10 +47,6 @@ void vga_install(void) { } void vga_clear() { - if(status){ - vbe_clear(); - return; - } for (size_t y = 0; y < VGA_HEIGHT; y++) { for (size_t x = 0; x < VGA_WIDTH; x++) { const size_t index = y * VGA_WIDTH + x; @@ -80,10 +76,6 @@ void vga_putentryat(char c, uint8_t color, size_t x, size_t y) { } void vga_putchar(char c) { - if(status){ - vbe_putchar(c); - return; - } uint8_t attributeByte = terminal_color; // 黑底白字 uint16_t attribute = attributeByte << 8; uint16_t *location; @@ -148,13 +140,3 @@ void vga_write(const char *data, size_t size) { void vga_writestring(const char *data) { vga_write(data, strlen(data)); } - -void printf(const char *formet, ...) { - int len; - va_list ap; - va_start(ap, formet); - char *buf[1024] = {0}; - len = vsprintf(buf, formet, ap); - vga_writestring(buf); - va_end(ap); -} \ No newline at end of file diff --git a/include/common.h b/include/common.h index bb26da9..1c37c81 100644 --- a/include/common.h +++ b/include/common.h @@ -11,6 +11,8 @@ #include #include +typedef int bool; + void assert(int b,char* message); size_t strlen(const char* str); int strcmp(const char *s1, const char *s2); diff --git a/include/description_table.h b/include/description_table.h index 5a696c6..1ec240f 100644 --- a/include/description_table.h +++ b/include/description_table.h @@ -126,4 +126,6 @@ void write_tss(int32_t num, uint16_t ss0, uint32_t esp0); void gdt_install(); void idt_install(); +void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags); + #endif //CRASHPOWEROS_DESCRIPTION_TABLE_H diff --git a/include/fat.h b/include/fat.h new file mode 100644 index 0000000..c870ed3 --- /dev/null +++ b/include/fat.h @@ -0,0 +1,93 @@ +#ifndef CRASHPOWEROS_FAT_H +#define CRASHPOWEROS_FAT_H + +#include "../include/common.h" + +struct FAT_CACHE { + unsigned int ADR_DISKIMG; + struct FAT_FILEINFO *root_directory; + struct LIST *directory_list; + struct LIST *directory_max_list; + struct LIST *directory_clustno_list; + int *fat; + int FatMaxTerms; + unsigned int ClustnoBytes; + unsigned short RootMaxFiles; + unsigned int RootDictAddress; + unsigned int FileDataAddress; + unsigned int imgTotalSize; + unsigned short SectorBytes; + unsigned int Fat1Address, Fat2Address; + unsigned char *FatClustnoFlags; + int type; +}; +typedef struct { + struct FAT_CACHE dm; + struct FAT_FILEINFO *dir; +} fat_cache; + +#define get_dm(vfs) ((fat_cache *)(vfs->cache))->dm +#define get_now_dir(vfs) ((fat_cache *)(vfs->cache))->dir +#define get_clustno(high, low) (high << 16) | (low & 0xffff) +#define clustno_end(type) 0xfffffff & ((((1 << (type - 1)) - 1) << 1) + 1) + +struct FAT_FILEINFO { + unsigned char name[8], ext[3], type; + char reserve; + unsigned char create_time_tenth; + unsigned short create_time, create_date, access_date, clustno_high; + unsigned short update_time, update_date, clustno_low; + unsigned int size; +}; + +typedef struct FILE { + unsigned int mode; + unsigned int fileSize; + unsigned char *buffer; + unsigned int bufferSize; + unsigned int p; + char *name; +} FILE; + +typedef enum { FLE, DIR, RDO, HID, SYS } ftype; +typedef struct { + char name[255]; + ftype type; + unsigned int size; + unsigned short year, month, day; + unsigned short hour, minute; +} vfs_file; + +typedef struct vfs_t { + struct List *path; + void *cache; + char FSName[255]; + int disk_number; + uint8_t drive; // 大写(必须) + vfs_file *(*FileInfo)(struct vfs_t *vfs, char *filename); + struct List *(*ListFile)(struct vfs_t *vfs, char *dictpath); + bool (*ReadFile)(struct vfs_t *vfs, char *path, char *buffer); + bool (*WriteFile)(struct vfs_t *vfs, char *path, char *buffer, int size); + bool (*DelFile)(struct vfs_t *vfs, char *path); + bool (*DelDict)(struct vfs_t *vfs, char *path); + bool (*CreateFile)(struct vfs_t *vfs, char *filename); + bool (*CreateDict)(struct vfs_t *vfs, char *filename); + bool (*RenameFile)(struct vfs_t *vfs, char *filename, char *filename_of_new); + bool (*Attrib)(struct vfs_t *vfs, char *filename, ftype type); + bool (*Format)(uint8_t disk_number); + void (*InitFs)(struct vfs_t *vfs, uint8_t disk_number); + void (*DeleteFs)(struct vfs_t *vfs); + bool (*Check)(uint8_t disk_number); + bool (*cd)(struct vfs_t *vfs, char *dictName); + int (*FileSize)(struct vfs_t *vfs, char *filename); + void (*CopyCache)(struct vfs_t *dest, struct vfs_t *src); + int flag; +} vfs_t; +/* +void read_fat(unsigned char *img, int *fat, unsigned char *ff, int max,int type); +int get_directory_max(struct FAT_FILEINFO *directory, vfs_t *vfs); +void file_loadfile(int clustno, int size, char *buf, int *fat, vfs_t *vfs); +void file_savefat(int *fat, int clustno, int length, vfs_t *vfs); + */ + +#endif diff --git a/include/graphics.h b/include/graphics.h index 2b08a46..ab8f08b 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -69,13 +69,6 @@ struct color_rgba { uint8_t a; }; -typedef struct { - unsigned short di, si, bp, sp, bx, dx, cx, ax; - unsigned short gs, fs, es, ds, eflags; -} regs16_t; - - - typedef struct color_rgba color_rgba; uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg); @@ -100,14 +93,4 @@ void vga_clear(); void move_cursor(); -void printf(const char *formet, ...); - -void vbe_putchar(char c); - -void vbe_clear(); - -void initVBE(multiboot_t *mboot); - -void putPix(unsigned int x, unsigned int y, uint32_t color); - #endif \ No newline at end of file diff --git a/include/io.h b/include/io.h index 0cd3936..d6be39e 100644 --- a/include/io.h +++ b/include/io.h @@ -4,6 +4,11 @@ #include +typedef struct { + unsigned short di, si, bp, sp, bx, dx, cx, ax; + unsigned short gs, fs, es, ds, eflags; +} regs16_t; + struct tty { int using1; // 使用标志 void *vram; // 显存(也可以当做图层) diff --git a/include/list.h b/include/list.h new file mode 100644 index 0000000..fa850a0 --- /dev/null +++ b/include/list.h @@ -0,0 +1,24 @@ +#ifndef CRASHPOWEROS_LIST_H +#define CRASHPOWEROS_LIST_H + +#include +#include + +struct ListCtl { + struct List *start; + struct List *end; + int all; +}; +struct List { + struct ListCtl *ctl; + struct List *prev; + uintptr_t val; + struct List *next; +}; + +typedef struct List List; + +struct List* FindForCount(size_t count, struct List* Obj); +int GetLastCount(struct List* Obj); + +#endif diff --git a/include/memory.h b/include/memory.h index c12c813..dff3a7b 100644 --- a/include/memory.h +++ b/include/memory.h @@ -83,4 +83,6 @@ uint32_t kmalloc_ap(uint32_t size, uint32_t *phys); void init_page(); +void memclean(char *s, int len); + #endif //CRASHPOWEROS_MEMORY_H diff --git a/include/multiboot.h b/include/multiboot.h index 597325c..f5e2656 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -18,14 +18,6 @@ typedef struct multiboot_t { uint32_t flags; // Multiboot 的版本信息 - /** - * 从 BIOS 获知的可用内存 - * - * mem_lower和mem_upper分别指出了低端和高端内存的大小,单位是K。 - * 低端内存的首地址是0,高端内存的首地址是1M。 - * 低端内存的最大可能值是640K。 - * 高端内存的最大可能值是最大值减去1M。但并不保证是这个值。 - */ uint32_t mem_lower; uint32_t mem_upper; diff --git a/include/pci.h b/include/pci.h new file mode 100644 index 0000000..d1a0553 --- /dev/null +++ b/include/pci.h @@ -0,0 +1,57 @@ +#ifndef CRASHPOWEROS_PCI_H +#define CRASHPOWEROS_PCI_H + +#define PCI_COMMAND_PORT 0xCF8 +#define PCI_DATA_PORT 0xCFC +#define mem_mapping 0 +#define input_output 1 + +#include + +typedef struct base_address_register { + int prefetchable; + uint8_t* address; + uint32_t size; + int type; +} base_address_register; + +struct pci_config_space_public { + unsigned short VendorID; + unsigned short DeviceID; + unsigned short Command; + unsigned short Status; + unsigned char RevisionID; + unsigned char ProgIF; + unsigned char SubClass; + unsigned char BaseClass; + unsigned char CacheLineSize; + unsigned char LatencyTimer; + unsigned char HeaderType; + unsigned char BIST; + unsigned int BaseAddr[6]; + unsigned int CardbusCIS; + unsigned short SubVendorID; + unsigned short SubSystemID; + unsigned int ROMBaseAddr; + unsigned char CapabilitiesPtr; + unsigned char Reserved[3]; + unsigned int Reserved1; + unsigned char InterruptLine; + unsigned char InterruptPin; + unsigned char MinGrant; + unsigned char MaxLatency; +}; + +uint32_t pci_read_command_status(uint8_t bus, uint8_t slot, uint8_t func); +void PCI_GET_DEVICE(uint16_t vendor_id, uint16_t device_id, uint8_t* bus, uint8_t* slot, uint8_t* func); +uint32_t pci_get_port_base(uint8_t bus, uint8_t slot, uint8_t func); +uint8_t pci_get_drive_irq(uint8_t bus, uint8_t slot, uint8_t func); +void pci_write_command_status(uint8_t bus, uint8_t slot, uint8_t func, uint32_t value); +void write_pci(uint8_t bus, uint8_t device, uint8_t function, uint8_t registeroffset, uint32_t value); +uint32_t read_bar_n(uint8_t bus, uint8_t device, uint8_t function, uint8_t bar_n); +uint32_t read_pci(uint8_t bus, uint8_t device, uint8_t function, uint8_t registeroffset); +base_address_register get_base_address_register(uint8_t bus, uint8_t device, uint8_t function, uint8_t bar); +void pci_config(unsigned int bus, unsigned int f, unsigned int equipment, unsigned int adder); +void init_pci(); + +#endif diff --git a/include/pcnet.h b/include/pcnet.h new file mode 100644 index 0000000..d7b2ee6 --- /dev/null +++ b/include/pcnet.h @@ -0,0 +1,62 @@ +#ifndef CRASHPOWEROS_PCNET_H +#define CRASHPOWEROS_PCNET_H + +#define CARD_VENDOR_ID 0x1022 +#define CARD_DEVICE_ID 0x2000 +// 为了使用该寄存器,必须将RAP设置为这些值 +#define CSR0 0 +#define CSR1 1 +#define CSR2 2 +#define CSR3 3 +#define CSR4 4 +#define BCR18 18 +#define BCR20 20 +// 16位I/O端口(或到I/O空间开始的偏移)。 +#define APROM0 0x00 +#define APROM1 0x01 +#define APROM2 0x02 +#define APROM3 0x03 +#define APROM4 0x04 +#define APROM5 0x05 +// 16位读写模式下 +#define RDP16 0x10 +#define RAP16 0x12 +#define RESET16 0x14 +#define BDP16 0x16 +// 32位读写模式下 +#define RDP32 0x10 +#define RAP32 0x14 +#define RESET32 0x18 +#define BDP32 0x1c + +#include +#include "isr.h" + +struct InitializationBlock { + uint16_t mode; + uint8_t reserved1numSendBuffers; + uint8_t reserved2numRecvBuffers; + uint8_t mac0, mac1, mac2, mac3, mac4, mac5; + uint16_t reserved3; + uint64_t logicalAddress; + uint32_t recvBufferDescAddress; + uint32_t sendBufferDescAddress; +} __attribute__((packed)); + +struct BufferDescriptor { + uint32_t address; + uint32_t flags; + uint32_t flags2; + uint32_t avail; +} __attribute__((packed)); + +void into_32bitsRW(); +void into_16bitsRW(); +void reset_card(); +void Activate(); +int pcnet_find_card(); +void init_pcnet_card(); +void PCNET_IRQ(registers_t *reg); +void Recv(); + +#endif diff --git a/include/printf.h b/include/printf.h index 5a9c4d7..f8c2d80 100644 --- a/include/printf.h +++ b/include/printf.h @@ -5,4 +5,9 @@ #include #include +int vsprintf(char *buf, const char *fmt, va_list args); +int sprintf(char *buf, const char *fmt, ...); +void printf(const char *formet, ...); +void print(char *message); + #endif //CRASHPOWEROS_PRINTF_H diff --git a/include/rtl8139.h b/include/rtl8139.h new file mode 100644 index 0000000..0ab48be --- /dev/null +++ b/include/rtl8139.h @@ -0,0 +1,26 @@ +#ifndef CRASHPOWEROS_RTL8139_H +#define CRASHPOWEROS_RTL8139_H + +#define CARD_VENDOR_ID 0x10EC +#define CARD_DEVICE_ID 0x8139 +#define MAC0 0x00 +#define MAC1 0x01 +#define MAC2 0x02 +#define MAC3 0x03 +#define MAC4 0x04 +#define MAC5 0x05 +#define MAR 0x08 +#define RBSTART 0x30 +#define CAPR 0x38 +#define CMD 0x37 +#define IMR 0x3C +#define ISR 0x3E +#define CONFIG_1 0x52 +#define TCR 0x40 +#define RCR 0x44 +#define TSAD0 0x20 +#define TSD0 0x10 + +#include + +#endif diff --git a/include/vdisk.h b/include/vdisk.h new file mode 100644 index 0000000..2cd17cc --- /dev/null +++ b/include/vdisk.h @@ -0,0 +1,46 @@ +#ifndef CRASHPOWEROS_VDISK_H +#define CRASHPOWEROS_VDISK_H + +#define SECTORS_ONCE 8 + +typedef struct { + void (*Read)(char drive, unsigned char *buffer, unsigned int number, + unsigned int lba); + void (*Write)(char drive, unsigned char *buffer, unsigned int number, + unsigned int lba); + int flag; + unsigned int size; // 大小 + char DriveName[50]; +} vdisk; + +struct IDEHardDiskInfomationBlock { + char reserve1[2]; + unsigned short CylinesNum; + char reserve2[2]; + unsigned short HeadersNum; + unsigned short TrackBytes; + unsigned short SectorBytes; + unsigned short TrackSectors; + char reserve3[6]; + char OEM[20]; + char reserve4[2]; + unsigned short BuffersBytes; + unsigned short EECCheckSumLength; + char Version[8]; + char ID[40]; +}; + +int init_vdisk(); +int register_vdisk(vdisk vd); +int logout_vdisk(char drive); +int rw_vdisk(char drive, unsigned int lba, unsigned char *buffer, + unsigned int number, int read); +int have_vdisk(char drive); +void Disk_Read(unsigned int lba, unsigned int number, void *buffer, + char drive); +int disk_Size(char drive); +int DiskReady(char drive); +void Disk_Write(unsigned int lba, unsigned int number, void *buffer, + char drive); + +#endif diff --git a/kernel/fat.c b/kernel/fat.c new file mode 100644 index 0000000..140cde6 --- /dev/null +++ b/kernel/fat.c @@ -0,0 +1,380 @@ +/* + * PlantsOS fat FileSystem + * Copyright by min0911 + */ +#include "../include/vdisk.h" +#include "../include/fat.h" +#include "../include/memory.h" +#include "../include/list.h" +#include "../include/common.h" +/* +static inline int get_fat_date(unsigned short year, unsigned short month, + unsigned short day) { + year -= 1980; + unsigned short date = 0; + date |= (year & 0x7f) << 9; + date |= (month & 0x0f) << 5; + date |= (day & 0x1f); + return date; +} +static inline int get_fat_time(unsigned short hour, unsigned short minute) { + unsigned short time = 0; + time |= (hour & 0x1f) << 11; + time |= (minute & 0x3f) << 5; + return time; +} + +void read_fat(unsigned char *img, int *fat, unsigned char *ff, int max, + int type) { + if (type == 12) { + for (int i = 0, j = 0; i < max; i += 2) { + fat[i + 0] = (img[j + 0] | img[j + 1] << 8) & 0xfff; + fat[i + 1] = (img[j + 1] >> 4 | img[j + 2] << 4) & 0xfff; + j += 3; + } + // 保留簇 + ff[0] = 1; + ff[1] = 1; + for (int i = 1; i < max; i++) { + if (fat[i] > 0 && fat[i] < 0xff0) { + ff[fat[i]] = 1; + } else if (fat[i] >= 0xff0 && fat[i] <= 0xfff) { + ff[i + 1] = 1; + } + } + } else if (type == 16) { + unsigned short *p = (unsigned short *)img; + for (int i = 0; i != max; i++) { + fat[i] = p[i]; + } + ff[0] = 1; + ff[1] = 1; + for (int i = 1; i < max; i++) { + if (fat[i] > 0 && fat[i] < 0xfff0) { + ff[fat[i]] = 1; + } else if (fat[i] >= 0xfff0 && fat[i] <= 0xffff) { + ff[i + 1] = 1; + } + } + } else if (type == 32) { + unsigned int *p = (unsigned int *)img; + for (int i = 0; i != max; i++) { + fat[i] = p[i]; + } + ff[0] = 1; + ff[1] = 1; + for (int i = 1; i < max; i++) { + if (fat[i] > 0 && fat[i] < 0xffffff0) { + ff[fat[i]] = 1; + } else if (fat[i] >= 0xffffff0 && fat[i] <= 0xfffffff) { + ff[i + 1] = 1; + } + } + } + return; +} + +int get_directory_max(struct FAT_FILEINFO *directory, vfs_t *vfs) { + if (directory == get_dm(vfs).root_directory) { + return get_dm(vfs).RootMaxFiles; + } + for (int i = 1; FindForCount(i, get_dm(vfs).directory_list) != NULL; i++) { + struct List *l = FindForCount(i, get_dm(vfs).directory_list); + if ((struct FAT_FILEINFO *)l->val == directory) { + return (int)FindForCount(i, get_dm(vfs).directory_max_list)->val; + } + } +} +void file_loadfile(int clustno, int size, char *buf, int *fat, vfs_t *vfs) { + if (!size) { + return; + } + void *img = kmalloc(((size - 1) / get_dm(vfs).ClustnoBytes + 1) * + get_dm(vfs).ClustnoBytes); + for (int i = 0; i != (size - 1) / get_dm(vfs).ClustnoBytes + 1; i++) { + uint32_t sec = (get_dm(vfs).FileDataAddress + + (clustno - 2) * get_dm(vfs).ClustnoBytes) / + get_dm(vfs).SectorBytes; + Disk_Read(sec, get_dm(vfs).ClustnoBytes / get_dm(vfs).SectorBytes, + img + i * get_dm(vfs).ClustnoBytes, vfs->disk_number); + clustno = fat[clustno]; + } + memcpy((void *)buf, img, size); + kfree(img, ((size - 1) / get_dm(vfs).SectorBytes + 1) * + get_dm(vfs).SectorBytes); + return; +} + +void file_savefile(int clustno, int size, char *buf, int *fat, + unsigned char *ff, vfs_t *vfs) { + uint32_t clustall = 0; + int tmp = clustno; + int end = clustno_end(get_dm(vfs).type); + while (fat[clustno] != end) { // 计算文件占多少Fat项 Fat项 = 大小 / 簇大小 + 1 + clustno = fat[clustno]; + clustall++; + } + int old_clustno = clustno; + clustno = tmp; + int alloc_size; + if (size > + (clustall + 1) * + get_dm(vfs).ClustnoBytes) { // 新大小 > (旧大小 / 簇大小 + 1) * 簇大小 + // 请求内存大小 = (新大小 / 簇大小 + 1) * 簇大小 + alloc_size = + ((size - 1) / get_dm(vfs).ClustnoBytes + 1) * get_dm(vfs).ClustnoBytes; + // 分配Fat(这里需要在写盘前分配) + for (int size1 = size; size1 > ((clustall + 1) * get_dm(vfs).ClustnoBytes); + size1 -= get_dm(vfs).ClustnoBytes) { + for (int i = 0; i != get_dm(vfs).FatMaxTerms; i++) { + if (!ff[i]) { + fat[old_clustno] = i; + old_clustno = i; + ff[i] = true; + break; + } + } + } + fat[old_clustno] = end; // 结尾Fat + ff[old_clustno] = true; + } else if (size <= + (clustall + 1) * + get_dm(vfs).ClustnoBytes) { // 新大小 <= (旧大小 / 簇大小 + // + 1) * 簇大小 + // 请求内存大小 = (旧大小 / 簇大小 + 1) * 簇大小 + alloc_size = (clustall + 1) * get_dm(vfs).ClustnoBytes; + // 这里不分配Fat的原因是要清空更改后多余的数据 + } + void *img = kmalloc(alloc_size); + clean((char *)img, alloc_size); + memcpy(img, buf, size); // 把要写入的数据复制到新请求的内存地址 + for (int i = 0; i != (alloc_size / get_dm(vfs).ClustnoBytes); i++) { + uint32_t sec = (get_dm(vfs).FileDataAddress + + (clustno - 2) * get_dm(vfs).ClustnoBytes) / + get_dm(vfs).SectorBytes; + Disk_Write(sec, get_dm(vfs).ClustnoBytes / get_dm(vfs).SectorBytes, + img + i * get_dm(vfs).ClustnoBytes, vfs->disk_number); + clustno = fat[clustno]; + } + kfree(img, alloc_size); + if (size < + clustall * + get_dm(vfs).ClustnoBytes) { // 新大小 < (旧大小 / 簇大小) * 簇大小 + // 分配Fat(中间情况没必要分配) + int i = old_clustno; + for (int size1 = clustall * get_dm(vfs).ClustnoBytes; size1 > size; + size1 -= get_dm(vfs).ClustnoBytes) { + fat[i] = 0; + ff[i] = 0; + for (int j = 0; j != get_dm(vfs).FatMaxTerms; j++) { + if (fat[j] == i) { + i = j; + } + } + } + old_clustno = i; + fat[old_clustno] = end; + ff[old_clustno] = 1; + } + file_savefat(fat, 0, get_dm(vfs).FatMaxTerms, vfs); +} + +void file_savefat(int *fat, int clustno, int length, vfs_t *vfs) { + unsigned char *img = get_dm(vfs).ADR_DISKIMG + get_dm(vfs).Fat1Address; + int size, sec; + if (get_dm(vfs).type == 12) { + for (int i = 0; i <= length; i++) { + if ((clustno + i) % 2 == 0) { + img[(clustno + i) * 3 / 2 + 0] = fat[clustno + i] & 0xff; + img[(clustno + i) * 3 / 2 + 1] = + (fat[clustno + i] >> 8 | (img[(clustno + i) * 3 / 2 + 1] & 0xf0)) & + 0xff; + } else if ((clustno + i) % 2 != 0) { + img[(clustno + i - 1) * 3 / 2 + 1] = + ((img[(clustno + i - 1) * 3 / 2 + 1] & 0x0f) | fat[clustno + i] + << 4) & + 0xff; + img[(clustno + i - 1) * 3 / 2 + 2] = (fat[clustno + i] >> 4) & 0xff; + } + } + size = length * 3 / 2 - 1; + sec = clustno * 3 / 2; + } else if (get_dm(vfs).type == 16) { + for (int i = 0; i <= length; i++) { + img[(clustno + i) * 2 + 0] = fat[clustno + i] & 0xff; + img[(clustno + i) * 2 + 1] = (fat[clustno + i] >> 8) & 0xff; + } + size = length * 2 - 1; + sec = clustno * 2; + } else if (get_dm(vfs).type == 32) { + for (int i = 0; i <= length; i++) { + img[(clustno + i) * 4 + 0] = fat[clustno + i] & 0xff; + img[(clustno + i) * 4 + 1] = (fat[clustno + i] >> 8) & 0xff; + img[(clustno + i) * 4 + 2] = (fat[clustno + i] >> 16) & 0xff; + img[(clustno + i) * 4 + 3] = fat[clustno + i] >> 24; + } + size = length * 4 - 1; + sec = clustno * 4; + } + Disk_Write((get_dm(vfs).Fat1Address + sec) / get_dm(vfs).SectorBytes, + size / get_dm(vfs).SectorBytes + 1, + get_dm(vfs).ADR_DISKIMG + get_dm(vfs).Fat1Address, + vfs->disk_number); + Disk_Write((get_dm(vfs).Fat2Address + sec) / get_dm(vfs).SectorBytes, + size / get_dm(vfs).SectorBytes + 1, + get_dm(vfs).ADR_DISKIMG + get_dm(vfs).Fat2Address, + vfs->disk_number); +} + +struct FAT_FILEINFO *file_search(char *name, struct FAT_FILEINFO *finfo, + int max) { + int i, j; + char s[12]; + for (j = 0; j < 11; j++) { + s[j] = ' '; + } + j = 0; + for (i = 0; name[i] != 0; i++) { + if (j >= 11) { + return 0; //没有找到 + } + if (name[i] == '.' && j <= 8) { + j = 8; + } else { + s[j] = name[i]; + if ('a' <= s[j] && s[j] <= 'z') { + //将小写字母转换为大写字母 + s[j] -= 0x20; + } + j++; + } + } + for (i = 0; i < max;) { + if (finfo[i].name[0] == 0x00) { + break; + } + if ((finfo[i].type & 0x18) == 0) { + for (j = 0; j < 11; j++) { + if (finfo[i].name[j] != s[j]) { + goto next; + } + } + return finfo + i; //找到文件 + } + next: + i++; + } + return 0; //没有找到 +} +struct FAT_FILEINFO *dict_search(char *name, struct FAT_FILEINFO *finfo, + int max) { + int i, j; + char s[12]; + for (j = 0; j < 11; j++) { + s[j] = ' '; + } + j = 0; + for (i = 0; name[i] != 0; i++) { + if (j >= 11) { + return 0; //没有找到 + } else { + s[j] = name[i]; + if ('a' <= s[j] && s[j] <= 'z') { + //将小写字母转换为大写字母 + s[j] -= 0x20; + } + j++; + } + } + for (i = 0; i < max;) { + if (finfo[i].name[0] == 0x00) { + break; + } + if (finfo[i].type == 0x10) { + for (j = 0; j < 11; j++) { + if (finfo[i].name[j] != s[j]) { + goto next; + } + } + return finfo + i; // 找到文件 + } + next: + i++; + } + return 0; //没有找到 +} +struct FAT_FILEINFO *Get_File_Address(char *path1, vfs_t *vfs) { + // TODO: Modifly it + struct FAT_FILEINFO *bmpDict = get_now_dir(vfs); + int drive_number = vfs->disk_number; + char *path = (char *)page_malloc(strlen(path1) + 1); + char *bmp = path; + strcpy(path, path1); + strtoupper(path); + if (strncmp("/", path, 1) == 0) { + path += 1; + bmpDict = get_dm(vfs).root_directory; + } + if (path[0] == '\\' || path[0] == '/') { + //跳过反斜杠和正斜杠 + for (int i = 0; i < strlen(path); i++) { + if (path[i] != '\\' && path[i] != '/') { + path += i; + break; + } + } + } + char *temp_name = (char *)kmalloc(128); + struct FAT_FILEINFO *finfo = get_dm(vfs).root_directory; + int i = 0; + while (1) { + int j; + for (j = 0; i < strlen(path); i++, j++) { + if (path[i] == '\\' || path[i] == '/') { + temp_name[j] = '\0'; + i++; + break; + } + temp_name[j] = path[i]; + } + finfo = dict_search(temp_name, bmpDict, get_directory_max(bmpDict, vfs)); + if (finfo == 0) { + if (path[i] != '\0') { + kfree((void *)temp_name, 128); + kfree((void *)bmp, strlen(path1) + 1); + return 0; + } + finfo = file_search(temp_name, bmpDict, get_directory_max(bmpDict, vfs)); + if (finfo == 0) { + kfree((void *)temp_name, 128); + kfree((void *)bmp, strlen(path1) + 1); + return 0; + } else { + goto END; + } + } else { + if (get_clustno(finfo->clustno_high, finfo->clustno_low) != 0) { + for (int count = 1; + FindForCount(count, get_dm(vfs).directory_clustno_list) != NULL; + count++) { + struct List *list = + FindForCount(count, get_dm(vfs).directory_clustno_list); + if (get_clustno(finfo->clustno_high, finfo->clustno_low) == + list->val) { + list = FindForCount(count, get_dm(vfs).directory_list); + bmpDict = (struct FAT_FILEINFO *)list->val; + break; + } + } + } else { + bmpDict = get_dm(vfs).root_directory; + } + clean(temp_name, 128); + } + } + END: + kfree((void *)temp_name, 128); + kfree((void *)bmp, strlen(path1) + 1); + return finfo; +} +*/ \ No newline at end of file diff --git a/kernel/idt.c b/kernel/idt.c index c9693df..2231a32 100644 --- a/kernel/idt.c +++ b/kernel/idt.c @@ -9,7 +9,7 @@ idt_ptr_t idt_ptr; extern void idt_flush(uint32_t); -static void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { +void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { idt_entries[num].base_low = base & 0xFFFF; idt_entries[num].base_high = (base >> 16) & 0xFFFF; // 拆成低位和高位 diff --git a/kernel/kernel.c b/kernel/kernel.c index 61e38ac..799cd86 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -12,12 +12,16 @@ #include "../include/date.h" #include "../include/acpi.h" #include "../include/syscall.h" +#include "../include/vdisk.h" +#include "../include/pci.h" +#include "../include/pcnet.h" extern uint32_t end; extern int status; uint32_t placement_address = (uint32_t) & end; multiboot_t *multiboot_all; + void reset_kernel(){ printf("Restart %s for x86...\n",OS_NAME); kill_all_task(); @@ -37,7 +41,6 @@ uint32_t memory_all(){ } void kernel_main(multiboot_t *multiboot) { - multiboot_all = multiboot; io_cli(); vga_install(); if ((multiboot->mem_upper + multiboot->mem_lower) / 1024 + 1 < 16) { @@ -60,8 +63,15 @@ void kernel_main(multiboot_t *multiboot) { printf("[\035kernel\036]: task load success!\n"); init_keyboard(); printf("[\035kernel\036]: Keyboard driver load success!\n"); - + multiboot_all = multiboot; + init_vdisk(); + init_pci(); syscall_install(); + + if(pcnet_find_card()){ + init_pcnet_card(); + } else printf("[\035kernel\036]: \033Cannot found pcnet.\036\n"); + print_cpu_id(); io_sti(); @@ -69,7 +79,7 @@ void kernel_main(multiboot_t *multiboot) { clock_sleep(25); - kernel_thread(setup_shell, NULL, "CPOS-Shell"); + //kernel_thread(setup_shell, NULL, "CPOS-Shell"); launch_date(); for (;;) { diff --git a/kernel/memory.c b/kernel/memory.c index d3e170b..ec9943b 100644 --- a/kernel/memory.c +++ b/kernel/memory.c @@ -1,5 +1,13 @@ #include "../include/memory.h" +void memclean(char *s, int len) { + // 清理某个内存区域(全部置0) + int i; + for (i = 0; i != len; i++) { + s[i] = 0; + } + return; +} void *memcpy(void *dst_, const void *src_, uint32_t size) { uint8_t *dst = dst_; diff --git a/util/list.c b/util/list.c new file mode 100644 index 0000000..8ab86aa --- /dev/null +++ b/util/list.c @@ -0,0 +1,21 @@ +#include "../include/list.h" + +int GetLastCount(struct List* Obj) { + return Obj->ctl->all; +} + +struct List* FindForCount(size_t count, struct List* Obj) { + int count_last = GetLastCount(Obj); + struct List *p = Obj, *q = Obj->ctl->end; + if (count > count_last) + return (List*)NULL; + for (int i = 0, j = count_last;; i++, j--) { + if (i == count) { + return p; + } else if (j == count) { + return q; + } + p = p->next; + q = q->prev; + } +} diff --git a/util/printf.c b/util/printf.c index d3b3ac8..0d29165 100644 --- a/util/printf.c +++ b/util/printf.c @@ -1,5 +1,6 @@ #include "../include/printf.h" #include "../include/common.h" +#include "../include/graphics.h" static int skip_atoi(const char **s) { int i = 0; @@ -278,4 +279,19 @@ int sprintf(char *buf, const char *fmt, ...) { i = vsprintf(buf, fmt, args); va_end(args); return i; +} + + +void printf(const char *formet, ...) { + int len; + va_list ap; + va_start(ap, formet); + char *buf[1024] = {0}; + len = vsprintf(buf, formet, ap); + print(buf); + va_end(ap); +} + +void print(char *message) { + vga_writestring(message); } \ No newline at end of file