文件系统修复
This commit is contained in:
parent
f1f2a45882
commit
9221f2e106
6
build.py
6
build.py
@ -1,7 +1,7 @@
|
||||
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'
|
||||
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'
|
||||
nasm = "nasm -f elf32"
|
||||
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':
|
||||
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':
|
||||
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")
|
323
driver/ide.c
323
driver/ide.c
@ -8,7 +8,6 @@
|
||||
static inline nul(char *f, ...) {}
|
||||
|
||||
#define logk nul
|
||||
|
||||
#define inb io_in8
|
||||
#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,
|
||||
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,
|
||||
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) {
|
||||
@ -70,6 +191,7 @@ unsigned char ide_read(unsigned char channel, unsigned char reg) {
|
||||
ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ide_write(unsigned char channel, unsigned char reg, unsigned char data) {
|
||||
if (reg > 0x07 && reg < 0x0C)
|
||||
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)
|
||||
ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
|
||||
}
|
||||
|
||||
void ide_read_buffer(unsigned char channel, unsigned char reg,
|
||||
unsigned int buffer, unsigned int quads) {
|
||||
/* 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)
|
||||
ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN);
|
||||
}
|
||||
|
||||
unsigned char ide_polling(unsigned char channel, unsigned int advanced_check) {
|
||||
// (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) {
|
||||
logk("a=%d\n", a & ATA_SR_BSY); // Wait for BSY to be zero.
|
||||
a = ide_read(channel, ATA_REG_STATUS);
|
||||
clock_sleep(1);
|
||||
sleep(1);
|
||||
}
|
||||
logk("II OK\n");
|
||||
if (advanced_check) {
|
||||
@ -198,11 +322,11 @@ unsigned char ide_print_error(unsigned int drive, unsigned char err) {
|
||||
}
|
||||
printk(
|
||||
"- [%s %s] %s\n",
|
||||
(const char *[]){
|
||||
(const char *[]) {
|
||||
"Primary",
|
||||
"Secondary"}[ide_devices[drive].Channel], // Use the channel as an
|
||||
// index into the array
|
||||
(const char *[]){
|
||||
(const char *[]) {
|
||||
"Master",
|
||||
"Slave"}[ide_devices[drive].Drive], // Same as above, using the drive
|
||||
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.
|
||||
logk("IV1\n");
|
||||
if (dma)
|
||||
if (direction == 0)
|
||||
;
|
||||
if (direction == 0);
|
||||
// DMA Read.
|
||||
else
|
||||
;
|
||||
else;
|
||||
// DMA Write.
|
||||
else if (direction == 0) {
|
||||
// PIO Read.
|
||||
uint16_t *word_ = edi;
|
||||
for (i = 0; i < numsects; i++) {
|
||||
logk("read %d\n", i);
|
||||
// printf("read %d\n", i);
|
||||
if (err = ide_polling(channel, 1))
|
||||
return err; // Polling, set error and exit if there is.
|
||||
|
||||
logk("words=%d bus=%d\n", words, bus);
|
||||
// for (int h = 0; h < words; h++) {
|
||||
// unsigned short a = io_in16(bus);
|
||||
// word_[i * words + h] = a;
|
||||
// }
|
||||
insl(bus, word_ + i * words, words / 2);
|
||||
for (int h = 0; h < words; h++) {
|
||||
unsigned short a = io_in16(bus);
|
||||
word_[i * words + h] = a;
|
||||
// printf("%04x ",a);
|
||||
}
|
||||
//insl(bus, word_ + i * words, words / 2);
|
||||
}
|
||||
} else {
|
||||
// PIO Write.
|
||||
@ -353,18 +476,19 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive,
|
||||
}
|
||||
}
|
||||
ide_write(channel, ATA_REG_COMMAND,
|
||||
(char[]){ATA_CMD_CACHE_FLUSH, ATA_CMD_CACHE_FLUSH,
|
||||
ATA_CMD_CACHE_FLUSH_EXT}[lba_mode]);
|
||||
(char[]) {ATA_CMD_CACHE_FLUSH, ATA_CMD_CACHE_FLUSH,
|
||||
ATA_CMD_CACHE_FLUSH_EXT}[lba_mode]);
|
||||
ide_polling(channel, 0); // Polling.
|
||||
}
|
||||
|
||||
return 0; // Easy, isn't it?
|
||||
}
|
||||
|
||||
void ide_wait_irq() {
|
||||
while (!ide_irq_invoked)
|
||||
;
|
||||
while (!ide_irq_invoked);
|
||||
ide_irq_invoked = 0;
|
||||
}
|
||||
|
||||
void ide_irq() {
|
||||
logk("ide irq.\n");
|
||||
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);
|
||||
logk("II\n");
|
||||
// (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("IV\n");
|
||||
@ -459,11 +582,11 @@ unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
|
||||
|
||||
// (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?
|
||||
}
|
||||
|
||||
void ide_read_sectors(unsigned char drive, unsigned char numsects,
|
||||
unsigned int lba, unsigned short es, unsigned int edi) {
|
||||
// 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] is an entry of an array. It contains the Error Code.
|
||||
|
||||
void ide_write_sectors(unsigned char drive, unsigned char numsects,
|
||||
unsigned int lba, unsigned short es, unsigned int edi) {
|
||||
// 1: Check if the drive presents:
|
||||
@ -575,7 +698,7 @@ void ide_atapi_eject(unsigned char drive) {
|
||||
// (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
|
||||
ide_wait_irq(); // Wait for an IRQ.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@ -90,7 +90,7 @@ unsigned char shift_keyboard_map[128] =
|
||||
|
||||
static void default_handle(uint32_t key,int release,char c){
|
||||
if(!release) {
|
||||
if(c == -1) {
|
||||
if(key == 42) {
|
||||
key_status->is_shift = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -106,7 +106,7 @@ static void default_handle(uint32_t key,int release,char c){
|
||||
|
||||
queue_push(key_char_queue,(char)c);
|
||||
} else {
|
||||
if(c == -1){
|
||||
if(key == -86){
|
||||
key_status->is_shift = 0;
|
||||
}
|
||||
|
||||
@ -125,6 +125,7 @@ void init_keyboard(){
|
||||
head_listener = (struct key_listener*) kmalloc(sizeof(struct key_listener));
|
||||
head_listener->func = default_handle;
|
||||
head_listener->lid = 0;
|
||||
head_listener->next = NULL;
|
||||
|
||||
register_interrupt_handler(0x21,handle_keyboard_input);
|
||||
}
|
||||
|
129
driver/vdisk.c
129
driver/vdisk.c
@ -10,30 +10,27 @@
|
||||
|
||||
int getReadyDisk();
|
||||
|
||||
vdisk vdisk_ctl[10];
|
||||
vdisk vdisk_ctl[26];
|
||||
|
||||
int init_vdisk() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int i = 0; i < 26; 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++) {
|
||||
for (int i = 0; i < 26; i++) {
|
||||
if (!vdisk_ctl[i].flag) {
|
||||
vdisk_ctl[i] = vd; // 找到了!
|
||||
return i + ('A'); // 注册成功,返回drive
|
||||
}
|
||||
}
|
||||
printf("[vdisk]not found\n");
|
||||
printk("[vdisk]not found\n");
|
||||
return 0; // 注册失败
|
||||
}
|
||||
|
||||
int logout_vdisk(char drive) {
|
||||
int indx = drive - ('A');
|
||||
if (indx > 10) {
|
||||
if (indx > 26) {
|
||||
return 0; // 失败
|
||||
}
|
||||
if (vdisk_ctl[indx].flag) {
|
||||
@ -43,17 +40,15 @@ int logout_vdisk(char drive) {
|
||||
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) {
|
||||
if (indx > 26) {
|
||||
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);
|
||||
}
|
||||
@ -62,10 +57,10 @@ int rw_vdisk(char drive, unsigned int lba, unsigned char *buffer,
|
||||
return 0; // 失败
|
||||
}
|
||||
}
|
||||
|
||||
int have_vdisk(char drive) {
|
||||
bool have_vdisk(char drive) {
|
||||
int indx = drive - 'A';
|
||||
if (indx > 10) {
|
||||
// printk("drive=%c\n",drive);
|
||||
if (indx > 26) {
|
||||
return 0; // 失败
|
||||
}
|
||||
if (vdisk_ctl[indx].flag) {
|
||||
@ -74,63 +69,23 @@ int have_vdisk(char drive) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 基于vdisk的通用读写
|
||||
|
||||
static unsigned char *drive_name[16] = {NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL};
|
||||
static struct FIFO8 drive_fifo[16];
|
||||
static unsigned char drive_buf[16][256];
|
||||
|
||||
bool SetDrive(unsigned char *name) {
|
||||
for (int i = 0; i != 16; i++) {
|
||||
if (drive_name[i] == NULL) {
|
||||
drive_name[i] = name;
|
||||
fifo8_init(&drive_fifo[i], 256, drive_buf[i]);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int GetDriveCode(unsigned char *name) {
|
||||
for (int i = 0; i != 16; i++) {
|
||||
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) {
|
||||
if (drive_code >= 16) {
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
void DriveSemaphoreGive(unsigned int drive_code) {
|
||||
if (drive_code >= 16) {
|
||||
return;
|
||||
}
|
||||
if (drive_buf[drive_code][drive_fifo[drive_code].q] != get_current()->pid) {
|
||||
return;
|
||||
}
|
||||
fifo8_get(&drive_fifo[drive_code]);
|
||||
return;
|
||||
}
|
||||
|
||||
void Disk_Read(unsigned int lba, unsigned int number, void *buffer,
|
||||
char drive) {
|
||||
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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
328
fs/iso9660.c
Normal file
328
fs/iso9660.c
Normal 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
103
fs/vfs.c
@ -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");
|
||||
return false;
|
||||
}
|
||||
|
||||
vfs_t *fs = check_disk_fs(disk_number);
|
||||
if (!fs) {
|
||||
printf("unknow file system.\n");
|
||||
printf("[FileSystem]: Unknown file system.\n");
|
||||
return false;
|
||||
}
|
||||
*seat = *fs;
|
||||
@ -178,6 +179,41 @@ bool vfs_delfile(char *filename) {
|
||||
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) {
|
||||
char *new_path = kmalloc(strlen(dictname) + 1);
|
||||
strcpy(new_path, dictname);
|
||||
@ -206,6 +242,7 @@ bool vfs_createfile(char *filename) {
|
||||
|
||||
bool vfs_createdict(char *filename) {
|
||||
char *new_path = kmalloc(strlen(filename) + 1);
|
||||
memclean(new_path, strlen(filename) + 1);
|
||||
strcpy(new_path, filename);
|
||||
vfs_t *vfs = ParsePath(new_path);
|
||||
if (vfs == NULL) {
|
||||
@ -254,17 +291,41 @@ bool vfs_format(uint8_t disk_number, char *FSName) {
|
||||
|
||||
vfs_file *vfs_fileinfo(char *filename) {
|
||||
char *new_path = kmalloc(strlen(filename) + 1);
|
||||
memclean(new_path,strlen(filename) + 1);
|
||||
strcpy(new_path, filename);
|
||||
vfs_t *vfs = ParsePath(new_path);
|
||||
if (vfs == NULL) {
|
||||
kfree(new_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vfs_file *result = vfs->FileInfo(vfs, new_path);
|
||||
kfree(new_path);
|
||||
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) {
|
||||
if (vfs_now != NULL) {
|
||||
while (FindForCount(1, vfs_now->path) != NULL) {
|
||||
@ -275,10 +336,12 @@ bool vfs_change_disk(uint8_t drive) {
|
||||
DeleteList(vfs_now->path);
|
||||
kfree(vfs_now);
|
||||
}
|
||||
|
||||
vfs_t *f;
|
||||
if (!(f = drive2fs(drive))) {
|
||||
return false; // 没有mount
|
||||
}
|
||||
|
||||
vfs_now = kmalloc(sizeof(vfs_t));
|
||||
memcpy(vfs_now, f, sizeof(vfs_t));
|
||||
f->CopyCache(vfs_now, f);
|
||||
@ -287,6 +350,44 @@ bool vfs_change_disk(uint8_t drive) {
|
||||
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() {
|
||||
for (int i = 0; i < 26; i++) {
|
||||
vfsstl[i].flag = 0;
|
||||
|
@ -22,5 +22,5 @@ struct ARPMessage {
|
||||
uint64_t IPParseMAC(uint32_t dstIP);
|
||||
uint8_t *ARP_Packet(uint64_t dest_mac, uint32_t dest_ip, uint64_t src_mac,
|
||||
uint32_t src_ip, uint16_t command);
|
||||
|
||||
void arp_handler(void *base);
|
||||
#endif
|
||||
|
@ -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 *uint64_to_str_hex(uint64_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 sprintf(char *buf, const char *fmt, ...);
|
||||
long int strtol(const char *str,char **endptr,int base);
|
||||
|
110
include/fat.h
Normal file
110
include/fat.h
Normal 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
|
@ -73,26 +73,26 @@
|
||||
#define ATA_READ 0x00
|
||||
#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);
|
||||
void ide_write(unsigned char channel, unsigned char reg, unsigned char data);
|
||||
void ide_read_buffer(unsigned char channel, unsigned char reg,
|
||||
unsigned int buffer, unsigned int quads);
|
||||
unsigned char ide_polling(unsigned char channel, unsigned int advanced_check);
|
||||
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 int lba, unsigned char numsects,
|
||||
unsigned short selector, unsigned int edi);
|
||||
void ide_write_sectors(unsigned char drive, unsigned char numsects,
|
||||
unsigned int lba, unsigned short es, unsigned int edi);
|
||||
void ide_read_sectors(unsigned char drive, unsigned char numsects,
|
||||
unsigned int lba, unsigned short es, unsigned int edi);
|
||||
void ide_wait_irq();
|
||||
void ide_irq();
|
||||
unsigned char ide_atapi_read(unsigned char drive, unsigned int lba,
|
||||
unsigned char numsects, unsigned short selector,
|
||||
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_initialize(unsigned int BAR0, unsigned int BAR1, unsigned int BAR2,
|
||||
unsigned int BAR3, unsigned int BAR4);
|
||||
|
||||
#endif
|
||||
|
169
include/iso9660.h
Normal file
169
include/iso9660.h
Normal 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
|
@ -28,7 +28,16 @@
|
||||
#define RAP32 0x14
|
||||
#define RESET32 0x18
|
||||
#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 "isr.h"
|
||||
|
||||
@ -58,5 +67,6 @@ int pcnet_find_card();
|
||||
void init_pcnet_card();
|
||||
void PCNET_IRQ(registers_t *reg);
|
||||
void Recv();
|
||||
void PcnetSend(uint8_t* buffer, int size);
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@ void timer_free(struct TIMER *timer);
|
||||
void timer_init(struct TIMER *timer, struct FIFO8 *fifo, unsigned char data);
|
||||
void timer_settime(struct TIMER *timer, unsigned int timeout);
|
||||
void clock_sleep(uint32_t timer);
|
||||
void sleep(uint32_t timer);
|
||||
struct TIMER *timer_alloc(void);
|
||||
unsigned int time(void);
|
||||
void init_pit(void);
|
||||
|
@ -40,7 +40,7 @@ int rw_vdisk(char drive, unsigned int lba, unsigned char *buffer,
|
||||
int have_vdisk(char drive);
|
||||
void Disk_Read(unsigned int lba, unsigned int number, void *buffer,
|
||||
char drive);
|
||||
int disk_Size(char drive);
|
||||
unsigned int disk_Size(char drive);
|
||||
int DiskReady(char drive);
|
||||
void Disk_Write(unsigned int lba, unsigned int number, void *buffer,
|
||||
char drive);
|
||||
|
@ -50,6 +50,9 @@ typedef struct vfs_t {
|
||||
int flag;
|
||||
} 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_unmount_disk(uint8_t drive);
|
||||
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_register_fs(vfs_t vfs);
|
||||
void init_vfs();
|
||||
vfs_file *get_cur_file(char* filename);
|
||||
|
||||
#endif
|
||||
|
@ -29,9 +29,10 @@ void isr_handler(registers_t regs) {
|
||||
}
|
||||
|
||||
void irq_handler(registers_t regs) {
|
||||
if (regs.int_no >= 40) outb(0xA0, 0x20); // 中断号 >= 40,来自从片,发送EOI给从片
|
||||
outb(0x20, 0x20); // 发送EOI给主片
|
||||
|
||||
if(regs.int_no != 0x2b) {
|
||||
if (regs.int_no >= 40) outb(0xA0, 0x20); // 中断号 >= 40,来自从片,发送EOI给从片
|
||||
outb(0x20, 0x20); // 发送EOI给主片
|
||||
}
|
||||
if (interrupt_handlers[regs.int_no]) {
|
||||
isr_t handler = interrupt_handlers[regs.int_no]; // 有自定义处理程序,调用之
|
||||
handler(®s); // 传入寄存器
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "../include/pcnet.h"
|
||||
#include "../include/ide.h"
|
||||
#include "../include/vfs.h"
|
||||
#include "../include/fat.h"
|
||||
#include "../include/iso9660.h"
|
||||
|
||||
extern uint32_t end;
|
||||
extern int status;
|
||||
@ -68,12 +70,20 @@ void kernel_main(multiboot_t *multiboot) {
|
||||
multiboot_all = multiboot;
|
||||
io_sti();
|
||||
init_pit();
|
||||
init_vdisk();
|
||||
init_pci();
|
||||
init_vfs();
|
||||
init_vdisk();
|
||||
ide_initialize(0x1F0, 0x3F6, 0x170, 0x376, 0x000);
|
||||
init_vfs();
|
||||
Register_fat_fileSys();
|
||||
init_iso9660();
|
||||
syscall_install();
|
||||
|
||||
vfs_mount_disk('A','A');
|
||||
if(vfs_change_disk('A'))
|
||||
printf("[FileSystem]: Chang disk win!");
|
||||
else {
|
||||
for(;;);
|
||||
}
|
||||
if(pcnet_find_card()){
|
||||
//init_pcnet_card();
|
||||
} else printf("[\035kernel\036]: \033Cannot found pcnet.\036\n");
|
||||
|
@ -22,6 +22,10 @@ static void timer_handle(registers_t *regs) {
|
||||
io_sti();
|
||||
}
|
||||
|
||||
void sleep(uint32_t timer){
|
||||
clock_sleep(timer);
|
||||
}
|
||||
|
||||
void clock_sleep(uint32_t timer){
|
||||
uint32_t sleep = tick + timer;
|
||||
while(1){
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "../include/arp.h"
|
||||
#include "../include/etherframe.h"
|
||||
#include "../include/memory.h"
|
||||
|
||||
#include "../include/pcnet.h"
|
||||
uint8_t ARP_flags = 1;
|
||||
uint64_t ARP_mac_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];
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
@ -65,6 +65,7 @@ int dhcp_discovery(uint8_t *mac) {
|
||||
}
|
||||
|
||||
void dhcp_handler(void *base) {
|
||||
printf("DHCP\n");
|
||||
struct IPV4Message *ipv4 =
|
||||
(struct IPV4Message *)(base + sizeof(struct EthernetFrame_head));
|
||||
struct UDPMessage *udp =
|
||||
@ -74,9 +75,10 @@ void dhcp_handler(void *base) {
|
||||
(struct DHCPMessage *)(base + sizeof(struct EthernetFrame_head) +
|
||||
sizeof(struct IPV4Message) +
|
||||
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 &&
|
||||
dhcp->bp_options[2] == DHCP_OPTION_OFFER) {
|
||||
// printk("DHCP Offer\n");
|
||||
dhcp->opcode == 2) {
|
||||
printf("DHCP Offer\n");
|
||||
ip = dhcp->yiaddr;
|
||||
uint8_t nip1 = ip;
|
||||
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 >> 24));
|
||||
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);
|
||||
|
||||
unsigned char *options = &dhcp->bp_options[0];
|
||||
while (options[0] != 0xff) {
|
||||
if (options[0] == MESSAGE_TYPE_DNS) {
|
||||
// printk("DNS: %d.%d.%d.%d\n", options[2], options[3], options[4],
|
||||
// options[5]);
|
||||
printf("DNS: %d.%d.%d.%d\n", options[2], options[3], options[4],
|
||||
options[5]);
|
||||
dns = swap32(*(uint32_t *)&options[2]);
|
||||
} else if (options[0] == MESSAGE_TYPE_REQ_SUBNET_MASK) {
|
||||
// printk("Subnet Mask: %d.%d.%d.%d\n", options[2], options[3], options[4],
|
||||
// options[5]);
|
||||
printf("Subnet Mask: %d.%d.%d.%d\n", options[2], options[3], options[4],
|
||||
options[5]);
|
||||
submask = swap32(*(uint32_t *)&options[2]);
|
||||
} else if (options[0] == MESSAGE_TYPE_ROUTER) {
|
||||
// printk("Gateway: %d.%d.%d.%d\n", options[2], options[3], options[4],
|
||||
// options[5]);
|
||||
printf("Gateway: %d.%d.%d.%d\n", options[2], options[3], options[4],
|
||||
options[5]);
|
||||
gateway = swap32(*(uint32_t *)&options[2]);
|
||||
}
|
||||
options += options[1] + 2;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "../include/etherframe.h"
|
||||
#include "../include/memory.h"
|
||||
#include "../include/net.h"
|
||||
|
||||
#include "../include/pcnet.h"
|
||||
extern uint8_t mac0, mac1, mac2, mac3, mac4, mac5;
|
||||
// 以太网帧
|
||||
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);
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
dst[i] = src[i];
|
||||
netcard_send(buffer2, sizeof(struct EthernetFrame_head) + size +
|
||||
PcnetSend(buffer2, sizeof(struct EthernetFrame_head) + size +
|
||||
sizeof(struct EthernetFrame_tail));
|
||||
kfree(buffer2);
|
||||
}
|
||||
|
131
network/pcnet.c
131
network/pcnet.c
@ -6,6 +6,11 @@
|
||||
#include "../include/memory.h"
|
||||
#include "../include/printf.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;
|
||||
|
||||
@ -25,7 +30,9 @@ struct InitializationBlock initBlock;
|
||||
static struct BufferDescriptor* sendBufferDesc;
|
||||
static struct BufferDescriptor* recvBufferDesc;
|
||||
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) {
|
||||
register_interrupt_handler(0x20 + IRQ, (int)addr);
|
||||
}
|
||||
@ -61,7 +68,6 @@ void Activate() {
|
||||
printf("[pcnet]: io\n");
|
||||
io_out16(io_base + RDP16, 0x41);
|
||||
printf("[pcnet]: success.\n");
|
||||
|
||||
io_out16(io_base + RAP16, CSR4);
|
||||
uint32_t temp = io_in16(io_base + RDP16);
|
||||
io_out16(io_base + RAP16, CSR4);
|
||||
@ -91,7 +97,9 @@ static void init_Card_all() {
|
||||
mac4 = io_in8(io_base + APROM4);
|
||||
mac5 = io_in8(io_base + APROM5);
|
||||
reset_card();
|
||||
printf("SLEEP\n");
|
||||
clock_sleep(1);
|
||||
printf("END\n");
|
||||
|
||||
|
||||
|
||||
@ -148,6 +156,7 @@ static void init_Card_all() {
|
||||
gateway = 0xFFFFFFFF;
|
||||
submask = 0xFFFFFFFF;
|
||||
dns = 0xFFFFFFFF;
|
||||
printf("DHCP DISCOVERY %08x %08x %08x %08x %08x %08x\n",&mac0,&mac1,&mac2,&mac3,&mac4,&mac5);
|
||||
dhcp_discovery(&mac0);
|
||||
while (gateway == 0xFFFFFFFF && submask == 0xFFFFFFFF && dns == 0xFFFFFFFF &&
|
||||
ip == 0xFFFFFFFF) {
|
||||
@ -156,8 +165,8 @@ static void init_Card_all() {
|
||||
}
|
||||
|
||||
void init_pcnet_card() {
|
||||
printf("[\035kernel\036]: Loading pcnet driver.\n");
|
||||
register_interrupt_handler(pci_get_drive_irq(bus, dev, func),PCNET_IRQ);
|
||||
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) + 0x20,PCNET_IRQ);
|
||||
// 2,写COMMAND和STATUS寄存器
|
||||
uint32_t conf = pci_read_command_status(bus, dev, func);
|
||||
conf &= 0xffff0000; // 保留STATUS寄存器,清除COMMAND寄存器
|
||||
@ -170,7 +179,7 @@ void init_pcnet_card() {
|
||||
}
|
||||
|
||||
void PCNET_IRQ(registers_t *reg) {
|
||||
|
||||
printf("PCNET IRQ");
|
||||
io_out16(io_base + RAP16, CSR0);
|
||||
uint16_t temp = io_in16(io_base + RDP16);
|
||||
|
||||
@ -182,12 +191,91 @@ void PCNET_IRQ(registers_t *reg) {
|
||||
|
||||
if ((temp & 0x0100) == 0x0100)
|
||||
printf("PCNET INIT DONE\n");
|
||||
io_out8(0xa0, (0x60 + pci_get_drive_irq(bus, dev, func) - 0x8));
|
||||
io_out8(0x20, 0x62);
|
||||
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() {
|
||||
recv = 1;
|
||||
//printk("\nPCNET RECV: ");
|
||||
printk("\nPCNET RECV: ");
|
||||
for (; (recvBufferDesc[currentRecvBuffer].flags & 0x80000000) == 0;
|
||||
currentRecvBuffer = (currentRecvBuffer + 1) % 8) {
|
||||
if (!(recvBufferDesc[currentRecvBuffer].flags & 0x40000000) &&
|
||||
@ -204,7 +292,7 @@ void Recv() {
|
||||
}
|
||||
recv = 0;
|
||||
currentRecvBuffer = 0;
|
||||
//TODO Card_Recv_Handler(recvBufferDesc[currentRecvBuffer].address);
|
||||
Card_Recv_Handler(recvBufferDesc[currentRecvBuffer].address);
|
||||
|
||||
memclean(recvBufferDesc[currentRecvBuffer].address, 2048);
|
||||
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;
|
||||
}
|
158
sysapp/shell.c
158
sysapp/shell.c
@ -5,6 +5,7 @@
|
||||
#include "../include/task.h"
|
||||
#include "../include/cmos.h"
|
||||
#include "../include/vdisk.h"
|
||||
#include "../include/vfs.h"
|
||||
|
||||
extern Queue *key_char_queue;
|
||||
extern vdisk vdisk_ctl[10];
|
||||
@ -66,36 +67,62 @@ void cmd_echo(int argc, char **argv) {
|
||||
vga_putchar('\n');
|
||||
}
|
||||
|
||||
void cmd_proc(int argc, char **argv){
|
||||
void cmd_proc(int argc, char **argv) {
|
||||
if (argc <= 1) {
|
||||
printf("\033[Shell-PROC]: If there are too few parameters.\036\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!strcmp("list",argv[1])){
|
||||
if (!strcmp("list", argv[1])) {
|
||||
print_proc();
|
||||
} else if(!strcmp("kill",argv[1])){
|
||||
} else if (!strcmp("kill", argv[1])) {
|
||||
if (argc <= 2) {
|
||||
printf("\033[Shell-PROC-kill]: If there are too few parameters.\036\n");
|
||||
return;
|
||||
}
|
||||
int pid = strtol(argv[2],NULL,10);
|
||||
int pid = strtol(argv[2], NULL, 10);
|
||||
task_kill(pid);
|
||||
} else{
|
||||
} else {
|
||||
printf("\033[Shell-[PROC]]: Unknown parameter\036\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_date(){
|
||||
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);
|
||||
void cmd_date() {
|
||||
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);
|
||||
print_cpu_id();
|
||||
|
||||
vga_writestring("\n");
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -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");
|
||||
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) {
|
||||
@ -113,62 +149,85 @@ void cmd_del(int argc, char **argv) {
|
||||
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();
|
||||
}
|
||||
|
||||
void cmd_shutdown(){
|
||||
void cmd_shutdown() {
|
||||
shutdown_kernel();
|
||||
}
|
||||
|
||||
void cmd_debug(){
|
||||
void cmd_debug() {
|
||||
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");
|
||||
extern int acpi_enable_flag;
|
||||
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;
|
||||
print_proc_t(&index,get_current(),get_current()->next,0);
|
||||
printf("Process Runnable: %d\n",index);
|
||||
print_proc_t(&index, get_current(), get_current()->next, 0);
|
||||
printf("Process Runnable: %d\n", index);
|
||||
cmd_date();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (vdisk_ctl[i].flag) {
|
||||
vdisk vd = vdisk_ctl[i];
|
||||
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");
|
||||
register uint32_t eax asm("eax"),
|
||||
ecx asm("ecx"),
|
||||
esp asm("esp"),
|
||||
ebp asm("ebp"),
|
||||
ebx asm("ebx"),
|
||||
esi asm("esi"),
|
||||
edi asm("edi");
|
||||
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);
|
||||
ecx asm("ecx"),
|
||||
esp asm("esp"),
|
||||
ebp asm("ebp"),
|
||||
ebx asm("ebx"),
|
||||
esi asm("esi"),
|
||||
edi asm("edi");
|
||||
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);
|
||||
}
|
||||
|
||||
void cmd_disk(int argc,char **argv){
|
||||
if(argc > 1){
|
||||
if(!strcmp("list",argv[1])){
|
||||
void cmd_cd(int argc, char **argv) {
|
||||
if (argc == 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 - ");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (vdisk_ctl[i].flag) {
|
||||
vdisk vd = vdisk_ctl[i];
|
||||
char id = i + ('A');
|
||||
printf("(%c) ",id,vd.size,vd.DriveName);
|
||||
printf("(%c) ", id, vd.size, vd.DriveName);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(strlen(argv[1]) > 1){
|
||||
if (strlen(argv[1]) > 1) {
|
||||
printf("\033[DISK]: Cannot found disk.\036\n");
|
||||
return;
|
||||
}
|
||||
@ -177,12 +236,12 @@ void cmd_disk(int argc,char **argv){
|
||||
if (vdisk_ctl[i].flag) {
|
||||
vdisk vd = vdisk_ctl[i];
|
||||
char id = i + ('A');
|
||||
if(id == (argv[1][0])){
|
||||
if (id == (argv[1][0])) {
|
||||
printf("[Disk(%c)]: \n"
|
||||
" Size: %dMB\n"
|
||||
" Name: %s\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;
|
||||
}
|
||||
}
|
||||
@ -195,46 +254,48 @@ void cmd_disk(int argc,char **argv){
|
||||
if (vdisk_ctl[i].flag) {
|
||||
vdisk vd = vdisk_ctl[i];
|
||||
char id = i + ('A');
|
||||
printf("(%c) ",id,vd.size,vd.DriveName);
|
||||
printf("(%c) ", id, vd.size, vd.DriveName);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
char* user(){
|
||||
char *user() {
|
||||
printf("\n\nPlease type your username and password.\n");
|
||||
char com[MAX_COMMAND_LEN];
|
||||
char* username = "admin";
|
||||
char* password = "12345678";
|
||||
while (1){
|
||||
char *username = "admin";
|
||||
char *password = "12345678";
|
||||
while (1) {
|
||||
print("username/> ");
|
||||
if (gets(com, MAX_COMMAND_LEN) <= 0) continue;
|
||||
if(!strcmp(username,com)){
|
||||
if (!strcmp(username, com)) {
|
||||
break;
|
||||
} else printf("Cannot found username, Please check your info.\n");
|
||||
}
|
||||
while (1){
|
||||
while (1) {
|
||||
print("password/> ");
|
||||
if (gets(com, MAX_COMMAND_LEN) <= 0) continue;
|
||||
if(!strcmp(password,com)){
|
||||
if (!strcmp(password, com)) {
|
||||
break;
|
||||
} else printf("Unknown password, Please check your info.\n");
|
||||
}
|
||||
return username;
|
||||
}
|
||||
|
||||
void setup_shell(){
|
||||
char* user1 = user();
|
||||
void setup_shell() {
|
||||
char *user1 = "default";//user();
|
||||
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");
|
||||
|
||||
char com[MAX_COMMAND_LEN];
|
||||
char *argv[MAX_ARG_NR];
|
||||
int argc = -1;
|
||||
char *buffer[255];
|
||||
|
||||
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;
|
||||
argc = cmd_parse(com, argv, ' ');
|
||||
|
||||
@ -244,7 +305,7 @@ void setup_shell(){
|
||||
}
|
||||
|
||||
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]))
|
||||
cmd_echo(argc, argv);
|
||||
else if (!strcmp("clear", argv[0]))
|
||||
@ -261,12 +322,14 @@ void setup_shell(){
|
||||
cmd_del(argc, argv);
|
||||
else if (!strcmp("reset", argv[0]))
|
||||
cmd_reset();
|
||||
else if (!strcmp("shutdown", argv[0])||!strcmp("exit", argv[0]))
|
||||
else if (!strcmp("shutdown", argv[0]) || !strcmp("exit", argv[0]))
|
||||
cmd_shutdown();
|
||||
else if (!strcmp("debug", argv[0]))
|
||||
cmd_debug();
|
||||
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])) {
|
||||
vga_writestring("-=[\037CoolPotShell Helper\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("debug \032Print os debug info.\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]);
|
||||
}
|
||||
}
|
||||
|
@ -152,6 +152,7 @@ char *strcpy(char *dest, const char *src) {
|
||||
do {
|
||||
*dest++ = *src++;
|
||||
} while (*src != 0);
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
char *insert_str(char *buf, const char *str) {
|
||||
char *p = buf;
|
||||
|
||||
while (*str) {
|
||||
*p++ = *str++;
|
||||
void insert_str(char *str, char *insert_str, int pos) {
|
||||
for (int i = 0; i < strlen(insert_str); i++) {
|
||||
insert_char(str, pos + i, insert_str[i]);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void assert(int b, char *message) {
|
||||
|
Loading…
Reference in New Issue
Block a user