修复ISO9660文件系统读取问题
This commit is contained in:
parent
2c0b386a8b
commit
0fe64260c0
361
src/fs/iso9660.c
361
src/fs/iso9660.c
@ -6,6 +6,7 @@
|
|||||||
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector);
|
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector);
|
||||||
#define l9660_seekdir(dir, pos) (l9660_seek(&(dir)->file, L9660_SEEK_SET, (pos)))
|
#define l9660_seekdir(dir, pos) (l9660_seek(&(dir)->file, L9660_SEEK_SET, (pos)))
|
||||||
#define l9660_telldir(dir) (l9660_tell(&(dir)->file))
|
#define l9660_telldir(dir) (l9660_tell(&(dir)->file))
|
||||||
|
xi#define get_root_dir(vfs) ((l9660_fs_status_t *)(vfs->cache))->root_dir
|
||||||
|
|
||||||
#define SEEK_END L9660_SEEK_END
|
#define SEEK_END L9660_SEEK_END
|
||||||
#define SEEK_SET L9660_SEEK_SET
|
#define SEEK_SET L9660_SEEK_SET
|
||||||
@ -41,77 +42,59 @@ static char gbuf[2048];
|
|||||||
|
|
||||||
#define get_now_dir(vfs) ((l9660_fs_status_t *)(vfs->cache))->now_dir
|
#define get_now_dir(vfs) ((l9660_fs_status_t *)(vfs->cache))->now_dir
|
||||||
|
|
||||||
static char *strchrnul(const char *s, int c)
|
|
||||||
{
|
static char *strchrnul(const char *s, int c) {
|
||||||
while (*s)
|
while (*s) {
|
||||||
{
|
|
||||||
if ((*s++) == c)
|
if ((*s++) == c)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (char *)s;
|
return (char *)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t
|
static inline uint16_t fsectoff(l9660_file *f) { return f->position % 2048; }
|
||||||
fsectoff(l9660_file
|
|
||||||
*f)
|
static inline uint32_t fsector(l9660_file *f) { return f->position / 2048; }
|
||||||
{
|
|
||||||
return f->position % 2048;
|
static inline uint32_t fnextsectpos(l9660_file *f) {
|
||||||
|
return (f->position + 2047) & ~2047;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t
|
l9660_status l9660_openfs(l9660_fs *fs,
|
||||||
fsector(l9660_file
|
bool (*read_sector)(l9660_fs *fs, void *buf,
|
||||||
*f)
|
uint32_t sector),
|
||||||
{
|
uint8_t disk_number) {
|
||||||
return f->position / 2048;
|
fs->read_sector = read_sector;
|
||||||
}
|
fs->disk_number = disk_number;
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
fs->read_sector = read_sector;
|
|
||||||
fs->disk_number = disk_number;
|
|
||||||
logkf("fs--- %08x\n",fs->read_sector);
|
|
||||||
#ifndef L9660_SINGLEBUFFER
|
#ifndef L9660_SINGLEBUFFER
|
||||||
l9660_vdesc_primary *pvd = PVD(&fs->pvd);
|
l9660_vdesc_primary *pvd = PVD(&fs->pvd);
|
||||||
#else
|
#else
|
||||||
last_file = NULL;
|
last_file = NULL;
|
||||||
l9660_vdesc_primary *pvd = PVD(gbuf);
|
l9660_vdesc_primary *pvd = PVD(gbuf);
|
||||||
#endif
|
#endif
|
||||||
uint32_t idx = 0x10;
|
uint32_t idx = 0x10;
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
// Read next sector
|
||||||
// Read next sector
|
if (!read_sector(fs, pvd, idx))
|
||||||
if (!read_sector(fs, pvd, idx))
|
return L9660_EIO;
|
||||||
return L9660_EIO;
|
|
||||||
|
|
||||||
// Validate magic
|
// Validate magic
|
||||||
if (
|
if (memcmp(pvd->hdr.magic, "CD001", 5) != 0)
|
||||||
memcmp(pvd
|
return L9660_EBADFS;
|
||||||
->hdr.magic,
|
|
||||||
"CD001", 5) != 0)
|
|
||||||
return L9660_EBADFS;
|
|
||||||
|
|
||||||
if (pvd->hdr.type == 1)
|
if (pvd->hdr.type == 1)
|
||||||
break; // Found PVD
|
break; // Found PVD
|
||||||
else if (pvd->hdr.type == 255)
|
else if (pvd->hdr.type == 255)
|
||||||
return L9660_EBADFS;
|
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)
|
#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;
|
l9660_file *f = &dir->file;
|
||||||
#ifndef L9660_SINGLEBUFFER
|
#ifndef L9660_SINGLEBUFFER
|
||||||
l9660_dirent *dirent = &PVD(&fs->pvd)->root_dir_ent;
|
l9660_dirent *dirent = &PVD(&fs->pvd)->root_dir_ent;
|
||||||
@ -127,35 +110,32 @@ l9660_status l9660_fs_open_root(l9660_dir *dir, l9660_fs *fs)
|
|||||||
return L9660_OK;
|
return L9660_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static l9660_status buffer(l9660_file *f)
|
static l9660_status buffer(l9660_file *f) {
|
||||||
{
|
|
||||||
#ifdef L9660_SINGLEBUFFER
|
#ifdef L9660_SINGLEBUFFER
|
||||||
last_file = f;
|
last_file = f;
|
||||||
#endif
|
#endif
|
||||||
logkf("%08x %08x\n",read_sector,f->fs->read_sector);
|
|
||||||
if (!f->fs->read_sector(f->fs, BUF(f), f->first_sector + f->position / 2048))
|
if (!f->fs->read_sector(f->fs, BUF(f), f->first_sector + f->position / 2048))
|
||||||
return L9660_EIO;
|
return L9660_EIO;
|
||||||
else
|
else
|
||||||
return L9660_OK;
|
return L9660_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static l9660_status prebuffer(l9660_file *f)
|
static l9660_status prebuffer(l9660_file *f) {
|
||||||
{
|
|
||||||
if (!HAVEBUFFER(f) || (f->position % 2048) == 0)
|
if (!HAVEBUFFER(f) || (f->position % 2048) == 0)
|
||||||
return buffer(f);
|
return buffer(f);
|
||||||
else
|
else
|
||||||
return L9660_OK;
|
return L9660_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char *name, bool isdir)
|
static l9660_status openat_raw(l9660_file *child, l9660_dir *parent,
|
||||||
{
|
const char *name, bool isdir) {
|
||||||
l9660_status rv;
|
l9660_status rv;
|
||||||
l9660_dirent *dent = NULL;
|
l9660_dirent *dent = NULL;
|
||||||
if ((rv = l9660_seekdir(parent, 0)))
|
if ((rv = l9660_seekdir(parent, 0)))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
const char *seg = name;
|
const char *seg = name;
|
||||||
name = strchrnul(name, '/');
|
name = strchrnul(name, '/');
|
||||||
size_t seglen = name - seg;
|
size_t seglen = name - seg;
|
||||||
@ -165,14 +145,12 @@ static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char
|
|||||||
seg = "\0";
|
seg = "\0";
|
||||||
|
|
||||||
/* ISO9660 stores ".." as '\1' */
|
/* ISO9660 stores ".." as '\1' */
|
||||||
if (seglen == 2 && seg[0] == '.' && seg[1] == '.')
|
if (seglen == 2 && seg[0] == '.' && seg[1] == '.') {
|
||||||
{
|
|
||||||
seg = "\1";
|
seg = "\1";
|
||||||
seglen = 1;
|
seglen = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
|
||||||
if ((rv = l9660_readdir(parent, &dent)))
|
if ((rv = l9660_readdir(parent, &dent)))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
@ -204,20 +182,17 @@ static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char
|
|||||||
child->first_sector = READ32(dent->sector) + dent->xattr_length;
|
child->first_sector = READ32(dent->sector) + dent->xattr_length;
|
||||||
child->length = READ32(dent->size);
|
child->length = READ32(dent->size);
|
||||||
child->position = 0;
|
child->position = 0;
|
||||||
|
parent->file.position = 0;
|
||||||
if (*name && (dent->flags & DENT_ISDIR) != 0)
|
if (*name && (dent->flags & DENT_ISDIR) != 0)
|
||||||
return L9660_ENOTDIR;
|
return L9660_ENOTDIR;
|
||||||
|
|
||||||
parent = (l9660_dir *)child;
|
parent = (l9660_dir *)child;
|
||||||
} while (*name);
|
} while (*name);
|
||||||
|
|
||||||
if (isdir)
|
if (isdir) {
|
||||||
{
|
|
||||||
if ((dent->flags & DENT_ISDIR) == 0)
|
if ((dent->flags & DENT_ISDIR) == 0)
|
||||||
return L9660_ENOTDIR;
|
return L9660_ENOTDIR;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((dent->flags & DENT_ISDIR) != 0)
|
if ((dent->flags & DENT_ISDIR) != 0)
|
||||||
return L9660_ENOTFILE;
|
return L9660_ENOTFILE;
|
||||||
}
|
}
|
||||||
@ -225,33 +200,28 @@ static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char
|
|||||||
return L9660_OK;
|
return L9660_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
l9660_status l9660_opendirat(l9660_dir *dir, l9660_dir *parent, const char *path)
|
l9660_status l9660_opendirat(l9660_dir *dir, l9660_dir *parent,
|
||||||
{
|
const char *path) {
|
||||||
return openat_raw(&dir->file, parent, path, true);
|
return openat_raw(&dir->file, parent, path, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned aligneven(unsigned v)
|
static inline unsigned aligneven(unsigned v) { return v + (v & 1); }
|
||||||
{
|
|
||||||
return v + (v & 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
l9660_status l9660_readdir(l9660_dir *dir, l9660_dirent **pdirent)
|
l9660_status l9660_readdir(l9660_dir *dir, l9660_dirent **pdirent) {
|
||||||
{
|
|
||||||
l9660_status rv;
|
l9660_status rv;
|
||||||
l9660_file *f = &dir->file;
|
l9660_file *f = &dir->file;
|
||||||
|
|
||||||
rebuffer:
|
rebuffer:
|
||||||
if (f->position >= f->length)
|
if (f->position >= f->length) {
|
||||||
{
|
|
||||||
*pdirent = NULL;
|
*pdirent = NULL;
|
||||||
|
f->position = 0;
|
||||||
return L9660_OK;
|
return L9660_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rv = prebuffer(f)))
|
if ((rv = prebuffer(f)))
|
||||||
return rv;
|
return rv;
|
||||||
char *off = BUF(f) + fsectoff(f);
|
char *off = BUF(f) + fsectoff(f);
|
||||||
if (*off == 0)
|
if (*off == 0) {
|
||||||
{
|
|
||||||
// Padded end of sector
|
// Padded end of sector
|
||||||
f->position = fnextsectpos(f);
|
f->position = fnextsectpos(f);
|
||||||
goto rebuffer;
|
goto rebuffer;
|
||||||
@ -264,19 +234,17 @@ rebuffer:
|
|||||||
return L9660_OK;
|
return L9660_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
l9660_status l9660_openat(l9660_file *child, l9660_dir *parent, const char *name)
|
l9660_status l9660_openat(l9660_file *child, l9660_dir *parent,
|
||||||
{
|
const char *name) {
|
||||||
return openat_raw(child, parent, name, false);
|
return openat_raw(child, parent, name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Seek the file to \p offset from \p whence */
|
/*! Seek the file to \p offset from \p whence */
|
||||||
l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset)
|
l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset) {
|
||||||
{
|
|
||||||
l9660_status rv;
|
l9660_status rv;
|
||||||
uint32_t cursect = fsector(f);
|
uint32_t cursect = fsector(f);
|
||||||
|
|
||||||
switch (whence)
|
switch (whence) {
|
||||||
{
|
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
f->position = offset;
|
f->position = offset;
|
||||||
break;
|
break;
|
||||||
@ -290,8 +258,7 @@ l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsector(f) != cursect && fsectoff(f) != 0)
|
if (fsector(f) != cursect && fsectoff(f) != 0) {
|
||||||
{
|
|
||||||
if ((rv = buffer(f)))
|
if ((rv = buffer(f)))
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -299,13 +266,9 @@ l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset)
|
|||||||
return L9660_OK;
|
return L9660_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t l9660_tell(l9660_file *f)
|
uint32_t l9660_tell(l9660_file *f) { return f->position; }
|
||||||
{
|
|
||||||
return f->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
l9660_status l9660_read(l9660_file *f, void *buf, size_t size, size_t *read)
|
l9660_status l9660_read(l9660_file *f, void *buf, size_t size, size_t *read) {
|
||||||
{
|
|
||||||
l9660_status rv;
|
l9660_status rv;
|
||||||
|
|
||||||
if ((rv = prebuffer(f)))
|
if ((rv = prebuffer(f)))
|
||||||
@ -324,91 +287,54 @@ l9660_status l9660_read(l9660_file *f, void *buf, size_t size, size_t *read)
|
|||||||
|
|
||||||
return L9660_OK;
|
return L9660_OK;
|
||||||
}
|
}
|
||||||
|
char *strdup(const char *s) {
|
||||||
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector)
|
size_t l = strlen(s);
|
||||||
{
|
char *d = kmalloc(l + 1);
|
||||||
return CDROM_Read(sector,1,buf,fs->disk_number);
|
if (!d)
|
||||||
|
return NULL;
|
||||||
|
return memcpy(d, s, l + 1);
|
||||||
|
}
|
||||||
|
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector) {
|
||||||
|
return CDROM_Read(sector, 1, buf, fs->disk_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ISO_Check(uint8_t disk_number)
|
bool ISO_Check(uint8_t disk_number) {
|
||||||
{
|
|
||||||
unsigned char *buffer = kmalloc(2049); // 假设扇区大小为 2048 字节
|
unsigned char *buffer = kmalloc(2049); // 假设扇区大小为 2048 字节
|
||||||
bool ok = CDROM_Read(16, 1, buffer, disk_number);
|
bool ok = CDROM_Read(16, 1, buffer, disk_number);
|
||||||
|
|
||||||
if (buffer[0] == 0x01 && buffer[1] == 'C' && buffer[2] == 'D' && buffer[3] == '0' &&
|
if (buffer[0] == 0x01 && buffer[1] == 'C' && buffer[2] == 'D' &&
|
||||||
buffer[4] == '0' && buffer[5] == '1')
|
buffer[3] == '0' && buffer[4] == '0' && buffer[5] == '1') {
|
||||||
{
|
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
return true; // 是 ISO9660 文件系统
|
return true; // 是 ISO9660 文件系统
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
return false; // 不是 ISO9660 文件系统
|
return false; // 不是 ISO9660 文件系统
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISO_InitFs(struct vfs_t *vfs, uint8_t disk_number)
|
void ISO_InitFs(struct vfs_t *vfs, uint8_t disk_number) {
|
||||||
{
|
|
||||||
l9660_fs_status_t *fs_m;
|
l9660_fs_status_t *fs_m;
|
||||||
fs_m = (l9660_fs_status_t*) kmalloc(sizeof(l9660_fs_status_t));
|
fs_m = (l9660_fs_status_t *)kmalloc(sizeof(l9660_fs_status_t));
|
||||||
|
|
||||||
fs_m->fs = (l9660_fs *)kmalloc(sizeof(l9660_fs));
|
fs_m->fs = (l9660_fs *)kmalloc(sizeof(l9660_fs));
|
||||||
vfs->cache = (void *)fs_m;
|
vfs->cache = (void *)fs_m;
|
||||||
printf("ISO Load init...");
|
l9660_openfs(fs_m->fs, read_sector, disk_number);
|
||||||
l9660_openfs(fs_m->fs,read_sector,disk_number);
|
|
||||||
l9660_fs_open_root(&fs_m->root_dir, fs_m->fs);
|
l9660_fs_open_root(&fs_m->root_dir, fs_m->fs);
|
||||||
fs_m->now_dir = fs_m->root_dir;
|
fs_m->now_dir = fs_m->root_dir;
|
||||||
logkf("%08x\n",vfs->cache);
|
logkf("%08x\n", vfs->cache);
|
||||||
/*
|
|
||||||
l9660_file file;
|
|
||||||
for (;;) {
|
|
||||||
l9660_dirent *dent;
|
|
||||||
l9660_readdir(root_dir, &dent);
|
|
||||||
|
|
||||||
if (dent == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
printf("%.*s\n", dent->name_len, dent->name);
|
|
||||||
}
|
|
||||||
a = l9660_openat(&file, dir, "fuck.txt");
|
|
||||||
if(a) {
|
|
||||||
printf("failed\n");
|
|
||||||
for(;;);
|
|
||||||
}
|
|
||||||
for(;;) {
|
|
||||||
char buf[128];
|
|
||||||
size_t read;
|
|
||||||
l9660_read(&file, buf, 128, &read);
|
|
||||||
if (read == 0)
|
|
||||||
break;
|
|
||||||
for(int i = 0;i<read;i++) {
|
|
||||||
printf("%c",buf[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (1)
|
|
||||||
asm("hlt");
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ISO_CDFile(){}
|
void ISO_CDFile() {}
|
||||||
|
|
||||||
vfs_file *ISO_GetFile(char* path1){
|
void ISO_CopyCache(struct vfs_t *dest, struct vfs_t *src) {
|
||||||
// strtoupper(path1);
|
|
||||||
// if (strcmp(path1, "/") == 0) {
|
|
||||||
// return fs_m->root_dir;
|
|
||||||
// }
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ISO_CopyCache(struct vfs_t *dest, struct vfs_t *src){
|
|
||||||
dest->cache = kmalloc(sizeof(l9660_fs_status_t));
|
dest->cache = kmalloc(sizeof(l9660_fs_status_t));
|
||||||
memcpy(dest->cache, src->cache, sizeof(l9660_fs_status_t));
|
memcpy(dest->cache, src->cache, sizeof(l9660_fs_status_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ISO_cd(struct vfs_t *vfs, char *dictname){
|
int ISO_cd(struct vfs_t *vfs, char *dictname) {
|
||||||
//
|
//
|
||||||
// strtoupper(dictname);
|
// strtoupper(dictname);
|
||||||
//
|
//
|
||||||
if (strcmp(dictname, "/") == 0) {
|
if (strcmp(dictname, "/") == 0) {
|
||||||
while (vfs->path->ctl->all != 0) {
|
while (vfs->path->ctl->all != 0) {
|
||||||
kfree((FindForCount(vfs->path->ctl->all, vfs->path)->val));
|
kfree((FindForCount(vfs->path->ctl->all, vfs->path)->val));
|
||||||
@ -418,10 +344,20 @@ int ISO_cd(struct vfs_t *vfs, char *dictname){
|
|||||||
get_now_dir(vfs) = fs_m->root_dir;
|
get_now_dir(vfs) = fs_m->root_dir;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
int free_flag = 0;
|
||||||
l9660_dir finfo;
|
l9660_dir finfo;
|
||||||
l9660_status a = l9660_opendirat(&finfo,&get_now_dir(vfs),dictname);
|
l9660_status a;
|
||||||
|
RE:
|
||||||
|
a = l9660_opendirat(&finfo, &get_now_dir(vfs), dictname);
|
||||||
if (a) {
|
if (a) {
|
||||||
|
if (free_flag) {
|
||||||
|
kfree(dictname);
|
||||||
|
} else {
|
||||||
|
dictname = strdup(dictname);
|
||||||
|
strtoupper(dictname);
|
||||||
|
free_flag = 1;
|
||||||
|
goto RE;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
get_now_dir(vfs) = finfo;
|
get_now_dir(vfs) = finfo;
|
||||||
@ -435,37 +371,64 @@ int ISO_cd(struct vfs_t *vfs, char *dictname){
|
|||||||
kfree((FindForCount(vfs->path->ctl->all, vfs->path)->val));
|
kfree((FindForCount(vfs->path->ctl->all, vfs->path)->val));
|
||||||
DeleteVal(vfs->path->ctl->all, vfs->path);
|
DeleteVal(vfs->path->ctl->all, vfs->path);
|
||||||
}
|
}
|
||||||
|
if (free_flag) {
|
||||||
|
kfree(dictname);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ISO_ReadFile(struct vfs_t *vfs, char *path, char *buffer){
|
bool ISO_ReadFile(struct vfs_t *vfs, char *path, char *buffer) {
|
||||||
l9660_file file;
|
l9660_file file;
|
||||||
l9660_status a = l9660_openat(&file, &get_now_dir(vfs),path);
|
l9660_status a;
|
||||||
if(a) {
|
int free_flag = 0;
|
||||||
|
RE:
|
||||||
|
a = l9660_openat(&file, &get_now_dir(vfs), path);
|
||||||
|
if (a) {
|
||||||
|
if (free_flag) {
|
||||||
|
kfree(path);
|
||||||
|
} else {
|
||||||
|
path = strdup(path);
|
||||||
|
strtoupper(path);
|
||||||
|
free_flag = 1;
|
||||||
|
goto RE;
|
||||||
|
}
|
||||||
return false; // not found
|
return false; // not found
|
||||||
}
|
}
|
||||||
for(;;) {
|
for (;;) {
|
||||||
size_t read;
|
size_t read;
|
||||||
l9660_read(&file, buffer, 128, &read);
|
l9660_read(&file, buffer, 128, &read);
|
||||||
if (read == 0)
|
if (read == 0)
|
||||||
break;
|
break;
|
||||||
buffer += read;
|
buffer += read;
|
||||||
}
|
}
|
||||||
|
if (free_flag) {
|
||||||
|
kfree(path);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List *ISO_ListFile(struct vfs_t *vfs, char *dictpath){
|
List *ISO_ListFile(struct vfs_t *vfs, char *dictpath) {
|
||||||
l9660_dir finfo;
|
l9660_dir finfo;
|
||||||
if(strcmp(dictpath,"") == 0)
|
int free_flag = 0;
|
||||||
|
if (strcmp(dictpath, "") == 0)
|
||||||
finfo = get_now_dir(vfs);
|
finfo = get_now_dir(vfs);
|
||||||
else {
|
else {
|
||||||
l9660_status a = l9660_opendirat(&finfo,&get_now_dir(vfs),dictpath);
|
l9660_status a;
|
||||||
|
RE:
|
||||||
|
a = l9660_opendirat(&finfo, &get_now_dir(vfs), dictpath);
|
||||||
if (a) {
|
if (a) {
|
||||||
|
if (free_flag) {
|
||||||
|
kfree(dictpath);
|
||||||
|
} else {
|
||||||
|
dictpath = strdup(dictpath);
|
||||||
|
strtoupper(dictpath);
|
||||||
|
free_flag = 1;
|
||||||
|
goto RE;
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List *result = NewList();
|
List *result = NewList();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
l9660_dirent *dent;
|
l9660_dirent *dent;
|
||||||
@ -474,19 +437,26 @@ List *ISO_ListFile(struct vfs_t *vfs, char *dictpath){
|
|||||||
if (dent == 0)
|
if (dent == 0)
|
||||||
break;
|
break;
|
||||||
vfs_file *d = kmalloc(sizeof(vfs_file));
|
vfs_file *d = kmalloc(sizeof(vfs_file));
|
||||||
memclean((void *)d,sizeof(vfs_file));
|
memclean((void *)d, sizeof(vfs_file));
|
||||||
int j = 0;
|
int j = 0;
|
||||||
if(memcmp("\0",dent->name,dent->name_len) == 0) {
|
if (memcmp("\0", dent->name, dent->name_len) == 0) {
|
||||||
d->name[j++] = '.';
|
if (finfo.file.first_sector == get_root_dir(vfs).file.first_sector) {
|
||||||
d->name[j] = 0;
|
kfree(d);
|
||||||
} else if (memcmp("\1",dent->name,dent->name_len) == 0) {
|
continue;
|
||||||
d->name[j++] = '.';
|
|
||||||
d->name[j++] = '.';
|
|
||||||
d->name[j] = 0;
|
|
||||||
}
|
}
|
||||||
else
|
d->name[j++] = '.';
|
||||||
for(;j<dent->name_len;j++) {
|
d->name[j] = 0;
|
||||||
if(dent->name[j] == ';') {
|
} else if (memcmp("\1", dent->name, dent->name_len) == 0) {
|
||||||
|
if (finfo.file.first_sector == get_root_dir(vfs).file.first_sector) {
|
||||||
|
kfree(d);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
d->name[j++] = '.';
|
||||||
|
d->name[j++] = '.';
|
||||||
|
d->name[j] = 0;
|
||||||
|
} else
|
||||||
|
for (; j < dent->name_len; j++) {
|
||||||
|
if (dent->name[j] == ';') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,27 +464,42 @@ List *ISO_ListFile(struct vfs_t *vfs, char *dictpath){
|
|||||||
}
|
}
|
||||||
d->name[j] = 0;
|
d->name[j] = 0;
|
||||||
d->type = FLE;
|
d->type = FLE;
|
||||||
if(dent->flags & DENT_ISDIR) {
|
if (dent->flags & DENT_ISDIR) {
|
||||||
d->type = DIR;
|
d->type = DIR;
|
||||||
} else {
|
} else {
|
||||||
d->size = READ32(dent->size);
|
d->size = READ32(dent->size);
|
||||||
}
|
}
|
||||||
AddVal(d, result);
|
AddVal(d, result);
|
||||||
}
|
}
|
||||||
|
if (free_flag) {
|
||||||
|
kfree(dictpath);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
int ISO_FileSize(struct vfs_t *vfs, char *filename) {
|
int ISO_FileSize(struct vfs_t *vfs, char *filename) {
|
||||||
l9660_file file;
|
l9660_file file;
|
||||||
l9660_status a = l9660_openat(&file, &get_now_dir(vfs),filename);
|
l9660_status a;
|
||||||
if(a) {
|
int free_flag = 0;
|
||||||
|
RE:
|
||||||
|
a = l9660_openat(&file, &get_now_dir(vfs), filename);
|
||||||
|
if (a) {
|
||||||
|
if (free_flag) {
|
||||||
|
kfree(filename);
|
||||||
|
} else {
|
||||||
|
filename = strdup(filename);
|
||||||
|
strtoupper(filename);
|
||||||
|
free_flag = 1;
|
||||||
|
goto RE;
|
||||||
|
}
|
||||||
return -1; // not found
|
return -1; // not found
|
||||||
}
|
}
|
||||||
|
if (free_flag) {
|
||||||
|
kfree(filename);
|
||||||
|
}
|
||||||
return file.length;
|
return file.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_iso9660() {
|
||||||
void init_iso9660()
|
|
||||||
{
|
|
||||||
vfs_t fs;
|
vfs_t fs;
|
||||||
fs.flag = 1;
|
fs.flag = 1;
|
||||||
fs.cache = NULL;
|
fs.cache = NULL;
|
||||||
|
@ -122,6 +122,7 @@ typedef struct tss_table {
|
|||||||
} tss_entry;
|
} tss_entry;
|
||||||
|
|
||||||
void write_tss(int32_t num, uint16_t ss0, uint32_t esp0);
|
void write_tss(int32_t num, uint16_t ss0, uint32_t esp0);
|
||||||
|
void set_kernel_stack(uintptr_t stack);
|
||||||
|
|
||||||
void gdt_install();
|
void gdt_install();
|
||||||
void idt_install();
|
void idt_install();
|
||||||
|
46
src/include/elf.h
Normal file
46
src/include/elf.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef CRASHPOWEROS_ELF_H
|
||||||
|
#define CRASHPOWEROS_ELF_H
|
||||||
|
|
||||||
|
#define ELF_MAGIC 0x464c457f
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
/* elf 32 header */
|
||||||
|
typedef struct elf32hdr {
|
||||||
|
uint32_t magic; // equal ELF_MAGIC
|
||||||
|
char elf[12];
|
||||||
|
uint16_t type;
|
||||||
|
uint16_t machine;
|
||||||
|
uint32_t version;
|
||||||
|
uint32_t entry; // program entry
|
||||||
|
uint32_t phoff; // offset of program header
|
||||||
|
uint32_t shoff;
|
||||||
|
uint32_t flags;
|
||||||
|
uint16_t ehsize;
|
||||||
|
uint16_t phentsize;
|
||||||
|
uint16_t phnum; // number of program header
|
||||||
|
uint16_t shentsize;
|
||||||
|
uint16_t shnum;
|
||||||
|
uint16_t shstrndx;
|
||||||
|
}elf32hdr_t;
|
||||||
|
|
||||||
|
/* proghdr type */
|
||||||
|
#define ELF_PROG_LOAD 1
|
||||||
|
|
||||||
|
/* proghdr flag*/
|
||||||
|
#define ELF_PROG_EXEC 0x1
|
||||||
|
#define ELF_PROG_WRITE 0x2
|
||||||
|
#define ELF_PROG_READ 0x4
|
||||||
|
|
||||||
|
struct proghdr{
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t off;
|
||||||
|
uint32_t vaddr;
|
||||||
|
uint32_t paddr;
|
||||||
|
uint32_t filesz;
|
||||||
|
uint32_t memsz;
|
||||||
|
uint32_t flag;
|
||||||
|
uint32_t align;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -93,4 +93,6 @@ void alloc_frame_line(page_t *page, unsigned line,int is_kernel, int is_writable
|
|||||||
|
|
||||||
void free_frame(page_t *page);
|
void free_frame(page_t *page);
|
||||||
|
|
||||||
|
void page_flush(page_directory_t *dir);
|
||||||
|
|
||||||
#endif //CRASHPOWEROS_MEMORY_H
|
#endif //CRASHPOWEROS_MEMORY_H
|
||||||
|
@ -86,6 +86,12 @@ void free_frame(page_t *page) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void page_flush(page_directory_t *dir){
|
||||||
|
asm volatile("invlpg (%0)" ::"r"(&dir->tablesPhysical));
|
||||||
|
current_directory = dir;
|
||||||
|
//asm volatile("mov %0, %%cr3" : : "r"(&dir->physicalAddr));
|
||||||
|
}
|
||||||
|
|
||||||
void switch_page_directory(page_directory_t *dir) {
|
void switch_page_directory(page_directory_t *dir) {
|
||||||
current_directory = dir;
|
current_directory = dir;
|
||||||
asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical));
|
asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical));
|
||||||
@ -200,7 +206,7 @@ void init_page(multiboot_t *mboot) {
|
|||||||
current_directory = kernel_directory;
|
current_directory = kernel_directory;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (i < placement_address) {
|
while (i < placement_address + 0x30000) {
|
||||||
// 内核部分对ring3而言可读不可写 | 无偏移页表映射
|
// 内核部分对ring3而言可读不可写 | 无偏移页表映射
|
||||||
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
|
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
|
||||||
i += 0x1000;
|
i += 0x1000;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "../include/common.h"
|
#include "../include/common.h"
|
||||||
#include "../include/graphics.h"
|
#include "../include/graphics.h"
|
||||||
#include "../include/io.h"
|
#include "../include/io.h"
|
||||||
|
#include "../include/description_table.h"
|
||||||
|
|
||||||
struct task_struct *running_proc_head = NULL;
|
struct task_struct *running_proc_head = NULL;
|
||||||
struct task_struct *wait_proc_head = NULL;
|
struct task_struct *wait_proc_head = NULL;
|
||||||
@ -157,7 +158,8 @@ void change_task_to(struct task_struct *next) {
|
|||||||
struct task_struct *prev = current;
|
struct task_struct *prev = current;
|
||||||
current = next;
|
current = next;
|
||||||
|
|
||||||
switch_page_directory(current->pgd_dir);
|
page_flush(current->pgd_dir);
|
||||||
|
set_kernel_stack(current->stack);
|
||||||
switch_to(&(prev->context), &(current->context));
|
switch_to(&(prev->context), &(current->context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,7 +174,7 @@ int32_t kernel_thread(int (*fn)(void *), void *arg,char* name) {
|
|||||||
new_task->state = TASK_RUNNABLE;
|
new_task->state = TASK_RUNNABLE;
|
||||||
new_task->stack = current;
|
new_task->stack = current;
|
||||||
new_task->pid = now_pid++;
|
new_task->pid = now_pid++;
|
||||||
new_task->pgd_dir = kernel_directory;
|
new_task->pgd_dir = clone_directory(kernel_directory) ;
|
||||||
|
|
||||||
new_task->name = name;
|
new_task->name = name;
|
||||||
|
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
#include "../include/cmos.h"
|
#include "../include/cmos.h"
|
||||||
#include "../include/vdisk.h"
|
#include "../include/vdisk.h"
|
||||||
#include "../include/vfs.h"
|
#include "../include/vfs.h"
|
||||||
|
#include "../include/common.h"
|
||||||
#include "../include/sb16.h"
|
#include "../include/sb16.h"
|
||||||
|
#include "../include/elf.h"
|
||||||
|
|
||||||
extern Queue *key_char_queue;
|
extern Queue *key_char_queue;
|
||||||
extern vdisk vdisk_ctl[10];
|
extern vdisk vdisk_ctl[10];
|
||||||
@ -239,6 +241,8 @@ void cmd_type(int argc,char ** argv){
|
|||||||
printf("%s",buffer);
|
printf("%s",buffer);
|
||||||
else printf("Cannot read file.\n");
|
else printf("Cannot read file.\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user