修复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);
|
||||
#define l9660_seekdir(dir, pos) (l9660_seek(&(dir)->file, L9660_SEEK_SET, (pos)))
|
||||
#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_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
|
||||
|
||||
static char *strchrnul(const char *s, int c)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
fs->read_sector = read_sector;
|
||||
fs->disk_number = disk_number;
|
||||
logkf("fs--- %08x\n",fs->read_sector);
|
||||
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;
|
||||
#ifndef L9660_SINGLEBUFFER
|
||||
l9660_vdesc_primary *pvd = PVD(&fs->pvd);
|
||||
l9660_vdesc_primary *pvd = PVD(&fs->pvd);
|
||||
#else
|
||||
last_file = NULL;
|
||||
last_file = NULL;
|
||||
l9660_vdesc_primary *pvd = PVD(gbuf);
|
||||
#endif
|
||||
uint32_t idx = 0x10;
|
||||
for (;;)
|
||||
{
|
||||
// Read next sector
|
||||
if (!read_sector(fs, pvd, idx))
|
||||
return L9660_EIO;
|
||||
uint32_t idx = 0x10;
|
||||
for (;;) {
|
||||
// Read next sector
|
||||
if (!read_sector(fs, pvd, idx))
|
||||
return L9660_EIO;
|
||||
|
||||
// Validate magic
|
||||
if (
|
||||
memcmp(pvd
|
||||
->hdr.magic,
|
||||
"CD001", 5) != 0)
|
||||
return L9660_EBADFS;
|
||||
// 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;
|
||||
if (pvd->hdr.type == 1)
|
||||
break; // Found PVD
|
||||
else if (pvd->hdr.type == 255)
|
||||
return L9660_EBADFS;
|
||||
}
|
||||
|
||||
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;
|
||||
#ifndef L9660_SINGLEBUFFER
|
||||
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;
|
||||
}
|
||||
|
||||
static l9660_status buffer(l9660_file *f)
|
||||
{
|
||||
static l9660_status buffer(l9660_file *f) {
|
||||
#ifdef L9660_SINGLEBUFFER
|
||||
last_file = f;
|
||||
#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))
|
||||
return L9660_EIO;
|
||||
else
|
||||
return L9660_OK;
|
||||
}
|
||||
|
||||
static l9660_status prebuffer(l9660_file *f)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
do {
|
||||
const char *seg = name;
|
||||
name = strchrnul(name, '/');
|
||||
size_t seglen = name - seg;
|
||||
|
@ -165,14 +145,12 @@ static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char
|
|||
seg = "\0";
|
||||
|
||||
/* ISO9660 stores ".." as '\1' */
|
||||
if (seglen == 2 && seg[0] == '.' && seg[1] == '.')
|
||||
{
|
||||
if (seglen == 2 && seg[0] == '.' && seg[1] == '.') {
|
||||
seg = "\1";
|
||||
seglen = 1;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
if ((rv = l9660_readdir(parent, &dent)))
|
||||
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->length = READ32(dent->size);
|
||||
child->position = 0;
|
||||
|
||||
parent->file.position = 0;
|
||||
if (*name && (dent->flags & DENT_ISDIR) != 0)
|
||||
return L9660_ENOTDIR;
|
||||
|
||||
parent = (l9660_dir *)child;
|
||||
} while (*name);
|
||||
|
||||
if (isdir)
|
||||
{
|
||||
if (isdir) {
|
||||
if ((dent->flags & DENT_ISDIR) == 0)
|
||||
return L9660_ENOTDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if ((dent->flags & DENT_ISDIR) != 0)
|
||||
return L9660_ENOTFILE;
|
||||
}
|
||||
|
@ -225,33 +200,28 @@ static l9660_status openat_raw(l9660_file *child, l9660_dir *parent, const char
|
|||
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);
|
||||
}
|
||||
|
||||
static inline unsigned aligneven(unsigned v)
|
||||
{
|
||||
return v + (v & 1);
|
||||
}
|
||||
static inline unsigned aligneven(unsigned v) { 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_file *f = &dir->file;
|
||||
|
||||
rebuffer:
|
||||
if (f->position >= f->length)
|
||||
{
|
||||
rebuffer:
|
||||
if (f->position >= f->length) {
|
||||
*pdirent = NULL;
|
||||
f->position = 0;
|
||||
return L9660_OK;
|
||||
}
|
||||
|
||||
if ((rv = prebuffer(f)))
|
||||
return rv;
|
||||
char *off = BUF(f) + fsectoff(f);
|
||||
if (*off == 0)
|
||||
{
|
||||
if (*off == 0) {
|
||||
// Padded end of sector
|
||||
f->position = fnextsectpos(f);
|
||||
goto rebuffer;
|
||||
|
@ -264,19 +234,17 @@ rebuffer:
|
|||
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);
|
||||
}
|
||||
|
||||
/*! 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;
|
||||
uint32_t cursect = fsector(f);
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
f->position = offset;
|
||||
break;
|
||||
|
@ -290,8 +258,7 @@ l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset)
|
|||
break;
|
||||
}
|
||||
|
||||
if (fsector(f) != cursect && fsectoff(f) != 0)
|
||||
{
|
||||
if (fsector(f) != cursect && fsectoff(f) != 0) {
|
||||
if ((rv = buffer(f)))
|
||||
return rv;
|
||||
}
|
||||
|
@ -299,13 +266,9 @@ l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset)
|
|||
return L9660_OK;
|
||||
}
|
||||
|
||||
uint32_t l9660_tell(l9660_file *f)
|
||||
{
|
||||
return f->position;
|
||||
}
|
||||
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 l9660_read(l9660_file *f, void *buf, size_t size, size_t *read) {
|
||||
l9660_status rv;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool read_sector(l9660_fs *fs, void *buf, uint32_t sector)
|
||||
{
|
||||
return CDROM_Read(sector,1,buf,fs->disk_number);
|
||||
char *strdup(const char *s) {
|
||||
size_t l = strlen(s);
|
||||
char *d = kmalloc(l + 1);
|
||||
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 字节
|
||||
bool ok = CDROM_Read(16, 1, buffer, disk_number);
|
||||
|
||||
if (buffer[0] == 0x01 && buffer[1] == 'C' && buffer[2] == 'D' && buffer[3] == '0' &&
|
||||
buffer[4] == '0' && buffer[5] == '1')
|
||||
{
|
||||
if (buffer[0] == 0x01 && buffer[1] == 'C' && buffer[2] == 'D' &&
|
||||
buffer[3] == '0' && buffer[4] == '0' && buffer[5] == '1') {
|
||||
kfree(buffer);
|
||||
return true; // 是 ISO9660 文件系统
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
kfree(buffer);
|
||||
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;
|
||||
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));
|
||||
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);
|
||||
fs_m->now_dir = fs_m->root_dir;
|
||||
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");
|
||||
*/
|
||||
logkf("%08x\n", vfs->cache);
|
||||
}
|
||||
|
||||
void ISO_CDFile(){}
|
||||
void ISO_CDFile() {}
|
||||
|
||||
vfs_file *ISO_GetFile(char* path1){
|
||||
// strtoupper(path1);
|
||||
// if (strcmp(path1, "/") == 0) {
|
||||
// return fs_m->root_dir;
|
||||
// }
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ISO_CopyCache(struct vfs_t *dest, struct vfs_t *src){
|
||||
void ISO_CopyCache(struct vfs_t *dest, struct vfs_t *src) {
|
||||
dest->cache = kmalloc(sizeof(l9660_fs_status_t));
|
||||
memcpy(dest->cache, src->cache, sizeof(l9660_fs_status_t));
|
||||
}
|
||||
|
||||
int ISO_cd(struct vfs_t *vfs, char *dictname){
|
||||
//
|
||||
// strtoupper(dictname);
|
||||
//
|
||||
int ISO_cd(struct vfs_t *vfs, char *dictname) {
|
||||
//
|
||||
// strtoupper(dictname);
|
||||
//
|
||||
if (strcmp(dictname, "/") == 0) {
|
||||
while (vfs->path->ctl->all != 0) {
|
||||
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;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int free_flag = 0;
|
||||
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 (free_flag) {
|
||||
kfree(dictname);
|
||||
} else {
|
||||
dictname = strdup(dictname);
|
||||
strtoupper(dictname);
|
||||
free_flag = 1;
|
||||
goto RE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
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));
|
||||
DeleteVal(vfs->path->ctl->all, vfs->path);
|
||||
}
|
||||
if (free_flag) {
|
||||
kfree(dictname);
|
||||
}
|
||||
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_status a = l9660_openat(&file, &get_now_dir(vfs),path);
|
||||
if(a) {
|
||||
l9660_status 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
|
||||
}
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
size_t read;
|
||||
l9660_read(&file, buffer, 128, &read);
|
||||
if (read == 0)
|
||||
break;
|
||||
buffer += read;
|
||||
}
|
||||
if (free_flag) {
|
||||
kfree(path);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
List *ISO_ListFile(struct vfs_t *vfs, char *dictpath){
|
||||
List *ISO_ListFile(struct vfs_t *vfs, char *dictpath) {
|
||||
l9660_dir finfo;
|
||||
if(strcmp(dictpath,"") == 0)
|
||||
int free_flag = 0;
|
||||
if (strcmp(dictpath, "") == 0)
|
||||
finfo = get_now_dir(vfs);
|
||||
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 (free_flag) {
|
||||
kfree(dictpath);
|
||||
} else {
|
||||
dictpath = strdup(dictpath);
|
||||
strtoupper(dictpath);
|
||||
free_flag = 1;
|
||||
goto RE;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List *result = NewList();
|
||||
for (;;) {
|
||||
l9660_dirent *dent;
|
||||
|
@ -474,19 +437,26 @@ List *ISO_ListFile(struct vfs_t *vfs, char *dictpath){
|
|||
if (dent == 0)
|
||||
break;
|
||||
vfs_file *d = kmalloc(sizeof(vfs_file));
|
||||
memclean((void *)d,sizeof(vfs_file));
|
||||
memclean((void *)d, sizeof(vfs_file));
|
||||
int j = 0;
|
||||
if(memcmp("\0",dent->name,dent->name_len) == 0) {
|
||||
d->name[j++] = '.';
|
||||
d->name[j] = 0;
|
||||
} else if (memcmp("\1",dent->name,dent->name_len) == 0) {
|
||||
d->name[j++] = '.';
|
||||
d->name[j++] = '.';
|
||||
d->name[j] = 0;
|
||||
if (memcmp("\0", dent->name, dent->name_len) == 0) {
|
||||
if (finfo.file.first_sector == get_root_dir(vfs).file.first_sector) {
|
||||
kfree(d);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
for(;j<dent->name_len;j++) {
|
||||
if(dent->name[j] == ';') {
|
||||
d->name[j++] = '.';
|
||||
d->name[j] = 0;
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
@ -494,27 +464,42 @@ List *ISO_ListFile(struct vfs_t *vfs, char *dictpath){
|
|||
}
|
||||
d->name[j] = 0;
|
||||
d->type = FLE;
|
||||
if(dent->flags & DENT_ISDIR) {
|
||||
if (dent->flags & DENT_ISDIR) {
|
||||
d->type = DIR;
|
||||
} else {
|
||||
d->size = READ32(dent->size);
|
||||
}
|
||||
AddVal(d, result);
|
||||
}
|
||||
if (free_flag) {
|
||||
kfree(dictpath);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int ISO_FileSize(struct vfs_t *vfs, char *filename) {
|
||||
l9660_file file;
|
||||
l9660_status a = l9660_openat(&file, &get_now_dir(vfs),filename);
|
||||
if(a) {
|
||||
l9660_status 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
|
||||
}
|
||||
if (free_flag) {
|
||||
kfree(filename);
|
||||
}
|
||||
return file.length;
|
||||
}
|
||||
|
||||
|
||||
void init_iso9660()
|
||||
{
|
||||
void init_iso9660() {
|
||||
vfs_t fs;
|
||||
fs.flag = 1;
|
||||
fs.cache = NULL;
|
||||
|
|
|
@ -122,6 +122,7 @@ typedef struct tss_table {
|
|||
} tss_entry;
|
||||
|
||||
void write_tss(int32_t num, uint16_t ss0, uint32_t esp0);
|
||||
void set_kernel_stack(uintptr_t stack);
|
||||
|
||||
void gdt_install();
|
||||
void idt_install();
|
||||
|
|
|
@ -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 page_flush(page_directory_t *dir);
|
||||
|
||||
#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) {
|
||||
current_directory = dir;
|
||||
asm volatile("mov %0, %%cr3" : : "r"(&dir->tablesPhysical));
|
||||
|
@ -200,7 +206,7 @@ void init_page(multiboot_t *mboot) {
|
|||
current_directory = kernel_directory;
|
||||
int i = 0;
|
||||
|
||||
while (i < placement_address) {
|
||||
while (i < placement_address + 0x30000) {
|
||||
// 内核部分对ring3而言可读不可写 | 无偏移页表映射
|
||||
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
|
||||
i += 0x1000;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "../include/common.h"
|
||||
#include "../include/graphics.h"
|
||||
#include "../include/io.h"
|
||||
#include "../include/description_table.h"
|
||||
|
||||
struct task_struct *running_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;
|
||||
current = next;
|
||||
|
||||
switch_page_directory(current->pgd_dir);
|
||||
page_flush(current->pgd_dir);
|
||||
set_kernel_stack(current->stack);
|
||||
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->stack = current;
|
||||
new_task->pid = now_pid++;
|
||||
new_task->pgd_dir = kernel_directory;
|
||||
new_task->pgd_dir = clone_directory(kernel_directory) ;
|
||||
|
||||
new_task->name = name;
|
||||
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
#include "../include/cmos.h"
|
||||
#include "../include/vdisk.h"
|
||||
#include "../include/vfs.h"
|
||||
#include "../include/common.h"
|
||||
#include "../include/sb16.h"
|
||||
#include "../include/elf.h"
|
||||
|
||||
extern Queue *key_char_queue;
|
||||
extern vdisk vdisk_ctl[10];
|
||||
|
@ -239,6 +241,8 @@ void cmd_type(int argc,char ** argv){
|
|||
printf("%s",buffer);
|
||||
else printf("Cannot read file.\n");
|
||||
|
||||
|
||||
|
||||
kfree(buffer);
|
||||
print("\n");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue