文件系统修复
This commit is contained in:
parent
f1f2a45882
commit
9221f2e106
6
build.py
6
build.py
|
@ -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")
|
323
driver/ide.c
323
driver/ide.c
|
@ -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.
|
||||||
|
@ -584,152 +707,4 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
129
driver/vdisk.c
129
driver/vdisk.c
|
@ -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) {
|
void Disk_Read(unsigned int lba, unsigned int number, void *buffer,
|
||||||
return;
|
char drive) {
|
||||||
}
|
if (have_vdisk(drive)) {
|
||||||
fifo8_get(&drive_fifo[drive_code]);
|
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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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_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
|
||||||
|
|
|
@ -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 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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 >= 40) outb(0xA0, 0x20); // 中断号 >= 40,来自从片,发送EOI给从片
|
if(regs.int_no != 0x2b) {
|
||||||
outb(0x20, 0x20); // 发送EOI给主片
|
if (regs.int_no >= 40) outb(0xA0, 0x20); // 中断号 >= 40,来自从片,发送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(®s); // 传入寄存器
|
handler(®s); // 传入寄存器
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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){
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
131
network/pcnet.c
131
network/pcnet.c
|
@ -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;
|
||||||
|
}
|
158
sysapp/shell.c
158
sysapp/shell.c
|
@ -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,62 +149,85 @@ 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");
|
||||||
register uint32_t eax asm("eax"),
|
register uint32_t eax asm("eax"),
|
||||||
ecx asm("ecx"),
|
ecx asm("ecx"),
|
||||||
esp asm("esp"),
|
esp asm("esp"),
|
||||||
ebp asm("ebp"),
|
ebp asm("ebp"),
|
||||||
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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue