#define PARTITION_NAME_SIZE 48
#define DEV_ID_SIZE 32
+struct block_dev;
+
+struct block_dev_ops
+{
+ int (*block_read)(struct block_dev*, void*, u64_t, size_t);
+ int (*block_write)(struct block_dev*, void*, u64_t, size_t);
+ void* (*block_alloc)(struct block_dev*);
+ void (*block_free)(struct block_dev*, void*);
+};
+
struct block_dev
{
struct llist_header parts;
u64_t start_lba;
u64_t end_lba;
u32_t blk_size;
+ struct block_dev_ops ops;
};
// Lunaix Partition Table
#ifndef __LUNAIX_CLOCK_H
#define __LUNAIX_CLOCK_H
-#include <stdint.h>
+#include <lunaix/types.h>
typedef uint32_t time_t;
(dt->minute - 1) * 60u + dt->second;
}
+static inline time_t
+time_tounix(u32_t yyyy, u32_t mm, u32_t dd, u32_t hh, u32_t MM, u32_t ss)
+{
+ return (yyyy - 1970) * 31556926u + (mm - 1) * 2629743u + (dd - 1) * 86400u +
+ (hh - 1) * 3600u + (MM - 1) * 60u + ss;
+}
+
#endif /* __LUNAIX_CLOCK_H */
struct filesystem* fs;
uint32_t iobuf_size;
struct hbucket* i_cache;
+ void* data;
struct
{
uint32_t (*read_capacity)(struct v_superblock* vsb);
#ifndef __LUNAIX_ISO9660_H
#define __LUNAIX_ISO9660_H
+#include <lunaix/clock.h>
+#include <lunaix/device.h>
#include <lunaix/types.h>
+#define ISO_SIGNATURE_LO 0x30304443UL
+#define ISO_SIGNATURE_HI 0x31
+
// Volume Types
#define ISO_VOLBOOT 0 // Boot Record
#define ISO_VOLPRIM 1 // Primary
#define ISO_FPROTECT 0x10 // file being protected by access control
#define ISO_FEXTENTS 0x80 // the extent by this record is a file partial
+#define ISO9660_BLKSZ 2048
+#define ISO9660_IDLEN 256
+
// NOTES:
// Each Descriptor sized 1 logical block (2048 bytes in common cases)
// ISO9660 store number in both-byte order. That is, for a d-bits number, it
u8_t gmt;
} PACKED;
+// 32bits both-byte-order integer
+typedef struct iso_bbo32
+{
+ u32_t le; // little-endian
+ u32_t be; // big-endian
+} PACKED iso_bbo32_t;
+
+// 16bits both-byte-order integer
+typedef struct iso_bbo16
+{
+ u16_t le; // little-endian
+ u16_t be; // big-endian
+} PACKED iso_bbo16_t;
+
// (8.4) Describe a primary volume space
struct iso_vol_primary
{
u8_t reserved_1;
u8_t sys_id[32];
u8_t vol_id[32];
- u8_t reserved_2;
- u32_t sz_lo; // (8.4.8) only lower portion is valid.
- u32_t sz_hi;
- u8_t reserved_2;
- u32_t set_size;
- u32_t seq_num;
- u32_t lb_size;
- u32_t path_tbl_sz_lo; // lower partition - LE.
- u32_t path_tbl_sz_hi;
+ u8_t reserved_2[8];
+ iso_bbo32_t vol_size;
+ u8_t reserved_3[32];
+ iso_bbo16_t set_size;
+ iso_bbo16_t seq_num;
+ iso_bbo16_t lb_size;
+ iso_bbo32_t ptable_size;
u32_t lpath_tbl_ptr; // Type L Path table location (LBA)
- u32_t reserved_3[3]; // use type M if big endian machine.
+ u32_t reserved_4[3]; // use type M if big endian machine.
u8_t root_record[34];
u8_t set_id[128];
u8_t publisher_id[128];
u8_t reserved;
u8_t sys_id[32];
u8_t part_id[32];
- u32_t part_addr_lo; // (8.6.7) only lower portion is valid.
- u32_t part_addr_hi;
- u32_t part_sz_lo; // (8.6.8) only lower portion is valid.
- u32_t part_sz_hi;
+ iso_bbo32_t part_addr;
+ iso_bbo32_t part_size;
} PACKED;
// (6.10.4) MDU with variable record
struct iso_drecord
{
u8_t xattr_len;
- u32_t extent_lo; // location of extent, lower 32 bits is valid.
- u32_t extent_hi;
- u32_t data_sz_lo; // size of extent, lower 32 bits is valid.
- u32_t data_sz_hi;
+ iso_bbo32_t extent_addr;
+ iso_bbo32_t data_size;
struct
{
u8_t year;
u8_t month;
+ u8_t day;
u8_t hour;
u8_t min;
u8_t sec;
u8_t flags;
u8_t fu_sz; // size of file unit (FU)
u8_t gap_sz; // size of gap if FU is interleaved.
- u32_t vol_seq;
+ iso_bbo16_t vol_seq;
struct iso_var_mdu name;
} PACKED;
-// (9.4) Path Table Record. [Embedded into Variable MDU]
+// (9.4) L-Path Table Record. [Embedded into Variable MDU]
struct iso_precord
{
u8_t xattr_len;
struct iso_xattr
{
- u32_t owner;
- u32_t group;
+ iso_bbo16_t owner;
+ iso_bbo16_t group;
u16_t perm;
struct iso_datetime ctime;
struct iso_datetime mtime;
struct iso_datetime ef_time;
u8_t record_fmt;
u8_t record_attr;
- u8_t record_len;
+ iso_bbo16_t record_len;
u32_t sys_id;
u8_t reserved1[64];
u8_t version;
u8_t len_esc;
u8_t reserved2[64];
- u32_t payload_sz;
+ iso_bbo16_t payload_sz;
u8_t payload[0];
// There is also a escape sequence after payload,
// It however marked as optional, hence we ignore it.
} PACKED;
+struct iso_ptable
+{
+ u32_t start_lba;
+ u32_t current_lba;
+ u32_t size;
+ u32_t range_lower;
+ u32_t range_upper;
+ void* ptable_part;
+};
+
+struct iso_inode
+{
+ time_t ctime;
+ time_t mtime;
+ u32_t record_fmt;
+ u32_t fu_size;
+ u32_t gap_size;
+ struct llist_header* drecaches;
+};
+
+struct iso_drecache
+{
+ struct llist_header caches;
+ u32_t extent_addr;
+ u32_t data_size;
+ u32_t xattr_len;
+ u32_t fu_size;
+ u32_t gap_size;
+ u32_t flags;
+ struct hstr name;
+ char name_val[ISO9660_IDLEN];
+};
+
+struct iso_superblock
+{
+ u32_t volume_size;
+ u32_t lb_size;
+};
+
+struct iso_drecord*
+iso9660_get_drecord(struct iso_var_mdu* drecord_mdu);
+
+int
+iso9660_fill_inode(struct v_inode* inode, struct iso_drecache* dir, int ino);
+
+time_t
+iso9660_dt2unix(struct iso_datetime* isodt);
+
+void
+iso9660_init();
+
+int
+iso9660_setup_dnode(struct v_dnode* dnode, struct v_inode* inode);
+
+void
+iso9660_fill_drecache(struct iso_drecache* cache, struct iso_drecord* drec);
+
+int
+iso9660_dir_lookup(struct v_inode* this, struct v_dnode* dnode);
+
+int
+iso9660_readdir(struct v_file* file, struct dir_context* dctx);
+
+int
+iso9660_open(struct v_inode* this, struct v_file* file);
+
+int
+iso9660_close(struct v_file* file);
+
+int
+iso9660_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
+
+int
+iso9660_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
+
+int
+iso9660_seek(struct v_inode* inode, size_t offset);
+
#endif /* __LUNAIX_ISO9660_H */
-#ifndef __LUNAIX_SYS_H
-#define __LUNAIX_SYS_H
+#ifndef __LUNAIX_LUNAIX_H
+#define __LUNAIX_LUNAIX_H
#include <lunaix/syscall.h>
#include <lunaix/types.h>
__LXSYSCALL(int, geterrno);
-#endif /* __LUNAIX_SYS_H */
+__LXSYSCALL2_VARG(void, syslog, int, level, const char*, fmt);
+
+#endif /* __LUNAIX_LUNAIX_H */
void
lxconsole_init();
+void
+lxconsole_spawn_ttydev();
+
void
console_write_str(char* str);
#define ENOMEM LXOUTOFMEM
#define ENOTDEV -24
#define EOVERFLOW -25
+#define ENOTBLK -26
#endif /* __LUNAIX_CODE_H */
#define __SYSCALL_getpgid 49
#define __SYSCALL_setpgid 50
+#define __SYSCALL_syslog 51
+
#define __SYSCALL_MAX 0x100
#ifndef __ASM__
___DOINT33(__SYSCALL_##name, rettype) \
}
#endif
+
#endif /* __LUNAIX_SYSCALL_H */
.long __lxsys_ioctl
.long __lxsys_getpgid
.long __lxsys_setpgid /* 50 */
+ .long __lxsys_syslog
2:
.rept __SYSCALL_MAX - (2b - 1b)/4
.long 0
__block_write(struct device* dev, void* buf, size_t offset, size_t len)
{
struct block_dev* bdev = (struct block_dev*)dev->underlay;
- size_t bsize = bdev->blk_size, rd_block = offset / bsize + bdev->start_lba,
+ size_t bsize = bdev->blk_size, wr_block = offset / bsize + bdev->start_lba,
r = offset % bsize, wr_size = 0;
- if (!(len = MIN(len, ((size_t)bdev->end_lba - rd_block + 1) * bsize))) {
+ if (!(len = MIN(len, ((size_t)bdev->end_lba - wr_block + 1) * bsize))) {
return 0;
}
vbuf_alloc(&vbuf, buf + wr_size, llen);
}
- req = blkio_vwr(vbuf, rd_block, NULL, NULL, 0);
+ // FIXME race condition between blkio_commit and pwait.
+ // Consider: what if scheduler complete the request before process enter
+ // wait state?
+ req = blkio_vwr(vbuf, wr_block, NULL, NULL, 0);
blkio_commit(bdev->blkio, req);
pwait(&req->wait);
return errno;
}
+int
+__block_rd_lb(struct block_dev* bdev, void* buf, u64_t start, size_t count)
+{
+ struct vecbuf* vbuf = NULL;
+ vbuf_alloc(&vbuf, buf, bdev->blk_size * count);
+
+ struct blkio_req* req = blkio_vrd(vbuf, start, NULL, NULL, 0);
+ blkio_commit(bdev->blkio, req);
+ pwait(&req->wait);
+
+ int errno = req->errcode;
+ if (!errno) {
+ errno = count;
+ } else {
+ errno = -errno;
+ }
+
+ blkio_free_req(req);
+ vbuf_free(vbuf);
+
+ return errno;
+}
+
+int
+__block_wr_lb(struct block_dev* bdev, void* buf, u64_t start, size_t count)
+{
+ struct vecbuf* vbuf = NULL;
+ vbuf_alloc(&vbuf, buf, bdev->blk_size * count);
+
+ struct blkio_req* req = blkio_vwr(vbuf, start, NULL, NULL, 0);
+ blkio_commit(bdev->blkio, req);
+ pwait(&req->wait);
+
+ int errno = req->errcode;
+ if (!errno) {
+ errno = count;
+ } else {
+ errno = -errno;
+ }
+
+ blkio_free_req(req);
+ vbuf_free(vbuf);
+
+ return errno;
+}
+
+void*
+block_alloc_buf(struct block_dev* bdev)
+{
+ return valloc(bdev->blk_size);
+}
+
+void
+block_free_buf(struct block_dev* bdev, void* buf)
+{
+ return vfree(buf);
+}
+
struct block_dev*
block_alloc_dev(const char* blk_id, void* driver, req_handler ioreq_handler)
{
bdev->blkio = blkio_newctx(ioreq_handler);
bdev->driver = driver;
bdev->blkio->driver = driver;
+ bdev->ops = (struct block_dev_ops){ .block_read = __block_rd_lb,
+ .block_write = __block_wr_lb };
return bdev;
}
#include <lunaix/dirent.h>
#include <lunaix/fctrl.h>
+#include <lunaix/lunaix.h>
#include <lunaix/lunistd.h>
-#include <lunaix/proc.h>
void
_readdir_main()
#include <lunaix/fctrl.h>
#include <lunaix/foptions.h>
#include <lunaix/input.h>
+#include <lunaix/lunaix.h>
#include <lunaix/lunistd.h>
-#include <lunaix/proc.h>
#include <ulibc/stdio.h>
#define STDIN 1
#include <lunaix/fctrl.h>
#include <lunaix/foptions.h>
+#include <lunaix/lunaix.h>
#include <lunaix/lunistd.h>
-#include <lunaix/proc.h>
#include <ulibc/stdio.h>
void
+#include <lunaix/lunaix.h>
#include <lunaix/lunistd.h>
-#include <lunaix/proc.h>
#include <lunaix/signal.h>
#include <lunaix/spike.h>
#include <lunaix/types.h>
#include <lunaix/fctrl.h>
#include <lunaix/foptions.h>
#include <lunaix/ioctl.h>
+#include <lunaix/lunaix.h>
#include <lunaix/lunistd.h>
-#include <lunaix/proc.h>
#include <lunaix/signal.h>
#include <lunaix/status.h>
#include <lunaix/fs.h>
#include <lunaix/fs/devfs.h>
+#include <lunaix/fs/iso9660.h>
#include <lunaix/fs/ramfs.h>
#include <lunaix/fs/taskfs.h>
#include <lunaix/fs/twifs.h>
twifs_init();
devfs_init();
taskfs_init();
+ iso9660_init();
// ... more fs implementation
}
\ No newline at end of file
fsm_new_fs(char* name, size_t name_len)
{
struct filesystem* fs = vzalloc(sizeof(*fs));
+ if (name_len == (size_t)-1) {
+ name_len = strlen(name);
+ }
fs->fs_name = HHSTR(name, name_len, 0);
return fs;
}
\ No newline at end of file
--- /dev/null
+#include <lunaix/dirent.h>
+#include <lunaix/fs.h>
+#include <lunaix/fs/iso9660.h>
+#include <lunaix/mm/cake.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+
+#include <klibc/string.h>
+
+extern struct cake_pile* drec_cache_pile;
+
+void
+iso9660_fill_drecache(struct iso_drecache* cache, struct iso_drecord* drec)
+{
+ *cache = (struct iso_drecache){ .data_size = drec->data_size.le,
+ .extent_addr = drec->extent_addr.le,
+ .flags = drec->flags,
+ .fu_size = drec->fu_sz ? drec->fu_sz : 1,
+ .gap_size = drec->gap_sz,
+ .xattr_len = drec->xattr_len };
+ u32_t l = drec->name.len;
+ while (l < (u32_t)-1 && drec->name.content[l--] != ';')
+ ;
+ l = (l + 1) ? l : drec->name.len;
+ l = MIN(l, ISO9660_IDLEN);
+ strncpy(cache->name_val, drec->name.content, l);
+ cache->name = HSTR(cache->name_val, l);
+ hstr_rehash(&cache->name, HSTR_FULL_HASH);
+}
+
+int
+iso9660_setup_dnode(struct v_dnode* dnode, struct v_inode* inode)
+{
+ if (!(inode->itype & VFS_IFDIR)) {
+ return;
+ }
+
+ int errno = 0;
+ struct device* dev = dnode->super_block->dev;
+ struct iso_inode* isoino = inode->data;
+ struct llist_header* lead = valloc(sizeof(*lead));
+ void* records = valloc(ISO9660_BLKSZ);
+ u32_t current_pos = -ISO9660_BLKSZ, max_pos = inode->fsize,
+ blk = inode->lb_addr * ISO9660_BLKSZ, blk_offset = (u32_t)-1;
+
+ llist_init_head(lead);
+
+ // As per 6.8.1, Directory structure shall NOT recorded in interleave mode.
+ do {
+ if (blk_offset >= ISO9660_BLKSZ - sizeof(struct iso_drecord)) {
+ current_pos += ISO9660_BLKSZ;
+ errno = dev->read(dev, records, blk + current_pos, ISO9660_BLKSZ);
+ if (errno < 0) {
+ errno = EIO;
+ goto done;
+ }
+ blk_offset = 0;
+ }
+
+ struct iso_drecord* drec;
+ struct iso_var_mdu* mdu = (struct iso_var_mdu*)(records + blk_offset);
+
+ if (!(drec = iso9660_get_drecord(mdu))) {
+ break;
+ }
+
+ // ignore the '.', '..' as we have built-in support
+ if (drec->name.len == 1) {
+ goto cont;
+ }
+
+ struct iso_drecache* cache = cake_grab(drec_cache_pile);
+
+ iso9660_fill_drecache(cache, drec);
+ llist_append(lead, &cache->caches);
+ cont:
+ blk_offset += mdu->len;
+ } while (current_pos + blk_offset < max_pos);
+
+ dnode->data = lead;
+ isoino->drecaches = lead;
+
+ vfs_assign_inode(dnode, inode);
+
+ errno = 0;
+
+done:
+ vfree(records);
+ return errno;
+}
+
+int
+iso9660_dir_lookup(struct v_inode* this, struct v_dnode* dnode)
+{
+ struct iso_inode* isoino = this->data;
+ struct llist_header* lead = isoino->drecaches;
+ struct iso_drecache *pos, *n;
+
+ llist_for_each(pos, n, lead, caches)
+ {
+ if (HSTR_EQ(&dnode->name, &pos->name)) {
+ goto found;
+ }
+ }
+
+ return ENOENT;
+found:
+ struct v_inode* inode = vfs_i_find(dnode->super_block, pos->extent_addr);
+
+ if (!inode) {
+ inode = vfs_i_alloc(dnode->super_block);
+ iso9660_fill_inode(inode, pos, pos->extent_addr);
+ vfs_i_addhash(inode);
+ }
+
+ iso9660_setup_dnode(dnode, inode);
+
+ return 0;
+}
+
+static int
+__get_dtype(struct iso_drecache* pos)
+{
+ if ((pos->flags & ISO_FDIR)) {
+ return DT_DIR;
+ } else {
+ return DT_FILE;
+ }
+}
+
+int
+iso9660_readdir(struct v_file* file, struct dir_context* dctx)
+{
+ struct llist_header* lead = file->dnode->data;
+ struct iso_drecache *pos, *n;
+ u32_t counter = dctx->index - 1;
+
+ llist_for_each(pos, n, lead, caches)
+ {
+ if (counter == (u32_t)-1 && !(pos->flags & ISO_FHIDDEN)) {
+ dctx->read_complete_callback(
+ dctx, pos->name_val, pos->name.len, __get_dtype(pos));
+ return 1;
+ }
+ counter--;
+ }
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+#include <lunaix/fs.h>
+#include <lunaix/fs/iso9660.h>
+
+int
+iso9660_open(struct v_inode* this, struct v_file* file)
+{
+ // TODO
+ return 0;
+}
+
+int
+iso9660_close(struct v_file* file)
+{
+ // TODO
+ return 0;
+}
+
+int
+iso9660_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
+{
+ // TODO
+ return 0;
+}
+
+int
+iso9660_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos)
+{
+ // TODO
+ return EROFS;
+}
+
+int
+iso9660_seek(struct v_inode* inode, size_t offset)
+{
+ // TODO
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+#include <klibc/string.h>
+#include <lunaix/fs.h>
+#include <lunaix/fs/iso9660.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+
+static struct v_inode_ops iso_inode_ops = {
+ .dir_lookup = iso9660_dir_lookup,
+ .open = iso9660_open,
+};
+
+static struct v_file_ops iso_file_ops = { .close = iso9660_close,
+ .read = iso9660_read,
+ .write = iso9660_write,
+ .seek = iso9660_seek,
+ .readdir = iso9660_readdir };
+
+void
+iso9660_init_inode(struct v_superblock* vsb, struct v_inode* inode)
+{
+ inode->data = vzalloc(sizeof(struct iso_inode));
+}
+
+int
+iso9660_fill_inode(struct v_inode* inode, struct iso_drecache* dir, int ino)
+{
+ int errno = 0;
+ struct device* dev = inode->sb->dev;
+ struct iso_inode* isoino = (struct iso_inode*)inode->data;
+
+ // In the spec, there is a differentiation in how file section organized
+ // between interleaving and non-interleaving mode. To simplify this, we
+ // treat the non-interleaving as an interleaving with gap size = 0 and fu
+ // size = 1
+ isoino->fu_size = dir->fu_size;
+ isoino->gap_size = dir->gap_size;
+
+ u32_t fu_len = isoino->fu_size * ISO9660_BLKSZ;
+
+ inode->id = ino;
+ inode->lb_addr = dir->extent_addr;
+ inode->ops = &iso_inode_ops;
+ inode->default_fops = &iso_file_ops;
+
+ // xattr_len is in unit of FU. Each FU comprise <fu_sz> block(s).
+ inode->fsize = dir->data_size - dir->xattr_len * fu_len;
+
+ if ((dir->flags & ISO_FDIR)) {
+ inode->itype = VFS_IFDIR;
+ } else {
+ inode->itype = VFS_IFFILE;
+ }
+
+ if (dir->xattr_len) {
+ struct iso_xattr* xattr = (struct iso_xattr*)valloc(ISO9660_BLKSZ);
+ // Only bring in single FU, as we only care about the attributes.
+ errno =
+ dev->read(dev, xattr, ISO9660_BLKSZ * inode->lb_addr, ISO9660_BLKSZ);
+ if (errno < 0) {
+ return EIO;
+ }
+ isoino->record_fmt = xattr->record_fmt;
+ isoino->ctime = iso9660_dt2unix(&xattr->ctime);
+ isoino->mtime = iso9660_dt2unix(&xattr->mtime);
+
+ inode->lb_addr += dir->xattr_len * dir->fu_size;
+
+ vfree(xattr);
+ }
+
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+#include <lunaix/block.h>
+#include <lunaix/fs.h>
+#include <lunaix/fs/iso9660.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+
+#include <lunaix/mm/cake.h>
+
+struct cake_pile* drec_cache_pile;
+
+extern void
+iso9660_init_inode(struct v_superblock* vsb, struct v_inode* inode);
+
+uint32_t
+iso9660_rd_capacity(struct v_superblock* vsb)
+{
+ struct iso_superblock* isovsb = (struct iso_superblock*)vsb->data;
+ return isovsb->volume_size;
+}
+
+int
+iso9660_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
+{
+ struct device* dev = vsb->dev;
+ struct iso_vol* vdesc = (struct iso_vol*)valloc(ISO9660_BLKSZ);
+ struct iso_vol_primary* vprim = NULL;
+ int errno = 0;
+ do {
+ errno = dev->read(dev, vdesc, ISO9660_BLKSZ * 16, ISO9660_BLKSZ);
+ if (errno < 0) {
+ errno = EIO;
+ goto done;
+ }
+ if (*(u32_t*)vdesc->std_id != ISO_SIGNATURE_LO) {
+ errno = ENODEV;
+ goto done;
+ }
+ if (vdesc->type == ISO_VOLPRIM) {
+ vprim = (struct iso_vol_primary*)vdesc;
+ break;
+ }
+
+ } while (vdesc->type != ISO_VOLTERM);
+
+ if (!vprim) {
+ errno = EINVAL;
+ goto done;
+ }
+
+ struct iso_superblock* isovsb = valloc(sizeof(*isovsb));
+ isovsb->lb_size = vprim->lb_size.le;
+ isovsb->volume_size = vprim->vol_size.le * isovsb->lb_size;
+
+ vsb->data = isovsb;
+ vsb->ops.init_inode = iso9660_init_inode;
+ vsb->ops.read_capacity = iso9660_rd_capacity;
+
+ struct v_inode* rootino = vfs_i_alloc(vsb);
+ struct iso_drecord* dir =
+ iso9660_get_drecord((struct iso_var_mdu*)vprim->root_record);
+
+ if (!dir) {
+ vfree(isovsb);
+ errno = EINVAL;
+ goto done;
+ }
+
+ struct iso_drecache drecache;
+ iso9660_fill_drecache(&drecache, dir);
+
+ if ((errno = iso9660_fill_inode(rootino, &drecache, 0)) < 0) {
+ vfree(isovsb);
+ errno = EINVAL;
+ goto done;
+ }
+
+ if ((errno = iso9660_setup_dnode(mount_point, rootino)) < 0) {
+ vfree(isovsb);
+ errno = EINVAL;
+ goto done;
+ }
+
+ vfs_i_addhash(rootino);
+
+done:
+ vfree(vdesc);
+ return 0;
+}
+
+int
+iso9660_unmount(struct v_superblock* vsb)
+{
+ // TODO clean up
+}
+
+void
+iso9660_init()
+{
+ drec_cache_pile =
+ cake_new_pile("iso_drec", sizeof(struct iso_drecache), 1, 0);
+
+ struct filesystem* fs = fsm_new_fs("iso9660", -1);
+ fs->types |= FSTYPE_ROFS;
+ fs->mount = iso9660_mount;
+ fs->unmount = iso9660_unmount;
+
+ fsm_register(fs);
+}
\ No newline at end of file
--- /dev/null
+#include <lunaix/fs/iso9660.h>
+
+struct iso_drecord*
+iso9660_get_drecord(struct iso_var_mdu* drecord_mdu)
+{
+ if (drecord_mdu->len <= sizeof(struct iso_drecord)) {
+ return NULL;
+ }
+ return (struct iso_drecord*)drecord_mdu->content;
+}
+
+#define FOUR_DIGIT(x) (x[0] + x[1] * 10 + x[2] * 100 + x[3] * 1000)
+#define TWO_DIGIT(x) (x[0] + x[1] * 10)
+
+time_t
+iso9660_dt2unix(struct iso_datetime* isodt)
+{
+ return time_tounix(FOUR_DIGIT(isodt->year),
+ TWO_DIGIT(isodt->month),
+ TWO_DIGIT(isodt->day),
+ TWO_DIGIT(isodt->hour),
+ TWO_DIGIT(isodt->min),
+ TWO_DIGIT(isodt->sec));
+}
#include <lunaix/mm/valloc.h>
#include <lunaix/process.h>
#include <lunaix/spike.h>
+#include <lunaix/syslog.h>
#include <lunaix/types.h>
+LOG_MODULE("fs")
+
struct llist_header all_mnts = { .next = &all_mnts, .prev = &all_mnts };
struct v_mount*
struct v_dnode* mnt_point,
int options)
{
+ if (device && device->dev_type != DEV_IFVOL) {
+ return ENOTBLK;
+ }
+
if (mnt_point->inode && !(mnt_point->inode->itype & VFS_IFDIR)) {
return ENOTDIR;
}
return ENODEV;
}
+ if (fs->types == FSTYPE_ROFS) {
+ options |= MNT_RO;
+ }
+
+ char* dev_name = "sys";
struct v_mount* parent_mnt = mnt_point->mnt;
struct v_superblock *sb = vfs_sb_alloc(), *old_sb = mnt_point->super_block;
sb->dev = device;
mnt_point->super_block = sb;
+ if (device) {
+ dev_name = device->name_val;
+ }
+
int errno = 0;
if (!(errno = fs->mount(sb, mnt_point))) {
sb->fs = fs;
goto cleanup;
}
+ kprintf("mount: dev=%s, fs=%s, mode=%d\n", dev_name, fs_name, options);
+
mnt_point->mnt->flags = options;
} else {
goto cleanup;
return errno;
cleanup:
+ kprintf(KERROR "mount: dev=%s, fs=%s, mode=%d, err=%d\n",
+ dev_name,
+ fs_name,
+ options,
+ errno);
mnt_point->super_block = old_sb;
vfs_sb_free(sb);
return errno;
void
ramfs_init()
{
- struct filesystem* ramfs = fsm_new_fs("ramfs", 5);
+ struct filesystem* ramfs = fsm_new_fs("ramfs", -1);
ramfs->mount = ramfs_mount;
ramfs->unmount = ramfs_unmount;
int
__twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
{
- vsb->dev = 1;
vsb->ops.init_inode = __twifs_init_inode;
struct v_inode* inode = vfs_i_alloc(vsb);
vfs_export_attributes();
+ lxconsole_init();
+
if ((errno = vfs_mount_root("ramfs", NULL))) {
panickf("Fail to mount root. (errno=%d)", errno);
}
vfs_mount("/sys", "twifs", NULL, MNT_RO);
vfs_mount("/task", "taskfs", NULL, MNT_RO);
- lxconsole_init();
+ lxconsole_spawn_ttydev();
syscall_install();
#include <klibc/stdio.h>
#include <lunaix/lxconsole.h>
+#include <lunaix/spike.h>
+#include <lunaix/syscall.h>
#include <lunaix/syslog.h>
#include <lunaix/tty/tty.h>
#define MAX_XFMT_SIZE 512
void
-__kprintf(const char* component, const char* fmt, va_list args)
+__kprintf_internal(const char* component,
+ int log_level,
+ const char* fmt,
+ va_list args)
{
char buf[MAX_KPRINTF_BUF_SIZE];
- if (!fmt)
- return;
- char log_level = '0';
char expanded_fmt[MAX_XFMT_SIZE];
- if (*fmt == '\x1b') {
- log_level = *(++fmt);
- fmt++;
- }
-
switch (log_level) {
- case '1':
+ case 1:
// tty_set_theme(VGA_COLOR_BROWN, current_theme >> 12);
ksnprintf(expanded_fmt,
MAX_XFMT_SIZE,
component,
fmt);
break;
- case '2':
+ case 2:
// tty_set_theme(VGA_COLOR_LIGHT_RED, current_theme >> 12);
ksnprintf(expanded_fmt,
MAX_XFMT_SIZE,
component,
fmt);
break;
- case '3':
+ case 3:
// tty_set_theme(VGA_COLOR_LIGHT_BLUE, current_theme >> 12);
ksnprintf(expanded_fmt,
MAX_XFMT_SIZE,
console_write_str(buf);
}
+void
+__kprintf(const char* component, const char* fmt, va_list args)
+{
+ if (!fmt)
+ return;
+ char log_level = '0';
+
+ if (*fmt == '\x1b') {
+ log_level = *(++fmt);
+ fmt++;
+ }
+
+ __kprintf_internal(component, log_level - '0', fmt, args);
+}
+
void
kprint_panic(const char* fmt, ...)
{
console_write_str(ch_cache);
console_write_char('\n');
}
+}
+
+__DEFINE_LXSYSCALL3(void, syslog, int, level, const char*, fmt, va_list, args)
+{
+ __kprintf_internal("syslog", level, fmt, args);
}
\ No newline at end of file
#include <hal/cpu.h>
#include <lunaix/clock.h>
+#include <lunaix/lunaix.h>
#include <lunaix/lunistd.h>
#include <lunaix/lxconsole.h>
#include <lunaix/mm/kalloc.h>
#include <lunaix/mm/vmm.h>
-#include <lunaix/proc.h>
#include <lunaix/spike.h>
#include <lunaix/syslog.h>
#include <lunaix/timer.h>
#include <lunaix/block.h>
#include <lunaix/common.h>
#include <lunaix/fctrl.h>
+#include <lunaix/foptions.h>
#include <lunaix/fs.h>
#include <lunaix/fs/twifs.h>
+#include <lunaix/lunaix.h>
#include <lunaix/lunistd.h>
#include <lunaix/lxconsole.h>
#include <lunaix/mm/cake.h>
#include <lunaix/mm/vmm.h>
#include <lunaix/peripheral/ps2kbd.h>
#include <lunaix/peripheral/serial.h>
-#include <lunaix/proc.h>
#include <lunaix/spike.h>
#include <lunaix/syscall.h>
#include <lunaix/syslog.h>
#include <lunaix/types.h>
+
#include <sdbg/protocol.h>
#include <hal/acpi/acpi.h>
extern void
sh_main();
+void __USER__
+__setup_dir()
+{
+ int errno;
+ mkdir("/mnt");
+ mkdir("/mnt/lunaix-os");
+
+ if ((errno = mount("/dev/sdb", "/mnt/lunaix-os", "iso9660", 0))) {
+ syslog(2, "fail mounting boot medium. (%d)\n", errno);
+ }
+}
+
void __USER__
__proc0_usr()
{
int fdstdout = open("/dev/tty", 0);
int fdstdin = dup2(stdout, 1);
+ __setup_dir();
+
pid_t p;
if (!(p = fork())) {
void
init_platform()
{
- kprintf(KINFO "\033[11;0mLunaixOS \033[39;49m\n");
+ kprintf(KINFO "\033[11;0mLunaixOS (gcc v%s, %s)\033[39;49m\n",
+ __VERSION__,
+ __TIME__);
// 锁定所有系统预留页(内存映射IO,ACPI之类的),并且进行1:1映射
lock_reserved_memory();
fifo_init(&lx_console.input, valloc(4096), 4096, 0);
lx_console.flush_timer = NULL;
+}
+void
+lxconsole_spawn_ttydev()
+{
struct device* tty_dev = device_addseq(NULL, &lx_console, "tty");
tty_dev->write = __tty_write;
tty_dev->read = __tty_read;