文件系统修复

This commit is contained in:
xiaoyi1212 2024-05-18 23:44:25 +08:00
parent f1f2a45882
commit 9221f2e106
25 changed files with 2557 additions and 345 deletions

View File

@ -1,7 +1,7 @@
import os import os
import sys import sys
gcc = '/i686_elf_tools/bin/i686-elf-gcc.exe -std=gnu99 -I include/ -std=gnu99 -ffreestanding -O2 -c -Wincompatible-pointer-types' gcc = '/i686_elf_tools/bin/i686-elf-gcc.exe -w -std=gnu99 -I include/ -std=gnu99 -ffreestanding -O0 -c -Wincompatible-pointer-types'
asm = '/i686_elf_tools/bin/i686-elf-as.exe' asm = '/i686_elf_tools/bin/i686-elf-as.exe'
nasm = "nasm -f elf32" nasm = "nasm -f elf32"
ld = '/i686_elf_tools/bin/i686-elf-ld.exe' ld = '/i686_elf_tools/bin/i686-elf-ld.exe'
@ -127,7 +127,7 @@ print("Launching i386 vm...")
if len(sys.argv) == 0 or sys.argv[1] == 'vga': if len(sys.argv) == 0 or sys.argv[1] == 'vga':
print("Graphics MODE [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") os.system("qemu-system-i386 -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -hda diskx.img")
elif sys.argv[1] == 'vbe': elif sys.argv[1] == 'vbe':
print("Graphics MODE [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") os.system("qemu-system-i386 -vga std -net nic,model=pcnet -net user -kernel isodir\\sys\\kernel.elf -hda diskx.img")

View File

@ -8,7 +8,6 @@
static inline nul(char *f, ...) {} static inline nul(char *f, ...) {}
#define logk nul #define logk nul
#define inb io_in8 #define inb io_in8
#define outb io_out8 #define outb io_out8
@ -46,12 +45,134 @@ static inline void insl(uint32_t port, uint32_t *addr, int cnt) {
static void Read(char drive, unsigned char *buffer, unsigned int number, static void Read(char drive, unsigned char *buffer, unsigned int number,
unsigned int lba) { unsigned int lba) {
ide_read_sectors(drive - 'C', number, lba, 1 * 8, buffer); ide_read_sectors(drive - 'A', number, lba, 1 * 8, buffer);
} }
static void Write(char drive, unsigned char *buffer, unsigned int number, static void Write(char drive, unsigned char *buffer, unsigned int number,
unsigned int lba) { unsigned int lba) {
ide_write_sectors(drive - 'C', number, lba, 1 * 8, buffer); ide_write_sectors(drive - 'A', number, lba, 1 * 8, buffer);
}
void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
unsigned int BAR3, unsigned int BAR4) {
int j, k, count = 0;
for (int i = 0; i < 4; i++) {
ide_devices[i].Reserved = 0;
}
// 1- Detect I/O Ports which interface IDE Controller:
channels[ATA_PRIMARY].base = (BAR0 & 0xFFFFFFFC) + 0x1F0 * (!BAR0);
channels[ATA_PRIMARY].ctrl = (BAR1 & 0xFFFFFFFC) + 0x3F6 * (!BAR1);
channels[ATA_SECONDARY].base = (BAR2 & 0xFFFFFFFC) + 0x170 * (!BAR2);
channels[ATA_SECONDARY].ctrl = (BAR3 & 0xFFFFFFFC) + 0x376 * (!BAR3);
channels[ATA_PRIMARY].bmide = (BAR4 & 0xFFFFFFFC) + 0; // Bus Master IDE
channels[ATA_SECONDARY].bmide = (BAR4 & 0xFFFFFFFC) + 8; // Bus Master IDE
// 2- Disable IRQs:
ide_write(ATA_PRIMARY, ATA_REG_CONTROL, 2);
ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2);
logk("w1\n");
// 3- Detect ATA-ATAPI Devices:
for (int i = 0; i < 2; i++)
for (j = 0; j < 2; j++) {
unsigned char err = 0, type = IDE_ATA, status;
ide_devices[count].Reserved = 0; // Assuming that no drive here.
// (I) Select Drive:
ide_write(i, ATA_REG_HDDEVSEL, 0xA0 | (j << 4)); // Select Drive.
sleep(1); // Wait 1ms for drive select to work.
logk("I\n");
// (II) Send ATA Identify Command:
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
sleep(1); // This function should be implemented in your OS. which waits
// for 1 ms. it is based on System Timer Device Driver.
logk("II\n");
// (III) Polling:
if (ide_read(i, ATA_REG_STATUS) == 0)
continue; // If Status = 0, No Device.
logk("III\n");
while (1) {
logk("read ide....\n");
status = ide_read(i, ATA_REG_STATUS);
logk("read ok\n");
if ((status & ATA_SR_ERR)) {
err = 1;
break;
} // If Err, Device is not ATA.
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ))
break; // Everything is right.
}
// (IV) Probe for ATAPI Devices:
logk("IV\n");
if (err != 0) {
unsigned char cl = ide_read(i, ATA_REG_LBA1);
unsigned char ch = ide_read(i, ATA_REG_LBA2);
if (cl == 0x14 && ch == 0xEB)
type = IDE_ATAPI;
else if (cl == 0x69 && ch == 0x96)
type = IDE_ATAPI;
else
continue; // Unknown Type (may not be a device).
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY_PACKET);
sleep(1);
}
// (V) Read Identification Space of the Device:
logk("V\n");
ide_read_buffer(i, ATA_REG_DATA, (unsigned int) ide_buf, 128);
// (VI) Read Device Parameters:
logk("VI\n");
ide_devices[count].Reserved = 1;
ide_devices[count].Type = type;
ide_devices[count].Channel = i;
ide_devices[count].Drive = j;
ide_devices[count].Signature =
*((unsigned short *) (ide_buf + ATA_IDENT_DEVICETYPE));
ide_devices[count].Capabilities =
*((unsigned short *) (ide_buf + ATA_IDENT_CAPABILITIES));
ide_devices[count].CommandSets =
*((unsigned int *) (ide_buf + ATA_IDENT_COMMANDSETS));
// (VII) Get Size:
logk("VII\n");
if (ide_devices[count].CommandSets & (1 << 26))
// Device uses 48-Bit Addressing:
ide_devices[count].Size =
*((unsigned int *) (ide_buf + ATA_IDENT_MAX_LBA_EXT));
else
// Device uses CHS or 28-bit Addressing:
ide_devices[count].Size =
*((unsigned int *) (ide_buf + ATA_IDENT_MAX_LBA));
// (VIII) String indicates model of device (like Western Digital HDD and
// SONY DVD-RW...):
logk("VIII\n");
for (k = 0; k < 40; k += 2) {
ide_devices[count].Model[k] = ide_buf[ATA_IDENT_MODEL + k + 1];
ide_devices[count].Model[k + 1] = ide_buf[ATA_IDENT_MODEL + k];
}
ide_devices[count].Model[40] = 0; // Terminate String.
count++;
}
// 4- Print Summary:
vdisk vd;
for (int i = 0; i < 4; i++)
if (ide_devices[i].Reserved == 1) {
logk(" %d Found %s Drive %dMB - %s\n", i,
(const char *[]) {"ATA", "ATAPI"}[ide_devices[i].Type], /* Type */
ide_devices[i].Size / 1024 / 2, /* Size */
ide_devices[i].Model);
strcpy(vd.DriveName, ide_devices[i].Model);
vd.flag = 1;
vd.Read = Read;
vd.Write = Write;
vd.size = ide_devices[i].Size;
printf("[Disk-(%c)]: Size: %dMB | Name: %s\n", register_vdisk(vd), vd.size, vd.DriveName);
}
} }
unsigned char ide_read(unsigned char channel, unsigned char reg) { unsigned char ide_read(unsigned char channel, unsigned char reg) {
@ -70,6 +191,7 @@ unsigned char ide_read(unsigned char channel, unsigned char reg) {
ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN); ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
return result; return result;
} }
void ide_write(unsigned char channel, unsigned char reg, unsigned char data) { void ide_write(unsigned char channel, unsigned char reg, unsigned char data) {
if (reg > 0x07 && reg < 0x0C) if (reg > 0x07 && reg < 0x0C)
ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN); ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN);
@ -84,6 +206,7 @@ void ide_write(unsigned char channel, unsigned char reg, unsigned char data) {
if (reg > 0x07 && reg < 0x0C) if (reg > 0x07 && reg < 0x0C)
ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN); ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
} }
void ide_read_buffer(unsigned char channel, unsigned char reg, void ide_read_buffer(unsigned char channel, unsigned char reg,
unsigned int buffer, unsigned int quads) { unsigned int buffer, unsigned int quads) {
/* WARNING: This code contains a serious bug. The inline assembly trashes ES /* WARNING: This code contains a serious bug. The inline assembly trashes ES
@ -105,6 +228,7 @@ void ide_read_buffer(unsigned char channel, unsigned char reg,
if (reg > 0x07 && reg < 0x0C) if (reg > 0x07 && reg < 0x0C)
ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN); ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
} }
unsigned char ide_polling(unsigned char channel, unsigned int advanced_check) { unsigned char ide_polling(unsigned char channel, unsigned int advanced_check) {
// (I) Delay 400 nanosecond for BSY to be set: // (I) Delay 400 nanosecond for BSY to be set:
// ------------------------------------------------- // -------------------------------------------------
@ -119,7 +243,7 @@ unsigned char ide_polling(unsigned char channel, unsigned int advanced_check) {
while (a & ATA_SR_BSY) { while (a & ATA_SR_BSY) {
logk("a=%d\n", a & ATA_SR_BSY); // Wait for BSY to be zero. logk("a=%d\n", a & ATA_SR_BSY); // Wait for BSY to be zero.
a = ide_read(channel, ATA_REG_STATUS); a = ide_read(channel, ATA_REG_STATUS);
clock_sleep(1); sleep(1);
} }
logk("II OK\n"); logk("II OK\n");
if (advanced_check) { if (advanced_check) {
@ -198,11 +322,11 @@ unsigned char ide_print_error(unsigned int drive, unsigned char err) {
} }
printk( printk(
"- [%s %s] %s\n", "- [%s %s] %s\n",
(const char *[]){ (const char *[]) {
"Primary", "Primary",
"Secondary"}[ide_devices[drive].Channel], // Use the channel as an "Secondary"}[ide_devices[drive].Channel], // Use the channel as an
// index into the array // index into the array
(const char *[]){ (const char *[]) {
"Master", "Master",
"Slave"}[ide_devices[drive].Drive], // Same as above, using the drive "Slave"}[ide_devices[drive].Drive], // Same as above, using the drive
ide_devices[drive].Model); ide_devices[drive].Model);
@ -317,26 +441,25 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
ide_write(channel, ATA_REG_COMMAND, cmd); // Send the Command. ide_write(channel, ATA_REG_COMMAND, cmd); // Send the Command.
logk("IV1\n"); logk("IV1\n");
if (dma) if (dma)
if (direction == 0) if (direction == 0);
;
// DMA Read. // DMA Read.
else else;
;
// DMA Write. // DMA Write.
else if (direction == 0) { else if (direction == 0) {
// PIO Read. // PIO Read.
uint16_t *word_ = edi; uint16_t *word_ = edi;
for (i = 0; i < numsects; i++) { for (i = 0; i < numsects; i++) {
logk("read %d\n", i); // printf("read %d\n", i);
if (err = ide_polling(channel, 1)) if (err = ide_polling(channel, 1))
return err; // Polling, set error and exit if there is. return err; // Polling, set error and exit if there is.
logk("words=%d bus=%d\n", words, bus); logk("words=%d bus=%d\n", words, bus);
// for (int h = 0; h < words; h++) { for (int h = 0; h < words; h++) {
// unsigned short a = io_in16(bus); unsigned short a = io_in16(bus);
// word_[i * words + h] = a; word_[i * words + h] = a;
// } // printf("%04x ",a);
insl(bus, word_ + i * words, words / 2); }
//insl(bus, word_ + i * words, words / 2);
} }
} else { } else {
// PIO Write. // PIO Write.
@ -353,18 +476,19 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
} }
} }
ide_write(channel, ATA_REG_COMMAND, ide_write(channel, ATA_REG_COMMAND,
(char[]){ATA_CMD_CACHE_FLUSH, ATA_CMD_CACHE_FLUSH, (char[]) {ATA_CMD_CACHE_FLUSH, ATA_CMD_CACHE_FLUSH,
ATA_CMD_CACHE_FLUSH_EXT}[lba_mode]); ATA_CMD_CACHE_FLUSH_EXT}[lba_mode]);
ide_polling(channel, 0); // Polling. ide_polling(channel, 0); // Polling.
} }
return 0; // Easy, isn't it? return 0; // Easy, isn't it?
} }
void ide_wait_irq() { void ide_wait_irq() {
while (!ide_irq_invoked) while (!ide_irq_invoked);
;
ide_irq_invoked = 0; ide_irq_invoked = 0;
} }
void ide_irq() { void ide_irq() {
logk("ide irq.\n"); logk("ide irq.\n");
ide_irq_invoked = 1; ide_irq_invoked = 1;
@ -403,8 +527,7 @@ unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
ide_write(channel, ATA_REG_HDDEVSEL, slavebit << 4); ide_write(channel, ATA_REG_HDDEVSEL, slavebit << 4);
logk("II\n"); logk("II\n");
// (III): Delay 400 nanoseconds for select to complete: // (III): Delay 400 nanoseconds for select to complete:
for (int i = 0; i < 4000; i++) for (int i = 0; i < 4000; i++);
;
logk("III\n"); logk("III\n");
// ------------------------------------------------------------------ // ------------------------------------------------------------------
logk("IV\n"); logk("IV\n");
@ -459,11 +582,11 @@ unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
// (XI): Waiting for BSY & DRQ to clear: // (XI): Waiting for BSY & DRQ to clear:
// ------------------------------------------------------------------ // ------------------------------------------------------------------
while (ide_read(channel, ATA_REG_STATUS) & (ATA_SR_BSY | ATA_SR_DRQ)) while (ide_read(channel, ATA_REG_STATUS) & (ATA_SR_BSY | ATA_SR_DRQ));
;
return 0; // Easy, ... Isn't it? return 0; // Easy, ... Isn't it?
} }
void ide_read_sectors(unsigned char drive, unsigned char numsects, void ide_read_sectors(unsigned char drive, unsigned char numsects,
unsigned int lba, unsigned short es, unsigned int edi) { unsigned int lba, unsigned short es, unsigned int edi) {
// 1: Check if the drive presents: // 1: Check if the drive presents:
@ -491,7 +614,7 @@ void ide_read_sectors(unsigned char drive, unsigned char numsects,
package[0] = ide_print_error(drive, err); package[0] = ide_print_error(drive, err);
} }
} }
// package[0] is an entry of an array. It contains the Error Code.
void ide_write_sectors(unsigned char drive, unsigned char numsects, void ide_write_sectors(unsigned char drive, unsigned char numsects,
unsigned int lba, unsigned short es, unsigned int edi) { unsigned int lba, unsigned short es, unsigned int edi) {
// 1: Check if the drive presents: // 1: Check if the drive presents:
@ -575,7 +698,7 @@ void ide_atapi_eject(unsigned char drive) {
// (VI): Sending the packet data: // (VI): Sending the packet data:
// ------------------------------------------------------------------ // ------------------------------------------------------------------
asm("rep outsw" ::"c"(6), "d"(bus), asm("rep outsw"::"c"(6), "d"(bus),
"S"(atapi_packet)); // Send Packet Data "S"(atapi_packet)); // Send Packet Data
ide_wait_irq(); // Wait for an IRQ. ide_wait_irq(); // Wait for an IRQ.
err = ide_polling(channel, 1); // Polling and get error code. err = ide_polling(channel, 1); // Polling and get error code.
@ -585,151 +708,3 @@ void ide_atapi_eject(unsigned char drive) {
package[0] = ide_print_error(drive, err); // Return; package[0] = ide_print_error(drive, err); // Return;
} }
} }
void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
unsigned int BAR3, unsigned int BAR4) {
int i1, j1, k1;
int flag = 0;
for (i1 = 0; i1 < 255; i1++) {
for (j1 = 0; j1 < 32; j1++) {
for (k1 = 0; k1 < 8; k1++) {
uint32_t p = read_pci(i1, j1, k1, 0x8);
uint16_t *reg =
&p; // reg[0] ---> P & R, reg[1] ---> Sub Class Class Code
uint8_t *codes =
&(reg[1]); // codes[0] --> Sub Class Code codes[1] Class Code
if (codes[1] == 0x1 && codes[0] == 0x1) {
flag = 1;
goto OK;
}
}
}
}
OK:
if (flag == 0) {
return;
}
BAR0 = read_bar_n(i1, j1, k1, 0);
BAR1 = read_bar_n(i1, j1, k1, 1);
BAR2 = read_bar_n(i1, j1, k1, 2);
BAR3 = read_bar_n(i1, j1, k1, 3);
BAR4 = read_bar_n(i1, j1, k1, 4);
int j, k, count = 0;
for (int i = 0; i < 4; i++) {
ide_devices[i].Reserved = 0;
}
// 1- Detect I/O Ports which interface IDE Controller:
channels[ATA_PRIMARY].base = (BAR0 & 0xFFFFFFFC) + 0x1F0 * (!BAR0);
channels[ATA_PRIMARY].ctrl = (BAR1 & 0xFFFFFFFC) + 0x3F6 * (!BAR1);
channels[ATA_SECONDARY].base = (BAR2 & 0xFFFFFFFC) + 0x170 * (!BAR2);
channels[ATA_SECONDARY].ctrl = (BAR3 & 0xFFFFFFFC) + 0x376 * (!BAR3);
channels[ATA_PRIMARY].bmide = (BAR4 & 0xFFFFFFFC) + 0; // Bus Master IDE
channels[ATA_SECONDARY].bmide = (BAR4 & 0xFFFFFFFC) + 8; // Bus Master IDE
// 2- Disable IRQs:
ide_write(ATA_PRIMARY, ATA_REG_CONTROL, 2);
ide_write(ATA_SECONDARY, ATA_REG_CONTROL, 2);
logk("w1\n");
// 3- Detect ATA-ATAPI Devices:
for (int i = 0; i < 2; i++)
for (j = 0; j < 2; j++) {
unsigned char err = 0, type = IDE_ATA, status;
ide_devices[count].Reserved = 0; // Assuming that no drive here.
// (I) Select Drive:
ide_write(i, ATA_REG_HDDEVSEL, 0xA0 | (j << 4)); // Select Drive.
clock_sleep(1); // Wait 1ms for drive select to work.
logk("I\n");
// (II) Send ATA Identify Command:
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
clock_sleep(1); // This function should be implemented in your OS. which waits
// for 1 ms. it is based on System Timer Device Driver.
logk("II\n");
// (III) Polling:
if (ide_read(i, ATA_REG_STATUS) == 0)
continue; // If Status = 0, No Device.
logk("III\n");
while (1) {
logk("read ide....\n");
status = ide_read(i, ATA_REG_STATUS);
logk("read ok\n");
if ((status & ATA_SR_ERR)) {
err = 1;
break;
} // If Err, Device is not ATA.
if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ))
break; // Everything is right.
}
// (IV) Probe for ATAPI Devices:
logk("IV\n");
if (err != 0) {
unsigned char cl = ide_read(i, ATA_REG_LBA1);
unsigned char ch = ide_read(i, ATA_REG_LBA2);
if (cl == 0x14 && ch == 0xEB)
type = IDE_ATAPI;
else if (cl == 0x69 && ch == 0x96)
type = IDE_ATAPI;
else
continue; // Unknown Type (may not be a device).
ide_write(i, ATA_REG_COMMAND, ATA_CMD_IDENTIFY_PACKET);
clock_sleep(1);
}
// (V) Read Identification Space of the Device:
logk("V\n");
ide_read_buffer(i, ATA_REG_DATA, (unsigned int)ide_buf, 128);
// (VI) Read Device Parameters:
logk("VI\n");
ide_devices[count].Reserved = 1;
ide_devices[count].Type = type;
ide_devices[count].Channel = i;
ide_devices[count].Drive = j;
ide_devices[count].Signature =
*((unsigned short *)(ide_buf + ATA_IDENT_DEVICETYPE));
ide_devices[count].Capabilities =
*((unsigned short *)(ide_buf + ATA_IDENT_CAPABILITIES));
ide_devices[count].CommandSets =
*((unsigned int *)(ide_buf + ATA_IDENT_COMMANDSETS));
// (VII) Get Size:
logk("VII\n");
if (ide_devices[count].CommandSets & (1 << 26))
// Device uses 48-Bit Addressing:
ide_devices[count].Size =
*((unsigned int *)(ide_buf + ATA_IDENT_MAX_LBA_EXT));
else
// Device uses CHS or 28-bit Addressing:
ide_devices[count].Size =
*((unsigned int *)(ide_buf + ATA_IDENT_MAX_LBA));
// (VIII) String indicates model of device (like Western Digital HDD and
// SONY DVD-RW...):
logk("VIII\n");
for (k = 0; k < 40; k += 2) {
ide_devices[count].Model[k] = ide_buf[ATA_IDENT_MODEL + k + 1];
ide_devices[count].Model[k + 1] = ide_buf[ATA_IDENT_MODEL + k];
}
ide_devices[count].Model[40] = 0; // Terminate String.
count++;
}
// 4- Print Summary:
vdisk vd;
for (int i = 0; i < 4; i++)
if (ide_devices[i].Reserved == 1) {
logk(" %d Found %s Drive %dMB - %s\n", i,
(const char *[]){"ATA", "ATAPI"}[ide_devices[i].Type], /* Type */
ide_devices[i].Size / 1024 / 2, /* Size */
ide_devices[i].Model);
strcpy(vd.DriveName, ide_devices[i].Model);
vd.flag = 1;
vd.Read = Read;
vd.Write = Write;
vd.size = ide_devices[i].Size;
printf("[Disk (%c)]: Size: %dMB Name: %s\n",register_vdisk(vd),vd.size,vd.DriveName);
}
}

View File

@ -90,7 +90,7 @@ unsigned char shift_keyboard_map[128] =
static void default_handle(uint32_t key,int release,char c){ static void default_handle(uint32_t key,int release,char c){
if(!release) { if(!release) {
if(c == -1) { if(key == 42) {
key_status->is_shift = 1; key_status->is_shift = 1;
return 0; return 0;
} }
@ -106,7 +106,7 @@ static void default_handle(uint32_t key,int release,char c){
queue_push(key_char_queue,(char)c); queue_push(key_char_queue,(char)c);
} else { } else {
if(c == -1){ if(key == -86){
key_status->is_shift = 0; key_status->is_shift = 0;
} }
@ -125,6 +125,7 @@ void init_keyboard(){
head_listener = (struct key_listener*) kmalloc(sizeof(struct key_listener)); head_listener = (struct key_listener*) kmalloc(sizeof(struct key_listener));
head_listener->func = default_handle; head_listener->func = default_handle;
head_listener->lid = 0; head_listener->lid = 0;
head_listener->next = NULL;
register_interrupt_handler(0x21,handle_keyboard_input); register_interrupt_handler(0x21,handle_keyboard_input);
} }

View File

@ -10,30 +10,27 @@
int getReadyDisk(); int getReadyDisk();
vdisk vdisk_ctl[10]; vdisk vdisk_ctl[26];
int init_vdisk() { int init_vdisk() {
for (int i = 0; i < 10; i++) { for (int i = 0; i < 26; i++) {
vdisk_ctl[i].flag = 0; // 设置为未使用 vdisk_ctl[i].flag = 0; // 设置为未使用
} }
printf("[\035kernel\036]: VDisk driver load success!\n");
return 0;
} }
int register_vdisk(vdisk vd) { int register_vdisk(vdisk vd) {
for (int i = 0; i < 10; i++) { for (int i = 0; i < 26; i++) {
if (!vdisk_ctl[i].flag) { if (!vdisk_ctl[i].flag) {
vdisk_ctl[i] = vd; // 找到了! vdisk_ctl[i] = vd; // 找到了!
return i + ('A'); // 注册成功返回drive return i + ('A'); // 注册成功返回drive
} }
} }
printf("[vdisk]not found\n"); printk("[vdisk]not found\n");
return 0; // 注册失败 return 0; // 注册失败
} }
int logout_vdisk(char drive) { int logout_vdisk(char drive) {
int indx = drive - ('A'); int indx = drive - ('A');
if (indx > 10) { if (indx > 26) {
return 0; // 失败 return 0; // 失败
} }
if (vdisk_ctl[indx].flag) { if (vdisk_ctl[indx].flag) {
@ -43,17 +40,15 @@ int logout_vdisk(char drive) {
return 0; // 失败 return 0; // 失败
} }
} }
int rw_vdisk(char drive, unsigned int lba, unsigned char *buffer, int rw_vdisk(char drive, unsigned int lba, unsigned char *buffer,
unsigned int number, int read) { unsigned int number, int read) {
int indx = drive - ('A'); int indx = drive - ('A');
if (indx > 10) { if (indx > 26) {
return 0; // 失败 return 0; // 失败
} }
if (vdisk_ctl[indx].flag) { if (vdisk_ctl[indx].flag) {
if (read) { if (read) {
vdisk_ctl[indx].Read(drive, buffer, number, lba); vdisk_ctl[indx].Read(drive, buffer, number, lba);
//for(;;);
} else { } else {
vdisk_ctl[indx].Write(drive, buffer, number, lba); vdisk_ctl[indx].Write(drive, buffer, number, lba);
} }
@ -62,10 +57,10 @@ int rw_vdisk(char drive, unsigned int lba, unsigned char *buffer,
return 0; // 失败 return 0; // 失败
} }
} }
bool have_vdisk(char drive) {
int have_vdisk(char drive) {
int indx = drive - 'A'; int indx = drive - 'A';
if (indx > 10) { // printk("drive=%c\n",drive);
if (indx > 26) {
return 0; // 失败 return 0; // 失败
} }
if (vdisk_ctl[indx].flag) { if (vdisk_ctl[indx].flag) {
@ -74,63 +69,23 @@ int have_vdisk(char drive) {
return 0; // 失败 return 0; // 失败
} }
} }
// 基于vdisk的通用读写
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);
}
}
}
static unsigned char *drive_name[16] = {NULL, NULL, NULL, NULL, NULL, NULL, static unsigned char *drive_name[16] = {NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL}; NULL, NULL, NULL, NULL};
static struct FIFO8 drive_fifo[16]; static struct FIFO8 drive_fifo[16];
static unsigned char drive_buf[16][256]; static unsigned char drive_buf[16][256];
bool SetDrive(unsigned char *name) { bool SetDrive(unsigned char *name) {
for (int i = 0; i != 16; i++) { for (int i = 0; i != 16; i++) {
if (drive_name[i] == NULL) { if (drive_name[i] == NULL) {
drive_name[i] = name; drive_name[i] = name;
fifo8_init(&drive_fifo[i], 256, drive_buf[i]); fifo8_init(&drive_fifo[i], 256, drive_buf[i]);
return 1; return true;
} }
} }
return 0; return false;
} }
unsigned int GetDriveCode(unsigned char *name) { unsigned int GetDriveCode(unsigned char *name) {
for (int i = 0; i != 16; i++) { for (int i = 0; i != 16; i++) {
if (strcmp((char *)drive_name[i], (char *)name) == 0) { if (strcmp((char *)drive_name[i], (char *)name) == 0) {
@ -141,24 +96,48 @@ unsigned int GetDriveCode(unsigned char *name) {
} }
bool DriveSemaphoreTake(unsigned int drive_code) { bool DriveSemaphoreTake(unsigned int drive_code) {
if (drive_code >= 16) { return true;
return 1;
}
fifo8_put(&drive_fifo[drive_code], get_current()->pid);
// printk("FIFO: %d PUT: %d STATUS: %d\n", drive_code, Get_Tid(current_task()),
// fifo8_status(&drive_fifo[drive_code]));
while (drive_buf[drive_code][drive_fifo[drive_code].q] !=
get_current()->pid) {
// printk("Waiting....\n");
}
return 1;
} }
void DriveSemaphoreGive(unsigned int drive_code) { void DriveSemaphoreGive(unsigned int drive_code) {
if (drive_code >= 16) {
return; return;
} }
if (drive_buf[drive_code][drive_fifo[drive_code].q] != get_current()->pid) {
return; void Disk_Read(unsigned int lba, unsigned int number, void *buffer,
} char drive) {
fifo8_get(&drive_fifo[drive_code]); if (have_vdisk(drive)) {
if (DriveSemaphoreTake(GetDriveCode((unsigned char *)"DISK_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);
}
DriveSemaphoreGive(GetDriveCode((unsigned char *)"DISK_DRIVE"));
}
}
}
unsigned int disk_Size(char drive) {
unsigned char drive1 = drive;
if (have_vdisk(drive1)) {
int indx = drive1 - 'A';
return vdisk_ctl[indx].size;
} else {
return 0;
}
return 0;
}
bool DiskReady(char drive) { return have_vdisk(drive); }
int getReadyDisk() { return 0; }
void Disk_Write(unsigned int lba, unsigned int number, void *buffer,
char drive) {
// printk("%d\n",lba);
if (have_vdisk(drive)) {
if (DriveSemaphoreTake(GetDriveCode((unsigned char *)"DISK_DRIVE"))) {
// printk("*buffer(%d %d) = %02x\n",lba,number,*(unsigned char *)buffer);
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);
}
DriveSemaphoreGive(GetDriveCode((unsigned char *)"DISK_DRIVE"));
}
}
} }

1302
fs/fat.c Normal file

File diff suppressed because it is too large Load Diff

328
fs/iso9660.c Normal file
View File

@ -0,0 +1,328 @@
#include "../include/iso9660.h"
#include "../include/memory.h"
#include "../include/vfs.h"
#include "../include/vdisk.h"
#define l9660_seekdir(dir, pos) (l9660_seek(&(dir)->file, L9660_SEEK_SET, (pos)))
#define l9660_telldir(dir) (l9660_tell(&(dir)->file))
#define SEEK_END L9660_SEEK_END
#define SEEK_SET L9660_SEEK_SET
#define SEEK_CUR L9660_SEEK_CUR
#define DENT_EXISTS (1 << 0)
#define DENT_ISDIR (1 << 1)
#define DENT_ASSOCIATED (1 << 2)
#define DENT_RECORD (1 << 3)
#define DENT_PROTECTION (1 << 4)
#define DENT_MULTIEXTENT (1 << 5)
#define PVD(vdesc) ((l9660_vdesc_primary*)(vdesc))
#ifdef L9660_BIG_ENDIAN
#define READ16(v) (((v).be[1]) | ((v).be[0] << 8))
#define READ32(v) (((v).be[3]) | ((v).be[2] << 8) | ((v).be[1]) << 16 | ((v).be[0] << 24))
#else
#define READ16(v) (((v).le[0]) | ((v).le[1] << 8))
#define READ32(v) (((v).le[0]) | ((v).le[1] << 8) | ((v).le[2]) << 16 | ((v).le[3] << 24))
#endif
#ifndef L9660_SINGLEBUFFER
#define HAVEBUFFER(f) (true)
#define BUF(f) ((f)->buf)
#else
#define HAVEBUFFER(f) ((f) == last_file)
#define BUF(f) (gbuf)
static l9660_file *last_file;
static char gbuf[2048];
#endif
l9660_fs *fs;
static char *strchrnul(const char *s, int c) {
while (*s) {
if ((*s++) == c)
break;
}
return (char *) s;
}
static inline uint16_t
fsectoff(l9660_file
*f)
{
return f->position % 2048;
}
static inline uint32_t
fsector(l9660_file
*f)
{
return f->position / 2048;
}
static inline uint32_t
fnextsectpos(l9660_file
*f)
{
return (f->position + 2047) & ~2047;
}
l9660_status l9660_openfs(l9660_fs *fs, bool (*read_sector)(l9660_fs *fs, void *buf, uint32_t sector,uint8_t disk_number),uint8_t disk_number){
fs->
read_sector = read_sector;
#ifndef L9660_SINGLEBUFFER
l9660_vdesc_primary *pvd = PVD(&fs->pvd);
#else
last_file = NULL;
l9660_vdesc_primary *pvd = PVD(gbuf);
#endif
uint32_t idx = 0x10;
for (;;) {
// Read next sector
if (!
read_sector(fs, pvd, idx, disk_number
))
return
L9660_EIO;
// Validate magic
if (
memcmp(pvd
->hdr.magic, "CD001", 5) != 0)
return
L9660_EBADFS;
if (pvd->hdr.type == 1)
break; // Found PVD
else if(pvd->hdr.type == 255)
return
L9660_EBADFS;
}
#ifdef L9660_SINGLEBUFFER
memcpy(&fs->root_dir_ent, &pvd->root_dir_ent, pvd->root_dir_ent.length);
#endif
return
L9660_OK;
}
l9660_status l9660_fs_open_root(l9660_dir *dir, l9660_fs *fs) {
l9660_file * f = &dir->file;
#ifndef L9660_SINGLEBUFFER
l9660_dirent *dirent = &PVD(&fs->pvd)->root_dir_ent;
#else
l9660_dirent *dirent = &fs->root_dir_ent;
#endif
f->fs = fs;
f->first_sector = READ32(dirent->sector);
f->length = READ32(dirent->size);
f->position = 0;
return L9660_OK;
}
static l9660_status buffer(l9660_file *f) {
#ifdef L9660_SINGLEBUFFER
last_file = f;
#endif
if (!f->fs->read_sector(f->fs, BUF(f), f->first_sector + f->position / 2048))
return L9660_EIO;
else
return L9660_OK;
}
static l9660_status prebuffer(l9660_file *f) {
if (!HAVEBUFFER(f) || (f->position % 2048) == 0)
return buffer(f);
else return L9660_OK;
}
static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char *name, bool isdir) {
l9660_status rv;
l9660_dirent *dent = NULL;
if ((rv = l9660_seekdir(parent, 0))) return rv;
do {
const char *seg = name;
name = strchrnul(name, '/');
size_t seglen = name - seg;
/* ISO9660 stores '.' as '\0' */
if (seglen == 1 && *seg == '.')
seg = "\0";
/* ISO9660 stores ".." as '\1' */
if (seglen == 2 && seg[0] == '.' && seg[1] == '.') {
seg = "\1";
seglen = 1;
}
for (;;) {
if ((rv = l9660_readdir(parent, &dent)))
return rv;
/* EOD */
if (!dent)
return L9660_ENOENT;
#ifdef DEBUG
print_dirent(dent);
#endif
/* wrong length */
if (seglen > dent->name_len)
continue;
/* check name */
if (memcmp(seg, dent->name, seglen) != 0)
continue;
/* check for a revision tag */
if (dent->name_len > seglen && dent->name[seglen] != ';')
continue;
/* all tests pass */
break;
}
child->fs = parent->file.fs;
child->first_sector = READ32(dent->sector) + dent->xattr_length;
child->length = READ32(dent->size);
child->position = 0;
if (*name && (dent->flags & DENT_ISDIR) != 0)
return L9660_ENOTDIR;
parent = (l9660_dir *) child;
} while (*name);
if (isdir) {
if ((dent->flags & DENT_ISDIR) == 0)
return L9660_ENOTDIR;
} else {
if ((dent->flags & DENT_ISDIR) != 0)
return L9660_ENOTFILE;
}
return L9660_OK;
}
l9660_status l9660_opendirat(l9660_dir *dir, l9660_dir *parent, const char *path) {
return openat_raw(&dir->file, parent, path, true);
}
static inline unsigned aligneven(unsigned v) {
return v + (v & 1);
}
l9660_status l9660_readdir(l9660_dir *dir, l9660_dirent **pdirent) {
l9660_status rv;
l9660_file * f = &dir->file;
rebuffer:
if (f->position >= f->length) {
*pdirent = NULL;
return L9660_OK;
}
if ((rv = prebuffer(f)))
return rv;
char *off = BUF(f) + fsectoff(f);
if (*off == 0) {
// Padded end of sector
f->position = fnextsectpos(f);
goto rebuffer;
}
l9660_dirent *dirent = (l9660_dirent *) off;
f->position += aligneven(dirent->length);
*pdirent = dirent;
return L9660_OK;
}
l9660_status l9660_openat(l9660_file *child, l9660_dir *parent, const char *name) {
return openat_raw(child, parent, name, false);
}
/*! Seek the file to \p offset from \p whence */
l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset) {
l9660_status rv;
uint32_t cursect = fsector(f);
switch (whence) {
case SEEK_SET:
f->position = offset;
break;
case SEEK_CUR:
f->position = f->position + offset;
break;
case SEEK_END:
f->position = f->length - offset;
break;
}
if (fsector(f) != cursect && fsectoff(f) != 0) {
if ((rv = buffer(f)))
return rv;
}
return L9660_OK;
}
uint32_t l9660_tell(l9660_file *f) {
return f->position;
}
l9660_status l9660_read(l9660_file *f, void *buf, size_t size, size_t *read) {
l9660_status rv;
if ((rv = prebuffer(f)))
return rv;
uint16_t rem = 2048 - fsectoff(f);
if (rem > f->length - f->position)
rem = f->length - f->position;
if (rem < size)
size = rem;
memcpy(buf, BUF(f) + fsectoff(f), size);
*read = size;
f->position += size;
return L9660_OK;
}
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector,uint8_t disk_number){
return false;
}
bool ISO_Check(uint8_t disk_number){
l9660_openfs(fs,read_sector,disk_number);
return false;
}
void ISO_InitFs(struct vfs_t *vfs, uint8_t disk_number){
}
void init_iso9660(){
vfs_t fs;
fs.flag = 1;
fs.cache = NULL;
strcpy(fs.FSName, "ISO9660");
fs.Check = ISO_Check;
fs.InitFs = ISO_InitFs;
//vfs_register_fs(fs);
}

103
fs/vfs.c
View File

@ -83,9 +83,10 @@ bool vfs_mount_disk(uint8_t disk_number, uint8_t drive) {
printf("can not find a seat of vfsMount_Stl(it's full)\n"); printf("can not find a seat of vfsMount_Stl(it's full)\n");
return false; return false;
} }
vfs_t *fs = check_disk_fs(disk_number); vfs_t *fs = check_disk_fs(disk_number);
if (!fs) { if (!fs) {
printf("unknow file system.\n"); printf("[FileSystem]: Unknown file system.\n");
return false; return false;
} }
*seat = *fs; *seat = *fs;
@ -178,6 +179,41 @@ bool vfs_delfile(char *filename) {
return result; return result;
} }
bool vfs_change_path(char *dictName) {
char *buf = kmalloc(strlen(dictName) + 1);
char *r = buf;
memcpy(buf, dictName, strlen(dictName) + 1);
int i = 0;
if (buf[i] == '/' || buf[i] == '\\') {
if (!vfs_now->cd(vfs_now, "/")) {
kfree(r);
return false;
}
i++;
buf++;
}
for (;; i++) {
if (buf[i] == '/' || buf[i] == '\\') {
buf[i] = 0;
if (!vfs_now->cd(vfs_now, buf)) {
kfree(r);
return false;
}
buf += strlen(buf) + 1;
}
if (buf[i] == 0) {
if (!vfs_now->cd(vfs_now, buf)) {
kfree(r);
return false;
}
break;
}
}
kfree(r);
return true;
}
bool vfs_deldir(char *dictname) { bool vfs_deldir(char *dictname) {
char *new_path = kmalloc(strlen(dictname) + 1); char *new_path = kmalloc(strlen(dictname) + 1);
strcpy(new_path, dictname); strcpy(new_path, dictname);
@ -206,6 +242,7 @@ bool vfs_createfile(char *filename) {
bool vfs_createdict(char *filename) { bool vfs_createdict(char *filename) {
char *new_path = kmalloc(strlen(filename) + 1); char *new_path = kmalloc(strlen(filename) + 1);
memclean(new_path, strlen(filename) + 1);
strcpy(new_path, filename); strcpy(new_path, filename);
vfs_t *vfs = ParsePath(new_path); vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) { if (vfs == NULL) {
@ -254,17 +291,41 @@ bool vfs_format(uint8_t disk_number, char *FSName) {
vfs_file *vfs_fileinfo(char *filename) { vfs_file *vfs_fileinfo(char *filename) {
char *new_path = kmalloc(strlen(filename) + 1); char *new_path = kmalloc(strlen(filename) + 1);
memclean(new_path,strlen(filename) + 1);
strcpy(new_path, filename); strcpy(new_path, filename);
vfs_t *vfs = ParsePath(new_path); vfs_t *vfs = ParsePath(new_path);
if (vfs == NULL) { if (vfs == NULL) {
kfree(new_path); kfree(new_path);
return false; return false;
} }
vfs_file *result = vfs->FileInfo(vfs, new_path); vfs_file *result = vfs->FileInfo(vfs, new_path);
kfree(new_path); kfree(new_path);
return result; return result;
} }
vfs_file *get_cur_file(char* filename){
vfs_file *file = NULL;
List *ls = vfs_listfile("");
strtoupper(filename);
for (int i = 1; FindForCount(i, ls) != NULL; i++) {
vfs_file *d = (vfs_file *) FindForCount(i, ls)->val;
if(strcmp(d->name, filename) == 0){
file = d;
break;
}
kfree(d);
}
DeleteList(ls);
kfree(ls);
return file;
}
bool vfs_change_disk(uint8_t drive) { bool vfs_change_disk(uint8_t drive) {
if (vfs_now != NULL) { if (vfs_now != NULL) {
while (FindForCount(1, vfs_now->path) != NULL) { while (FindForCount(1, vfs_now->path) != NULL) {
@ -275,10 +336,12 @@ bool vfs_change_disk(uint8_t drive) {
DeleteList(vfs_now->path); DeleteList(vfs_now->path);
kfree(vfs_now); kfree(vfs_now);
} }
vfs_t *f; vfs_t *f;
if (!(f = drive2fs(drive))) { if (!(f = drive2fs(drive))) {
return false; // 没有mount return false; // 没有mount
} }
vfs_now = kmalloc(sizeof(vfs_t)); vfs_now = kmalloc(sizeof(vfs_t));
memcpy(vfs_now, f, sizeof(vfs_t)); memcpy(vfs_now, f, sizeof(vfs_t));
f->CopyCache(vfs_now, f); f->CopyCache(vfs_now, f);
@ -287,6 +350,44 @@ bool vfs_change_disk(uint8_t drive) {
return true; return true;
} }
void vfs_getPath(char *buffer) {
char *path;
List *l;
buffer[0] = 0;
insert_char(buffer, 0, vfs_now->drive);
insert_char(buffer, 1, ':');
insert_char(buffer, 2, '\\');
int pos = strlen(buffer);
for (int i = 1; FindForCount(i, vfs_now->path) != NULL; i++) {
l = FindForCount(i, vfs_now->path);
path = (char *)l->val;
insert_str(buffer, path, pos);
pos += strlen(path);
insert_char(buffer, pos, '\\');
pos++;
}
delete_char(buffer, pos - 1);
}
void vfs_getPath_no_drive(char *buffer) {
char *path;
List *l;
buffer[0] = 0;
int pos = strlen(buffer);
int i;
for (i = 1; FindForCount(i, vfs_now->path) != NULL; i++) {
l = FindForCount(i, vfs_now->path);
path = (char *)l->val;
insert_char(buffer, pos, '/');
pos++;
insert_str(buffer, path, pos);
pos += strlen(path);
}
if (i == 1) {
insert_char(buffer, 0, '/');
}
}
void init_vfs() { void init_vfs() {
for (int i = 0; i < 26; i++) { for (int i = 0; i < 26; i++) {
vfsstl[i].flag = 0; vfsstl[i].flag = 0;

View File

@ -22,5 +22,5 @@ struct ARPMessage {
uint64_t IPParseMAC(uint32_t dstIP); uint64_t IPParseMAC(uint32_t dstIP);
uint8_t *ARP_Packet(uint64_t dest_mac, uint32_t dest_ip, uint64_t src_mac, uint8_t *ARP_Packet(uint64_t dest_mac, uint32_t dest_ip, uint64_t src_mac,
uint32_t src_ip, uint16_t command); uint32_t src_ip, uint16_t command);
void arp_handler(void *base);
#endif #endif

View File

@ -46,7 +46,7 @@ char *int64_to_str_dec(int64_t num, int flag, int width);
char *uint32_to_str_hex(uint32_t num, int flag, int width); char *uint32_to_str_hex(uint32_t num, int flag, int width);
char *uint64_to_str_hex(uint64_t num, int flag, int width); char *uint64_to_str_hex(uint64_t num, int flag, int width);
char *uint32_to_str_oct(uint32_t num, int flag, int width); char *uint32_to_str_oct(uint32_t num, int flag, int width);
char *insert_str(char *buf, const char *str); void insert_str(char *str, char *insert_str, int pos);
int vsprintf(char *buf, const char *fmt, va_list args); int vsprintf(char *buf, const char *fmt, va_list args);
int sprintf(char *buf, const char *fmt, ...); int sprintf(char *buf, const char *fmt, ...);
long int strtol(const char *str,char **endptr,int base); long int strtol(const char *str,char **endptr,int base);

110
include/fat.h Normal file
View File

@ -0,0 +1,110 @@
#ifndef CRASHPOWERDOS_FAT_H
#define CRASHPOWERDOS_FAT_H
#define BS_FileSysType 54
#define BPB_Fat32ExtByts 28
#define BS_jmpBoot 0
#define BS_OEMName 3
#define BPB_BytsPerSec 11
#define BPB_SecPerClus 13
#define BPB_RsvdSecCnt 14
#define BPB_NumFATs 16
#define BPB_RootEntCnt 17
#define BPB_TotSec16 19
#define BPB_Media 21
#define BPB_FATSz16 22
#define BPB_SecPerTrk 24
#define BPB_NumHeads 26
#define BPB_HiddSec 28
#define BPB_TotSec32 32
#define BPB_FATSz32 36
#define BPB_ExtFlags 40
#define BPB_FSVer 42
#define BPB_RootClus 44
#define BPB_FSInfo 48
#define BPB_BkBootSec 50
#define BPB_Reserved 52
#define BPB_Fat32ExtByts 28
#define BS_DrvNum 36
#define BS_Reserved1 37
#define BS_BootSig 38
#define BS_VolD 39
#define BS_VolLab 43
#define BS_FileSysType 54
#define EOF -1
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#include "list.h"
#include "vfs.h"
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;
};
struct FAT_CACHE {
unsigned int ADR_DISKIMG;
struct FAT_FILEINFO *root_directory;
struct List *directory_list;
struct List *directory_clustno_list;
struct List *directory_max_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;
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);
int changedict(char *dictname, vfs_t *vfs);
struct FAT_FILEINFO *dict_search(char *name, struct FAT_FILEINFO *finfo,
int max);
void file_savefat(int *fat, int clustno, int length, vfs_t *vfs);
void file_saveinfo(struct FAT_FILEINFO *directory, vfs_t *vfs);
void file_savefile(int clustno, int size, char *buf, int *fat,
unsigned char *ff, vfs_t *vfs);
void file_loadfile(int clustno, int size, char *buf, int *fat, vfs_t *vfs);
int deldir(char *path, vfs_t *vfs);
int del(char *cmdline, vfs_t *vfs);
int attrib(char *filename, ftype type, struct vfs_t *vfs);
int rename(char *src_name, char *dst_name, vfs_t *vfs);
int mkdir(char *dictname, int last_clust, vfs_t *vfs);
int mkfile(char *name, vfs_t *vfs);
void fat_InitFS(struct vfs_t *vfs, uint8_t disk_number);
bool Fat_Check(uint8_t disk_number);
void Fat_CopyCache(struct vfs_t *dest, struct vfs_t *src);
List *Fat_ListFile(struct vfs_t *vfs, char *dictpath);
bool Fat_WriteFile(struct vfs_t *vfs, char *path, char *buffer, int size);
bool Fat_ReadFile(struct vfs_t *vfs, char *path, char *buffer);
bool Fat_RenameFile(struct vfs_t *vfs, char *filename, char *filename_of_new);
bool Fat_CreateFile(struct vfs_t *vfs, char *filename);
void Fat_DeleteFs(struct vfs_t *vfs);
bool Fat_DelFile(struct vfs_t *vfs, char *path);
bool Fat_DelDict(struct vfs_t *vfs, char *path);
bool Fat_Format(uint8_t disk_number);
vfs_file *Fat_FileInfo(struct vfs_t *vfs, char *filename);
bool Fat_Attrib(struct vfs_t *vfs, char *filename, ftype type);
bool Fat_CreateDict(struct vfs_t *vfs, char *filename);
bool Fat_cd(struct vfs_t *vfs, char *dictName);
struct FAT_FILEINFO *Get_dictaddr(char *path1, vfs_t *vfs);
void Register_fat_fileSys();
#endif

View File

@ -73,26 +73,26 @@
#define ATA_READ 0x00 #define ATA_READ 0x00
#define ATA_WRITE 0x01 #define ATA_WRITE 0x01
void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
unsigned int BAR3, unsigned int BAR4);
unsigned char ide_read(unsigned char channel, unsigned char reg); unsigned char ide_read(unsigned char channel, unsigned char reg);
void ide_write(unsigned char channel, unsigned char reg, unsigned char data); void ide_write(unsigned char channel, unsigned char reg, unsigned char data);
void ide_read_buffer(unsigned char channel, unsigned char reg, void ide_read_buffer(unsigned char channel, unsigned char reg,
unsigned int buffer, unsigned int quads); unsigned int buffer, unsigned int quads);
unsigned char ide_polling(unsigned char channel, unsigned int advanced_check); unsigned char ide_polling(unsigned char channel, unsigned int advanced_check);
unsigned char ide_print_error(unsigned int drive, unsigned char err); unsigned char ide_print_error(unsigned int drive, unsigned char err);
void ide_wait_irq();
void ide_irq();
unsigned char ide_ata_access(unsigned char direction, unsigned char drive, unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
unsigned int lba, unsigned char numsects, unsigned int lba, unsigned char numsects,
unsigned short selector, unsigned int edi); unsigned short selector, unsigned int edi);
void ide_write_sectors(unsigned char drive, unsigned char numsects, void ide_wait_irq();
unsigned int lba, unsigned short es, unsigned int edi); void ide_irq();
void ide_read_sectors(unsigned char drive, unsigned char numsects,
unsigned int lba, unsigned short es, unsigned int edi);
unsigned char ide_atapi_read(unsigned char drive, unsigned int lba, unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
unsigned char numsects, unsigned short selector, unsigned char numsects, unsigned short selector,
unsigned int edi); unsigned int edi);
void ide_read_sectors(unsigned char drive, unsigned char numsects,
unsigned int lba, unsigned short es, unsigned int edi);
void ide_write_sectors(unsigned char drive, unsigned char numsects,
unsigned int lba, unsigned short es, unsigned int edi);
void ide_atapi_eject(unsigned char drive); void ide_atapi_eject(unsigned char drive);
void ide_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
unsigned int BAR3, unsigned int BAR4);
#endif #endif

169
include/iso9660.h Normal file
View File

@ -0,0 +1,169 @@
#ifndef CRASHPOWEROS_ISO9660_H
#define CRASHPOWEROS_ISO9660_H
#define L9660_SEEK_END -1
#define L9660_SEEK_SET 0
#define L9660_SEEK_CUR +1
#include <stdint.h>
#include <stddef.h>
#include "common.h"
typedef enum {
/*! Success! */
L9660_OK = 0,
/*! read_sector callback returned false */
L9660_EIO,
/*! file system is bad */
L9660_EBADFS,
/*! specified name does not exist */
L9660_ENOENT,
/*! attempted to open a non-file (e.g. a directory) as a file */
L9660_ENOTFILE,
/*! attempted to open a non-directory (e.g. a file) as a directory
* may be returned by l9660_openat if e.g. you pass path "a/b" and
* "a" is a file
*/
L9660_ENOTDIR,
} l9660_status;
typedef struct {
uint8_t le[2];
} l9660_luint16;
typedef struct {
uint8_t be[2];
} l9660_buint16;
typedef struct {
uint8_t le[2], be[2];
} l9660_duint16;
typedef struct {
uint8_t le[4];
} l9660_luint32;
typedef struct {
uint8_t be[4];
} l9660_buint32;
typedef struct {
uint8_t le[4], be[4];
} l9660_duint32;
/* Descriptor time format */
typedef struct {
char d[17];
} l9660_desctime;
/* File time format */
typedef struct {
char d[7];
} l9660_filetime;
/* Directory entry */
typedef struct {
uint8_t length;
uint8_t xattr_length;
l9660_duint32 sector;
l9660_duint32 size;
l9660_filetime time;
uint8_t flags;
uint8_t unit_size;
uint8_t gap_size;
l9660_duint16 vol_seq_number;
uint8_t name_len;
char name[/*name_len*/];
} l9660_dirent;
/* Volume descriptor header */
typedef struct {
uint8_t type;
char magic[5];
uint8_t version;
} l9660_vdesc_header;
/* Primary volume descriptor */
typedef struct {
l9660_vdesc_header hdr;
char pad0[1];
char system_id[32];
char volume_id[32];
char pad1[8];
l9660_duint32 volume_space_size;
char pad2[32];
l9660_duint16 volume_set_size;
l9660_duint16 volume_seq_number;
l9660_duint16 logical_block_size;
l9660_duint32 path_table_size;
l9660_luint32 path_table_le;
l9660_luint32 path_table_opt_le;
l9660_buint32 path_table_be;
l9660_buint32 path_table_opt_be;
union {
l9660_dirent root_dir_ent;
char pad3[34];
};
char volume_set_id[128];
char data_preparer_id[128];
char app_id[128];
char copyright_file[38];
char abstract_file[36];
char bibliography_file[37];
l9660_desctime volume_created,
volume_modified,
volume_expires,
volume_effective;
uint8_t file_structure_version;
char pad4[1];
char app_reserved[512];
char reserved[653];
} l9660_vdesc_primary;
/* A generic volume descriptor (i.e. 2048 bytes) */
typedef union {
l9660_vdesc_header hdr;
char _bits[2048];
} l9660_vdesc;
/* File system structure.
* Stick this inside your own structure and cast/offset as appropriate to store
* private data
*/
typedef struct l9660_fs {
#ifdef L9660_SINGLEBUFFER
union {
l9660_dirent root_dir_ent;
char root_dir_pad[34];
};
#else
/* Sector buffer to hold the PVD */
l9660_vdesc pvd;
#endif
/* read_sector func */
bool (*read_sector)(struct l9660_fs *fs, void *buf, uint32_t sector);
} l9660_fs;
typedef struct {
#ifndef L9660_SINGLEBUFFER
/* single sector buffer */
char buf[2048];
#endif
l9660_fs *fs;
uint32_t first_sector;
uint32_t position;
uint32_t length;
} l9660_file;
typedef struct {
/* directories are mostly just files with special accessors, but we like type safetey */
l9660_file file;
} l9660_dir;
uint32_t l9660_tell(l9660_file *f);
l9660_status l9660_read(l9660_file *f, void *buf, size_t size, size_t *read);
l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset);
l9660_status l9660_openat(l9660_file *child, l9660_dir *parent, const char *name);
l9660_status l9660_readdir(l9660_dir *dir, l9660_dirent **pdirent);
l9660_status l9660_opendirat(l9660_dir *dir, l9660_dir *parent, const char *path);
l9660_status l9660_fs_open_root(l9660_dir *dir, l9660_fs *fs);
l9660_status l9660_openfs(l9660_fs *fs, bool (*read_sector)(l9660_fs *fs, void *buf, uint32_t sector,uint8_t disk_number),uint8_t disk_number);
void init_iso9660();
#endif

View File

@ -28,7 +28,16 @@
#define RAP32 0x14 #define RAP32 0x14
#define RESET32 0x18 #define RESET32 0x18
#define BDP32 0x1c #define BDP32 0x1c
#define MTU 1500
#define ARP_PROTOCOL 0x806
#define IP_PROTOCOL 0x0800
#define IP_MF 13
#define IP_DF 14
#define IP_OFFSET 0
#define swap32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#define swap16(x) ((((x) & 0xff00) >> 8) | (((x) & 0x00ff) << 8))
#include <stdint.h> #include <stdint.h>
#include "isr.h" #include "isr.h"
@ -58,5 +67,6 @@ int pcnet_find_card();
void init_pcnet_card(); void init_pcnet_card();
void PCNET_IRQ(registers_t *reg); void PCNET_IRQ(registers_t *reg);
void Recv(); void Recv();
void PcnetSend(uint8_t* buffer, int size);
#endif #endif

View File

@ -27,6 +27,7 @@ void timer_free(struct TIMER *timer);
void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data); void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data);
void timer_settime(struct TIMER *timer, unsigned int timeout); void timer_settime(struct TIMER *timer, unsigned int timeout);
void clock_sleep(uint32_t timer); void clock_sleep(uint32_t timer);
void sleep(uint32_t timer);
struct TIMER *timer_alloc(void); struct TIMER *timer_alloc(void);
unsigned int time(void); unsigned int time(void);
void init_pit(void); void init_pit(void);

View File

@ -40,7 +40,7 @@ int rw_vdisk(char drive, unsigned int lba, unsigned char *buffer,
int have_vdisk(char drive); int have_vdisk(char drive);
void Disk_Read(unsigned int lba, unsigned int number, void *buffer, void Disk_Read(unsigned int lba, unsigned int number, void *buffer,
char drive); char drive);
int disk_Size(char drive); unsigned int disk_Size(char drive);
int DiskReady(char drive); int DiskReady(char drive);
void Disk_Write(unsigned int lba, unsigned int number, void *buffer, void Disk_Write(unsigned int lba, unsigned int number, void *buffer,
char drive); char drive);

View File

@ -50,6 +50,9 @@ typedef struct vfs_t {
int flag; int flag;
} vfs_t; } vfs_t;
bool vfs_change_path(char *dictName);
void vfs_getPath(char *buffer);
void vfs_getPath_no_drive(char *buffer);
bool vfs_mount_disk(uint8_t disk_number, uint8_t drive); bool vfs_mount_disk(uint8_t disk_number, uint8_t drive);
bool vfs_unmount_disk(uint8_t drive); bool vfs_unmount_disk(uint8_t drive);
bool vfs_readfile(char *path, char *buffer); bool vfs_readfile(char *path, char *buffer);
@ -67,5 +70,6 @@ vfs_file *vfs_fileinfo(char *filename);
bool vfs_change_disk(uint8_t drive); bool vfs_change_disk(uint8_t drive);
bool vfs_register_fs(vfs_t vfs); bool vfs_register_fs(vfs_t vfs);
void init_vfs(); void init_vfs();
vfs_file *get_cur_file(char* filename);
#endif #endif

View File

@ -29,9 +29,10 @@ void isr_handler(registers_t regs) {
} }
void irq_handler(registers_t regs) { void irq_handler(registers_t regs) {
if(regs.int_no != 0x2b) {
if (regs.int_no >= 40) outb(0xA0, 0x20); // 中断号 >= 40来自从片发送EOI给从片 if (regs.int_no >= 40) outb(0xA0, 0x20); // 中断号 >= 40来自从片发送EOI给从片
outb(0x20, 0x20); // 发送EOI给主片 outb(0x20, 0x20); // 发送EOI给主片
}
if (interrupt_handlers[regs.int_no]) { if (interrupt_handlers[regs.int_no]) {
isr_t handler = interrupt_handlers[regs.int_no]; // 有自定义处理程序,调用之 isr_t handler = interrupt_handlers[regs.int_no]; // 有自定义处理程序,调用之
handler(&regs); // 传入寄存器 handler(&regs); // 传入寄存器

View File

@ -17,6 +17,8 @@
#include "../include/pcnet.h" #include "../include/pcnet.h"
#include "../include/ide.h" #include "../include/ide.h"
#include "../include/vfs.h" #include "../include/vfs.h"
#include "../include/fat.h"
#include "../include/iso9660.h"
extern uint32_t end; extern uint32_t end;
extern int status; extern int status;
@ -68,12 +70,20 @@ void kernel_main(multiboot_t *multiboot) {
multiboot_all = multiboot; multiboot_all = multiboot;
io_sti(); io_sti();
init_pit(); init_pit();
init_vdisk();
init_pci(); init_pci();
init_vfs(); init_vdisk();
ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000); ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000);
init_vfs();
Register_fat_fileSys();
init_iso9660();
syscall_install(); syscall_install();
vfs_mount_disk('A','A');
if(vfs_change_disk('A'))
printf("[FileSystem]: Chang disk win!");
else {
for(;;);
}
if(pcnet_find_card()){ if(pcnet_find_card()){
//init_pcnet_card(); //init_pcnet_card();
} else printf("[\035kernel\036]: \033Cannot found pcnet.\036\n"); } else printf("[\035kernel\036]: \033Cannot found pcnet.\036\n");

View File

@ -22,6 +22,10 @@ static void timer_handle(registers_t *regs) {
io_sti(); io_sti();
} }
void sleep(uint32_t timer){
clock_sleep(timer);
}
void clock_sleep(uint32_t timer){ void clock_sleep(uint32_t timer){
uint32_t sleep = tick + timer; uint32_t sleep = tick + timer;
while(1){ while(1){

View File

@ -1,7 +1,7 @@
#include "../include/arp.h" #include "../include/arp.h"
#include "../include/etherframe.h" #include "../include/etherframe.h"
#include "../include/memory.h" #include "../include/memory.h"
#include "../include/pcnet.h"
uint8_t ARP_flags = 1; uint8_t ARP_flags = 1;
uint64_t ARP_mac_address[MAX_ARP_TABLE]; uint64_t ARP_mac_address[MAX_ARP_TABLE];
uint32_t ARP_ip_address[MAX_ARP_TABLE]; uint32_t ARP_ip_address[MAX_ARP_TABLE];
@ -70,3 +70,40 @@ uint64_t IPParseMAC(uint32_t dstIP) {
*/ */
return ARP_mac_address[ARP_write_pointer - 1]; return ARP_mac_address[ARP_write_pointer - 1];
} }
void arp_handler(void *base) {
extern uint32_t ip;
extern uint8_t mac0;
struct EthernetFrame_head *header = (struct EthernetFrame_head *)(base);
if ((*(uint64_t *)&header->dest_mac[0] & 0xffffffffffff) ==
(*(uint64_t *)&mac0 & 0xffffffffffff)) { // ARP广播回应
struct ARPMessage *arp =
(struct ARPMessage *)(base + sizeof(struct EthernetFrame_head));
if (arp->command == 0x0200) {
// printk("ARP MAC Address Reply\n");
if (ARP_write_pointer < MAX_ARP_TABLE) {
ARP_mac_address[ARP_write_pointer] =
*(uint64_t *)&header->src_mac[0] & 0xffffffffffff;
ARP_ip_address[ARP_write_pointer] = swap32(arp->src_ip);
ARP_write_pointer++;
ARP_flags = 0;
}
}
// 如果发送方不知道我们的MAC地址
// 要发ARP数据包返回给发送方 告诉发送方我的MAC地址确立联系
} else if ((*(uint64_t *)&header->dest_mac[0] & 0xffffffffffff) ==
0xffffffffffff) { // dest_mac = 0xffffffffffff && ARP广播请求
struct ARPMessage *arp =
(struct ARPMessage *)(base + sizeof(struct EthernetFrame_head));
if (arp->command == 0x0100 && arp->dest_ip == swap32(ip)) {
// printk("ARP MAC Address request\n");
uint32_t src_ip = ((arp->src_ip << 24) & 0xff000000) |
((arp->src_ip << 8) & 0x00ff0000) |
((arp->src_ip >> 8) & 0xff00) |
((arp->src_ip >> 24) & 0xff);
ether_frame_provider_send(*(uint64_t *)&header->src_mac[0], 0x0806,
ARP_Packet(*(uint64_t *)&header->src_mac[0],
src_ip, *(uint64_t *)&mac0, ip, 2),
sizeof(struct ARPMessage));
}
}
}

View File

@ -65,6 +65,7 @@ int dhcp_discovery(uint8_t *mac) {
} }
void dhcp_handler(void *base) { void dhcp_handler(void *base) {
printf("DHCP\n");
struct IPV4Message *ipv4 = struct IPV4Message *ipv4 =
(struct IPV4Message *)(base + sizeof(struct EthernetFrame_head)); (struct IPV4Message *)(base + sizeof(struct EthernetFrame_head));
struct UDPMessage *udp = struct UDPMessage *udp =
@ -74,9 +75,10 @@ void dhcp_handler(void *base) {
(struct DHCPMessage *)(base + sizeof(struct EthernetFrame_head) + (struct DHCPMessage *)(base + sizeof(struct EthernetFrame_head) +
sizeof(struct IPV4Message) + sizeof(struct IPV4Message) +
sizeof(struct UDPMessage)); sizeof(struct UDPMessage));
printf("%d %d %d\n",dhcp->bp_options[0],dhcp->bp_options[1],dhcp->bp_options[2]);
if (dhcp->bp_options[0] == 53 && dhcp->bp_options[1] == 1 && if (dhcp->bp_options[0] == 53 && dhcp->bp_options[1] == 1 &&
dhcp->bp_options[2] == DHCP_OPTION_OFFER) { dhcp->opcode == 2) {
// printk("DHCP Offer\n"); printf("DHCP Offer\n");
ip = dhcp->yiaddr; ip = dhcp->yiaddr;
uint8_t nip1 = ip; uint8_t nip1 = ip;
uint8_t nip2 = ip >> 8; uint8_t nip2 = ip >> 8;
@ -86,22 +88,22 @@ void dhcp_handler(void *base) {
// (uint8_t)(ipv4->srcIP >> 8), (uint8_t)(ipv4->srcIP >> 16), // (uint8_t)(ipv4->srcIP >> 8), (uint8_t)(ipv4->srcIP >> 16),
// (uint8_t)(ipv4->srcIP >> 24)); // (uint8_t)(ipv4->srcIP >> 24));
dhcp_ip = swap32(ipv4->srcIP); dhcp_ip = swap32(ipv4->srcIP);
//printk("IP: %d.%d.%d.%d\n", nip1, nip2, nip3, nip4); printf("IP: %d.%d.%d.%d\n", nip1, nip2, nip3, nip4);
ip = swap32(ip); ip = swap32(ip);
unsigned char *options = &dhcp->bp_options[0]; unsigned char *options = &dhcp->bp_options[0];
while (options[0] != 0xff) { while (options[0] != 0xff) {
if (options[0] == MESSAGE_TYPE_DNS) { if (options[0] == MESSAGE_TYPE_DNS) {
// printk("DNS: %d.%d.%d.%d\n", options[2], options[3], options[4], printf("DNS: %d.%d.%d.%d\n", options[2], options[3], options[4],
// options[5]); options[5]);
dns = swap32(*(uint32_t *)&options[2]); dns = swap32(*(uint32_t *)&options[2]);
} else if (options[0] == MESSAGE_TYPE_REQ_SUBNET_MASK) { } else if (options[0] == MESSAGE_TYPE_REQ_SUBNET_MASK) {
// printk("Subnet Mask: %d.%d.%d.%d\n", options[2], options[3], options[4], printf("Subnet Mask: %d.%d.%d.%d\n", options[2], options[3], options[4],
// options[5]); options[5]);
submask = swap32(*(uint32_t *)&options[2]); submask = swap32(*(uint32_t *)&options[2]);
} else if (options[0] == MESSAGE_TYPE_ROUTER) { } else if (options[0] == MESSAGE_TYPE_ROUTER) {
// printk("Gateway: %d.%d.%d.%d\n", options[2], options[3], options[4], printf("Gateway: %d.%d.%d.%d\n", options[2], options[3], options[4],
// options[5]); options[5]);
gateway = swap32(*(uint32_t *)&options[2]); gateway = swap32(*(uint32_t *)&options[2]);
} }
options += options[1] + 2; options += options[1] + 2;

View File

@ -1,7 +1,7 @@
#include "../include/etherframe.h" #include "../include/etherframe.h"
#include "../include/memory.h" #include "../include/memory.h"
#include "../include/net.h" #include "../include/net.h"
#include "../include/pcnet.h"
extern uint8_t mac0, mac1, mac2, mac3, mac4, mac5; extern uint8_t mac0, mac1, mac2, mac3, mac4, mac5;
// 以太网帧 // 以太网帧
void ether_frame_provider_send(uint64_t dest_mac, uint16_t type, uint8_t *buffer, void ether_frame_provider_send(uint64_t dest_mac, uint16_t type, uint8_t *buffer,
@ -31,7 +31,7 @@ void ether_frame_provider_send(uint64_t dest_mac, uint16_t type, uint8_t *buffer
uint8_t *dst = buffer2 + sizeof(struct EthernetFrame_head); uint8_t *dst = buffer2 + sizeof(struct EthernetFrame_head);
for (uint32_t i = 0; i < size; i++) for (uint32_t i = 0; i < size; i++)
dst[i] = src[i]; dst[i] = src[i];
netcard_send(buffer2, sizeof(struct EthernetFrame_head) + size + PcnetSend(buffer2, sizeof(struct EthernetFrame_head) + size +
sizeof(struct EthernetFrame_tail)); sizeof(struct EthernetFrame_tail));
kfree(buffer2); kfree(buffer2);
} }

View File

@ -6,6 +6,11 @@
#include "../include/memory.h" #include "../include/memory.h"
#include "../include/printf.h" #include "../include/printf.h"
#include "../include/dhcp.h" #include "../include/dhcp.h"
#include "../include/etherframe.h"
#include "../include/arp.h"
#include "../include/ipv4.h"
#include "../include/tcp.h"
#include "../include/udp.h"
uint8_t bus = 255, dev = 255, func = 255; uint8_t bus = 255, dev = 255, func = 255;
@ -25,7 +30,9 @@ struct InitializationBlock initBlock;
static struct BufferDescriptor* sendBufferDesc; static struct BufferDescriptor* sendBufferDesc;
static struct BufferDescriptor* recvBufferDesc; static struct BufferDescriptor* recvBufferDesc;
int recv = 0; int recv = 0;
static uint8_t* IP_Packet_Base[16] = {NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL};
static void set_handler(int IRQ, int addr) { static void set_handler(int IRQ, int addr) {
register_interrupt_handler(0x20 + IRQ, (int)addr); register_interrupt_handler(0x20 + IRQ, (int)addr);
} }
@ -61,7 +68,6 @@ void Activate() {
printf("[pcnet]: io\n"); printf("[pcnet]: io\n");
io_out16(io_base + RDP16, 0x41); io_out16(io_base + RDP16, 0x41);
printf("[pcnet]: success.\n"); printf("[pcnet]: success.\n");
io_out16(io_base + RAP16, CSR4); io_out16(io_base + RAP16, CSR4);
uint32_t temp = io_in16(io_base + RDP16); uint32_t temp = io_in16(io_base + RDP16);
io_out16(io_base + RAP16, CSR4); io_out16(io_base + RAP16, CSR4);
@ -91,7 +97,9 @@ static void init_Card_all() {
mac4 = io_in8(io_base + APROM4); mac4 = io_in8(io_base + APROM4);
mac5 = io_in8(io_base + APROM5); mac5 = io_in8(io_base + APROM5);
reset_card(); reset_card();
printf("SLEEP\n");
clock_sleep(1); clock_sleep(1);
printf("END\n");
@ -148,6 +156,7 @@ static void init_Card_all() {
gateway = 0xFFFFFFFF; gateway = 0xFFFFFFFF;
submask = 0xFFFFFFFF; submask = 0xFFFFFFFF;
dns = 0xFFFFFFFF; dns = 0xFFFFFFFF;
printf("DHCP DISCOVERY %08x %08x %08x %08x %08x %08x\n",&mac0,&mac1,&mac2,&mac3,&mac4,&mac5);
dhcp_discovery(&mac0); dhcp_discovery(&mac0);
while (gateway == 0xFFFFFFFF && submask == 0xFFFFFFFF && dns == 0xFFFFFFFF && while (gateway == 0xFFFFFFFF && submask == 0xFFFFFFFF && dns == 0xFFFFFFFF &&
ip == 0xFFFFFFFF) { ip == 0xFFFFFFFF) {
@ -156,8 +165,8 @@ static void init_Card_all() {
} }
void init_pcnet_card() { void init_pcnet_card() {
printf("[\035kernel\036]: Loading pcnet driver.\n"); printf("[\035kernel\036]: Loading pcnet driver. %x\n",pci_get_drive_irq(bus, dev, func));
register_interrupt_handler(pci_get_drive_irq(bus, dev, func),PCNET_IRQ); register_interrupt_handler(pci_get_drive_irq(bus, dev, func) + 0x20,PCNET_IRQ);
// 2,写COMMAND和STATUS寄存器 // 2,写COMMAND和STATUS寄存器
uint32_t conf = pci_read_command_status(bus, dev, func); uint32_t conf = pci_read_command_status(bus, dev, func);
conf &= 0xffff0000; // 保留STATUS寄存器清除COMMAND寄存器 conf &= 0xffff0000; // 保留STATUS寄存器清除COMMAND寄存器
@ -170,7 +179,7 @@ void init_pcnet_card() {
} }
void PCNET_IRQ(registers_t *reg) { void PCNET_IRQ(registers_t *reg) {
printf("PCNET IRQ");
io_out16(io_base + RAP16, CSR0); io_out16(io_base + RAP16, CSR0);
uint16_t temp = io_in16(io_base + RDP16); uint16_t temp = io_in16(io_base + RDP16);
@ -182,12 +191,91 @@ void PCNET_IRQ(registers_t *reg) {
if ((temp & 0x0100) == 0x0100) if ((temp & 0x0100) == 0x0100)
printf("PCNET INIT DONE\n"); printf("PCNET INIT DONE\n");
io_out8(0xa0, (0x60 + pci_get_drive_irq(bus, dev, func) - 0x8));
io_out8(0x20, 0x62);
return; return;
} }
static uint32_t Find_IP_Packet(uint16_t ident) {
for (int i = 0; i != 16; i++) {
if (IP_Packet_Base[i] != NULL) {
struct IPV4Message* ipv4 =
(struct IPV4Message*)(IP_Packet_Base[i] +
sizeof(struct EthernetFrame_head));
if (swap16(ipv4->ident) == ident) {
return i;
}
}
}
return -1;
}
static void IP_Assembling(struct IPV4Message* ipv4, unsigned char* RawData) {
uint32_t i_p = Find_IP_Packet(swap16(ipv4->ident));
struct IPV4Message* ipv4_p =
(struct IPV4Message*)(IP_Packet_Base[i_p] +
sizeof(struct EthernetFrame_head));
uint32_t size_p = swap16(ipv4_p->totalLength);
ipv4_p->totalLength =
swap16(swap16(ipv4->totalLength) + swap16(ipv4_p->totalLength) -
sizeof(struct IPV4Message));
IP_Packet_Base[i_p] = (uint8_t*)realloc((void*)IP_Packet_Base[i_p],
swap16(ipv4_p->totalLength));
memcpy(
(void*)(IP_Packet_Base[i_p] + size_p),
RawData + sizeof(struct EthernetFrame_head) + sizeof(struct IPV4Message),
swap16(ipv4->totalLength) - sizeof(struct IPV4Message));
return;
}
void Card_Recv_Handler(unsigned char* RawData) {
struct EthernetFrame_head* header = (struct EthernetFrame_head*)(RawData);
if (header->type == swap16(IP_PROTOCOL)) { // IP数据报
struct IPV4Message* ipv4 =
(struct IPV4Message*)(RawData + sizeof(struct EthernetFrame_head));
if (ipv4->version == 4) {
if ((swap16(ipv4->flagsAndOffset) >> IP_MF) & 1) {
if (Find_IP_Packet(swap16(ipv4->ident)) == -1) {
for (int i = 0; i != 16; i++) {
if (IP_Packet_Base[i] == NULL) {
IP_Packet_Base[i] =
(uint8_t*)kmalloc(swap16(ipv4->totalLength) +
sizeof(struct EthernetFrame_head));
memcpy((void*)IP_Packet_Base[i], RawData,
swap16(ipv4->totalLength) +
sizeof(struct EthernetFrame_head));
break;
}
}
} else {
IP_Assembling(ipv4, RawData);
}
} else if (!((swap16(ipv4->flagsAndOffset) >> IP_MF) & 1)) {
uint32_t i_p = Find_IP_Packet(swap16(ipv4->ident));
void* base = RawData;
if (i_p != -1) {
IP_Assembling(ipv4, RawData);
base = (void*)IP_Packet_Base[i_p];
}
// if (ipv4->protocol == ICMP_PROTOCOL) { // ICMP
// icmp_handler(base);
/*} else*/ if (ipv4->protocol == UDP_PROTOCOL) { // UDP
printf("UDP\n");
udp_handler(base);
} else if (ipv4->protocol == TCP_PROTOCOL) { // TCP
tcp_handler(base);
}
if (i_p != -1) {
kfree((void*)IP_Packet_Base[i_p]);
IP_Packet_Base[i_p] = NULL;
}
}
}
} else if (header->type == swap16(ARP_PROTOCOL)) { // ARP
arp_handler(RawData);
}
}
void Recv() { void Recv() {
recv = 1; recv = 1;
//printk("\nPCNET RECV: "); printk("\nPCNET RECV: ");
for (; (recvBufferDesc[currentRecvBuffer].flags & 0x80000000) == 0; for (; (recvBufferDesc[currentRecvBuffer].flags & 0x80000000) == 0;
currentRecvBuffer = (currentRecvBuffer + 1) % 8) { currentRecvBuffer = (currentRecvBuffer + 1) % 8) {
if (!(recvBufferDesc[currentRecvBuffer].flags & 0x40000000) && if (!(recvBufferDesc[currentRecvBuffer].flags & 0x40000000) &&
@ -204,7 +292,7 @@ void Recv() {
} }
recv = 0; recv = 0;
currentRecvBuffer = 0; currentRecvBuffer = 0;
//TODO Card_Recv_Handler(recvBufferDesc[currentRecvBuffer].address); Card_Recv_Handler(recvBufferDesc[currentRecvBuffer].address);
memclean(recvBufferDesc[currentRecvBuffer].address, 2048); memclean(recvBufferDesc[currentRecvBuffer].address, 2048);
recvBufferDesc[currentRecvBuffer].flags2 = 0; recvBufferDesc[currentRecvBuffer].flags2 = 0;
@ -214,3 +302,32 @@ void Recv() {
} }
void PcnetSend(uint8_t* buffer, int size) {
while(recv);
int sendDesc = currentSendBuffer;
currentSendBuffer = (currentSendBuffer + 1) % 8;
memclean(sendBufferDesc[currentSendBuffer].address, 2048);
if (size > MTU + sizeof(struct EthernetFrame_head) +
sizeof(struct EthernetFrame_tail))
size = MTU + sizeof(struct EthernetFrame_head) +
sizeof(struct EthernetFrame_tail);
for (uint8_t *src = buffer + size - 1,
*dst = (uint8_t*)(sendBufferDesc[sendDesc].address + size - 1);
src >= buffer; src--, dst--)
*dst = *src;
//printk("SENDING: ");
for (int i = 0; i < (size > 128 ? 128 : size); i++) {
//printk("%02x ", buffer[i]);
}
//printk("\n");
sendBufferDesc[sendDesc].avail = 0;
sendBufferDesc[sendDesc].flags = 0x8300f000 | ((uint16_t)((-size) & 0xfff));
sendBufferDesc[sendDesc].flags2 = 0;
io_out16(io_base + RAP16, CSR0);
io_out16(io_base + RDP16, 0x48);
currentSendBuffer = 0;
}

View File

@ -5,6 +5,7 @@
#include "../include/task.h" #include "../include/task.h"
#include "../include/cmos.h" #include "../include/cmos.h"
#include "../include/vdisk.h" #include "../include/vdisk.h"
#include "../include/vfs.h"
extern Queue *key_char_queue; extern Queue *key_char_queue;
extern vdisk vdisk_ctl[10]; extern vdisk vdisk_ctl[10];
@ -66,36 +67,62 @@ void cmd_echo(int argc, char **argv) {
vga_putchar('\n'); vga_putchar('\n');
} }
void cmd_proc(int argc, char **argv){ void cmd_proc(int argc, char **argv) {
if (argc <= 1) { if (argc <= 1) {
printf("\033[Shell-PROC]: If there are too few parameters.\036\n"); printf("\033[Shell-PROC]: If there are too few parameters.\036\n");
return; return;
} }
if(!strcmp("list",argv[1])){ if (!strcmp("list", argv[1])) {
print_proc(); print_proc();
} else if(!strcmp("kill",argv[1])){ } else if (!strcmp("kill", argv[1])) {
if (argc <= 2) { if (argc <= 2) {
printf("\033[Shell-PROC-kill]: If there are too few parameters.\036\n"); printf("\033[Shell-PROC-kill]: If there are too few parameters.\036\n");
return; return;
} }
int pid = strtol(argv[2],NULL,10); int pid = strtol(argv[2], NULL, 10);
task_kill(pid); task_kill(pid);
} else{ } else {
printf("\033[Shell-[PROC]]: Unknown parameter\036\n"); printf("\033[Shell-[PROC]]: Unknown parameter\036\n");
return; return;
} }
} }
void cmd_date(){ void cmd_date() {
printf("System Time: %s\n",get_date_time()); printf("System Time: %s\n", get_date_time());
printf("Memory Usage: [%dKB] | All Size: [%dMB]\n",memory_usage()/1024,(KHEAP_START+KHEAP_INITIAL_SIZE)/1024/1024); printf("Memory Usage: [%dKB] | All Size: [%dMB]\n", memory_usage() / 1024,
(KHEAP_START + KHEAP_INITIAL_SIZE) / 1024 / 1024);
print_cpu_id(); print_cpu_id();
vga_writestring("\n"); vga_writestring("\n");
} }
void cmd_ls() { void cmd_ls() {
List *ls = vfs_listfile("");
int files = 0, dirs = 0;
for (int i = 1; FindForCount(i, ls) != NULL; i++) {
vfs_file *d = (vfs_file *) FindForCount(i, ls)->val;
char *type;
if (d->type == DIR) {
type = "<DIR>"; //文件夹
dirs++;
} else if (d->type == HID) {
type = "<HID>"; //隐藏文件
files++;
} else {
type = "<FILE>"; //文件
files++;
}
printf("%-13s %-6s %d \n", d->name, type, d->size / 1024);
kfree(d);
}
printf("-----------------------------------------\n");
printf("Name Type Size(KB)\n"
"All directory: %d | All Files: %d\n",dirs, files);
DeleteList(ls);
kfree(ls);
} }
void cmd_mkdir(int argc, char **argv) { void cmd_mkdir(int argc, char **argv) {
@ -103,8 +130,17 @@ void cmd_mkdir(int argc, char **argv) {
printf("\033[Shell-MKDIR]: If there are too few parameters, please specify the directory name.\036\n"); printf("\033[Shell-MKDIR]: If there are too few parameters, please specify the directory name.\036\n");
return; return;
} }
printf("Create directory: %s\n",argv[1]);
vfs_file *file = get_cur_file(argv[1]);
if(file != NULL){
printf("This file is exist.\n");
return;
}
if(!vfs_createdict(argv[1])){
printf("Illegal create.\n");
} else printf("Create directory: %s\n", argv[1]);
} }
void cmd_del(int argc, char **argv) { void cmd_del(int argc, char **argv) {
@ -113,32 +149,47 @@ void cmd_del(int argc, char **argv) {
return; return;
} }
vfs_file *file = get_cur_file(argv[1]);
if(file == NULL){
printf("Cannot found file.\n");
return;
}
bool b;
if(file->type == DIR){
b = vfs_deldir(argv[1]);
} else b = vfs_delfile(argv[1]);
if(!b){
printf("Illegal delete!\n");
}
} }
void cmd_reset(){ void cmd_reset() {
reset_kernel(); reset_kernel();
} }
void cmd_shutdown(){ void cmd_shutdown() {
shutdown_kernel(); shutdown_kernel();
} }
void cmd_debug(){ void cmd_debug() {
vga_clear(); vga_clear();
printf("%s for x86 [Version %s] \n",OS_NAME, OS_VERSION); printf("%s for x86 [Version %s] \n", OS_NAME, OS_VERSION);
printf("\032Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\036\n"); printf("\032Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\036\n");
extern int acpi_enable_flag; extern int acpi_enable_flag;
extern uint8_t *rsdp_address; extern uint8_t *rsdp_address;
printf("ACPI: Enable: %s | RSDP Address: 0x%08x\n",acpi_enable_flag?"\035ENABLE\036":"\033DISABLE\036",rsdp_address); printf("ACPI: Enable: %s | RSDP Address: 0x%08x\n", acpi_enable_flag ? "\035ENABLE\036" : "\033DISABLE\036",
rsdp_address);
int index = 0; int index = 0;
print_proc_t(&index,get_current(),get_current()->next,0); print_proc_t(&index, get_current(), get_current()->next, 0);
printf("Process Runnable: %d\n",index); printf("Process Runnable: %d\n", index);
cmd_date(); cmd_date();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
if (vdisk_ctl[i].flag) { if (vdisk_ctl[i].flag) {
vdisk vd = vdisk_ctl[i]; vdisk vd = vdisk_ctl[i];
char id = i + ('A'); char id = i + ('A');
printf("[DISK-%c]: Size: %dMB | Name: %s\n",id,vd.size,vd.DriveName); printf("[DISK-%c]: Size: %dMB | Name: %s\n", id, vd.size, vd.DriveName);
} }
} }
printf(" > > > > ====[Registers Info]==== < < < <\n"); printf(" > > > > ====[Registers Info]==== < < < <\n");
@ -149,26 +200,34 @@ void cmd_debug(){
ebx asm("ebx"), ebx asm("ebx"),
esi asm("esi"), esi asm("esi"),
edi asm("edi"); edi asm("edi");
printf("EAX: 0x%08x | EBX 0x%08x | ECX 0x%08x | ESP 0x%08x \n",eax,ebx,ecx,esp); printf("EAX: 0x%08x | EBX 0x%08x | ECX 0x%08x | ESP 0x%08x \n", eax, ebx, ecx, esp);
printf("ESI: 0x%08x | EDI 0x%08x | EBP 0x%08x | EFLAGS 0x%08x\n",esi,edi,ebp,get_current()->context.eflags); printf("ESI: 0x%08x | EDI 0x%08x | EBP 0x%08x | EFLAGS 0x%08x\n", esi, edi, ebp, get_current()->context.eflags);
} }
void cmd_disk(int argc,char **argv){ void cmd_cd(int argc, char **argv) {
if(argc > 1){ if (argc == 1) {
if(!strcmp("list",argv[1])){ vga_writestring("\033[Shell-CD]: If there are too few parameters, please specify the path.\036\n");
return;
}
if (vfs_change_path(argv[1]) == 0) printf("Invalid path.\n");
}
void cmd_disk(int argc, char **argv) {
if (argc > 1) {
if (!strcmp("list", argv[1])) {
printf("[Disk]: Loaded disk - "); printf("[Disk]: Loaded disk - ");
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
if (vdisk_ctl[i].flag) { if (vdisk_ctl[i].flag) {
vdisk vd = vdisk_ctl[i]; vdisk vd = vdisk_ctl[i];
char id = i + ('A'); char id = i + ('A');
printf("(%c) ",id,vd.size,vd.DriveName); printf("(%c) ", id, vd.size, vd.DriveName);
} }
} }
printf("\n"); printf("\n");
return; return;
} }
if(strlen(argv[1]) > 1){ if (strlen(argv[1]) > 1) {
printf("\033[DISK]: Cannot found disk.\036\n"); printf("\033[DISK]: Cannot found disk.\036\n");
return; return;
} }
@ -177,12 +236,12 @@ void cmd_disk(int argc,char **argv){
if (vdisk_ctl[i].flag) { if (vdisk_ctl[i].flag) {
vdisk vd = vdisk_ctl[i]; vdisk vd = vdisk_ctl[i];
char id = i + ('A'); char id = i + ('A');
if(id == (argv[1][0])){ if (id == (argv[1][0])) {
printf("[Disk(%c)]: \n" printf("[Disk(%c)]: \n"
" Size: %dMB\n" " Size: %dMB\n"
" Name: %s\n" " Name: %s\n"
" WriteAddress: 0x%08x\n" " WriteAddress: 0x%08x\n"
" ReadAddress: 0x%08x\n",id,vd.size,vd.DriveName,vd.Write,vd.Read); " ReadAddress: 0x%08x\n", id, vd.size, vd.DriveName, vd.Write, vd.Read);
return; return;
} }
} }
@ -195,46 +254,48 @@ void cmd_disk(int argc,char **argv){
if (vdisk_ctl[i].flag) { if (vdisk_ctl[i].flag) {
vdisk vd = vdisk_ctl[i]; vdisk vd = vdisk_ctl[i];
char id = i + ('A'); char id = i + ('A');
printf("(%c) ",id,vd.size,vd.DriveName); printf("(%c) ", id, vd.size, vd.DriveName);
} }
} }
printf("\n"); printf("\n");
} }
char* user(){ char *user() {
printf("\n\nPlease type your username and password.\n"); printf("\n\nPlease type your username and password.\n");
char com[MAX_COMMAND_LEN]; char com[MAX_COMMAND_LEN];
char* username = "admin"; char *username = "admin";
char* password = "12345678"; char *password = "12345678";
while (1){ while (1) {
print("username/> "); print("username/> ");
if (gets(com, MAX_COMMAND_LEN) <= 0) continue; if (gets(com, MAX_COMMAND_LEN) <= 0) continue;
if(!strcmp(username,com)){ if (!strcmp(username, com)) {
break; break;
} else printf("Cannot found username, Please check your info.\n"); } else printf("Cannot found username, Please check your info.\n");
} }
while (1){ while (1) {
print("password/> "); print("password/> ");
if (gets(com, MAX_COMMAND_LEN) <= 0) continue; if (gets(com, MAX_COMMAND_LEN) <= 0) continue;
if(!strcmp(password,com)){ if (!strcmp(password, com)) {
break; break;
} else printf("Unknown password, Please check your info.\n"); } else printf("Unknown password, Please check your info.\n");
} }
return username; return username;
} }
void setup_shell(){ void setup_shell() {
char* user1 = user(); char *user1 = "default";//user();
vga_clear(); vga_clear();
printf("%s for x86 [Version %s] \n",OS_NAME, OS_VERSION); printf("%s for x86 [Version %s] \n", OS_NAME, OS_VERSION);
printf("\032Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\036\n"); printf("\032Copyright 2024 XIAOYI12 (Build by GCC i686-elf-tools)\036\n");
char com[MAX_COMMAND_LEN]; char com[MAX_COMMAND_LEN];
char *argv[MAX_ARG_NR]; char *argv[MAX_ARG_NR];
int argc = -1; int argc = -1;
char *buffer[255];
while (1) { while (1) {
printf("\035%s/>\036 ",user1); vfs_getPath(buffer);
printf("\035%s %s\\>\036 ", user1, buffer);
if (gets(com, MAX_COMMAND_LEN) <= 0) continue; if (gets(com, MAX_COMMAND_LEN) <= 0) continue;
argc = cmd_parse(com, argv, ' '); argc = cmd_parse(com, argv, ' ');
@ -244,7 +305,7 @@ void setup_shell(){
} }
if (!strcmp("version", argv[0])) if (!strcmp("version", argv[0]))
printf("%s for x86 [%s]\n",OS_NAME, OS_VERSION); printf("%s for x86 [%s]\n", OS_NAME, OS_VERSION);
else if (!strcmp("echo", argv[0])) else if (!strcmp("echo", argv[0]))
cmd_echo(argc, argv); cmd_echo(argc, argv);
else if (!strcmp("clear", argv[0])) else if (!strcmp("clear", argv[0]))
@ -261,12 +322,14 @@ void setup_shell(){
cmd_del(argc, argv); cmd_del(argc, argv);
else if (!strcmp("reset", argv[0])) else if (!strcmp("reset", argv[0]))
cmd_reset(); cmd_reset();
else if (!strcmp("shutdown", argv[0])||!strcmp("exit", argv[0])) else if (!strcmp("shutdown", argv[0]) || !strcmp("exit", argv[0]))
cmd_shutdown(); cmd_shutdown();
else if (!strcmp("debug", argv[0])) else if (!strcmp("debug", argv[0]))
cmd_debug(); cmd_debug();
else if (!strcmp("disk", argv[0])) else if (!strcmp("disk", argv[0]))
cmd_disk(argc,argv); cmd_disk(argc, argv);
else if (!strcmp("cd", argv[0]))
cmd_cd(argc, argv);
else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) { else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) {
vga_writestring("-=[\037CoolPotShell Helper\036]=-\n"); vga_writestring("-=[\037CoolPotShell Helper\036]=-\n");
vga_writestring("help ? h \032Print shell help info.\036\n"); vga_writestring("help ? h \032Print shell help info.\036\n");
@ -281,6 +344,7 @@ void setup_shell(){
vga_writestring("shutdown exit \032Shutdown OS.\036\n"); vga_writestring("shutdown exit \032Shutdown OS.\036\n");
vga_writestring("debug \032Print os debug info.\036\n"); vga_writestring("debug \032Print os debug info.\036\n");
vga_writestring("disk [list|<ID>] \032List or view disks.\036\n"); vga_writestring("disk [list|<ID>] \032List or view disks.\036\n");
vga_writestring("cd <path> \032Change shell top directory.\036\n");
} else printf("\033[Shell]: Unknown command '%s'.\036\n", argv[0]); } else printf("\033[Shell]: Unknown command '%s'.\036\n", argv[0]);
} }
} }

View File

@ -152,6 +152,7 @@ char *strcpy(char *dest, const char *src) {
do { do {
*dest++ = *src++; *dest++ = *src++;
} while (*src != 0); } while (*src != 0);
*dest = 0;
} }
char *strcat(char *dest, const char *src) { char *strcat(char *dest, const char *src) {
@ -477,14 +478,10 @@ char *uint32_to_str_oct(uint32_t num, int flag, int width) {
return str_first; return str_first;
} }
char *insert_str(char *buf, const char *str) { void insert_str(char *str, char *insert_str, int pos) {
char *p = buf; for (int i = 0; i < strlen(insert_str); i++) {
insert_char(str, pos + i, insert_str[i]);
while (*str) {
*p++ = *str++;
} }
return p;
} }
void assert(int b, char *message) { void assert(int b, char *message) {