From ccbe784335203a210021ccac549035f58d447296 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Tue, 12 Nov 2019 21:08:26 +1100 Subject: TEST --- Makefrag.am | 2 + configure.ac | 1 + device/ramdisk.c | 160 ++++++++++++++++++++++++++++++++++++++++ device/ramdisk.h | 47 ++++++++++++ i386/i386at/conf.c | 3 + i386/i386at/kd.c | 4 + i386/include/mach/i386/fp_reg.h | 2 + kern/boot_script.c | 8 ++ kern/bootstrap.c | 18 +++++ version.c.in | 2 +- vm/vm_map.c | 3 +- 11 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 device/ramdisk.c create mode 100644 device/ramdisk.h diff --git a/Makefrag.am b/Makefrag.am index fee77894..f01707fe 100644 --- a/Makefrag.am +++ b/Makefrag.am @@ -319,6 +319,8 @@ libkernel_a_SOURCES += \ device/net_io.c \ device/net_io.h \ device/param.h \ + device/ramdisk.c \ + device/ramdisk.h \ device/subrs.c \ device/subrs.h \ device/tty.h diff --git a/configure.ac b/configure.ac index d4daa932..815f5818 100644 --- a/configure.ac +++ b/configure.ac @@ -19,6 +19,7 @@ AC_PREREQ([2.57]) m4_include([version.m4]) AC_INIT([AC_PACKAGE_NAME], [AC_PACKAGE_VERSION], [AC_PACKAGE_BUGREPORT], [AC_PACKAGE_TARNAME]) +AC_SUBST([PACKAGE_VERSION_SUFFIX]) AC_CONFIG_SRCDIR([kern/ipc_kobject.c]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/device/ramdisk.c b/device/ramdisk.c new file mode 100644 index 00000000..daf70436 --- /dev/null +++ b/device/ramdisk.c @@ -0,0 +1,160 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct ramdisk { + void *data; + vm_size_t size; +} ramdisk[RAMDISK_MAX]; + +static int ramdisk_num = 0; + +/* Initial ramdisks are created from the boot scripts */ +int ramdisk_create(vm_size_t size, const void *initdata, int *out_no) +{ + struct ramdisk *rd = &ramdisk[ramdisk_num]; + int err; + + if(ramdisk_num >= RAMDISK_MAX) + return -1; + + /* allocate the memory */ + rd->size = round_page(size); + err = kmem_alloc(kernel_map, (vm_offset_t *) &rd->data, rd->size); + if(err != KERN_SUCCESS) + return err; + + /* initialize */ + if(initdata) + memcpy(rd->data, initdata, rd->size); + else + memset(rd->data, 0, rd->size); + + /* report */ + if(out_no) *out_no = ramdisk_num; + printf("%s%d: %lu bytes @%p\n", RAMDISK_NAME, ramdisk_num, + (unsigned long) rd->size, rd->data); + + ramdisk_num++; + return KERN_SUCCESS; +} + +/* On d_open() we just check whether the ramdisk exists */ +int ramdisk_open(dev_t dev, int mode, io_req_t ior) +{ + return (dev < ramdisk_num) ? D_SUCCESS : D_NO_SUCH_DEVICE; +} + +/* d_getstat() is used to query the device characteristics */ +int ramdisk_getstat(dev_t dev, dev_flavor_t flavor, dev_status_t status, + mach_msg_type_number_t *status_count) +{ + switch(flavor) { + case DEV_GET_SIZE: + status[DEV_GET_SIZE_DEVICE_SIZE] = ramdisk[dev].size; + status[DEV_GET_SIZE_RECORD_SIZE] = RAMDISK_BLOCKSZ; + *status_count = DEV_GET_SIZE_COUNT; + return D_SUCCESS; + + case DEV_GET_RECORDS: + status[DEV_GET_RECORDS_DEVICE_RECORDS] + = ramdisk[dev].size / RAMDISK_BLOCKSZ; + status[DEV_GET_RECORDS_RECORD_SIZE] = RAMDISK_BLOCKSZ; + *status_count = DEV_GET_RECORDS_COUNT; + return D_SUCCESS; + } + return D_INVALID_OPERATION; +} + +/* TODO: implement freeramdisk with setstat() ? */ + +/* Check the given io request and compute a pointer to the ramdisk data and the + * amount to be handled. */ +static int ramdisk_ioreq(int dev, io_req_t ior, void **data, int *amt) +{ + vm_offset_t ofs = ior->io_recnum * RAMDISK_BLOCKSZ; + if(ofs >= ramdisk[dev].size) + return D_INVALID_RECNUM; + + *data = (char*) ramdisk[dev].data + ofs; + *amt = ior->io_count; + if(ofs + *amt > ramdisk[dev].size) + *amt = ramdisk[dev].size - ofs; + + return KERN_SUCCESS; +} + +/* Copy data from a vm_map_copy by mapping it temporarily. */ +static int mem_map_cpy(void *dst, vm_map_copy_t src, int amt) +{ + vm_offset_t srcaddr; + int err; + + err = vm_map_copyout(device_io_map, &srcaddr, src); + if (err != KERN_SUCCESS) + return err; + + memcpy(dst, (void *) srcaddr, amt); + vm_deallocate(device_io_map, srcaddr, amt); + return KERN_SUCCESS; +} + +int ramdisk_read(dev_t dev, io_req_t ior) +{ + void *data; + int amt, err; + + err = ramdisk_ioreq(dev, ior, &data, &amt); + if(err != KERN_SUCCESS) + return err; + + err = device_read_alloc (ior, ior->io_count); + if (err != KERN_SUCCESS) + return err; + + memcpy(ior->io_data, data, amt); + ior->io_residual = ior->io_count - amt; + + return D_SUCCESS; +} + +int ramdisk_write(dev_t dev, io_req_t ior) +{ + void *data; + int amt, err; + + err = ramdisk_ioreq(dev, ior, &data, &amt); + if(err != KERN_SUCCESS) + return err; + + if (!(ior->io_op & IO_INBAND)) { + /* Out-of-band data is transmitted as a vm_map_copy */ + err = mem_map_cpy(data, (vm_map_copy_t) ior->io_data, amt); + if(err != KERN_SUCCESS) + return err; + } else { + /* In-band data can be accessed directly */ + memcpy(data, ior->io_data, amt); + } + + ior->io_residual = ior->io_count - amt; + return D_SUCCESS; +} + +vm_offset_t ramdisk_mmap(dev_t dev, vm_offset_t off, vm_prot_t prot) +{ + if(dev >= ramdisk_num) + return -1; + if(off >= ramdisk[dev].size) + return -1; + + return pmap_phys_to_frame(kvtophys((vm_offset_t) ramdisk[dev].data + off)); +} + diff --git a/device/ramdisk.h b/device/ramdisk.h new file mode 100644 index 00000000..3a232460 --- /dev/null +++ b/device/ramdisk.h @@ -0,0 +1,47 @@ +#ifndef _KERN_RAMDISK_H_ +#define _KERN_RAMDISK_H_ + +#include +#include +#include + +/* Maximum number of ramdisk devices */ +#define RAMDISK_MAX 4 + +/* The block size used (userspace requires 512) */ +#define RAMDISK_BLOCKSZ 512 + +/* Name associated to the ramdisk major */ +#define RAMDISK_NAME "rd" +#define RAMDISK_NAMESZ (sizeof RAMDISK_NAME + sizeof (int) * 3 + 1) + +/* Create a new ramdisk of the given size. On success, if out_no and/or out_ptr + * are not NULL, the device number and pointer to the ramdisk's data are stored + * there. Returns D_SUCCESS or D_NO_MEMORY. */ +int ramdisk_create(vm_size_t size, const void *initdata, int *out_no); + +/* Device operations */ +int ramdisk_open(dev_t, int, io_req_t); +int ramdisk_getstat(dev_t, dev_flavor_t, dev_status_t, mach_msg_type_number_t *); +int ramdisk_read(dev_t, io_req_t); +int ramdisk_write(dev_t, io_req_t); +vm_offset_t ramdisk_mmap(dev_t, vm_offset_t, vm_prot_t); + +/* dev_ops initializer to be used from /conf.c */ +#define RAMDISK_DEV_OPS { \ + .d_name = RAMDISK_NAME, \ + .d_open = ramdisk_open, \ + .d_close = nulldev_close, \ + .d_read = ramdisk_read, \ + .d_write = ramdisk_write, \ + .d_getstat = ramdisk_getstat, \ + .d_setstat = nulldev_setstat, \ + .d_mmap = ramdisk_mmap, \ + .d_async_in = nodev, \ + .d_reset = nulldev, \ + .d_port_death = nulldev_portdeath, \ + .d_subdev = 0, \ + .d_dev_info = nodev, \ + } + +#endif diff --git a/i386/i386at/conf.c b/i386/i386at/conf.c index fe7c7c09..7b82ff47 100644 --- a/i386/i386at/conf.c +++ b/i386/i386at/conf.c @@ -31,6 +31,7 @@ #include #include #include +#include #define timename "time" @@ -135,6 +136,8 @@ struct dev_ops dev_name_list[] = nodev }, #endif /* MACH_HYP */ + RAMDISK_DEV_OPS, + #ifdef MACH_KMSG { kmsgname, kmsgopen, kmsgclose, kmsgread, nulldev_write, kmsggetstat, nulldev_setstat, nomap, diff --git a/i386/i386at/kd.c b/i386/i386at/kd.c index 8e9222a0..c448adab 100644 --- a/i386/i386at/kd.c +++ b/i386/i386at/kd.c @@ -1733,6 +1733,10 @@ kd_parserest(u_char *cp) kd_erase(number[0]); esc_spt = esc_seq; break; + case 'n': + /* Ignore status/cursor report request */ + esc_spt = esc_seq; + break; case '\0': break; /* not enough yet */ default: diff --git a/i386/include/mach/i386/fp_reg.h b/i386/include/mach/i386/fp_reg.h index 56730555..f4906238 100644 --- a/i386/include/mach/i386/fp_reg.h +++ b/i386/include/mach/i386/fp_reg.h @@ -117,6 +117,7 @@ struct i386_xfp_save { #define FPS_C3 0x4000 /* condition code bit 3 */ #define FPS_BUSY 0x8000 /* FPU busy */ +#ifdef MACH_KERNEL /* * Kind of floating-point support provided by kernel. */ @@ -125,5 +126,6 @@ struct i386_xfp_save { #define FP_287 2 /* 80287 */ #define FP_387 3 /* 80387 or 80486 */ #define FP_387X 4 /* FXSAVE/RSTOR-capable */ +#endif #endif /* _MACH_I386_FP_REG_H_ */ diff --git a/kern/boot_script.c b/kern/boot_script.c index b2ae901c..503a18de 100644 --- a/kern/boot_script.c +++ b/kern/boot_script.c @@ -88,12 +88,20 @@ prompt_resume_task (struct cmd *cmd, const long *val) return boot_script_prompt_task_resume (cmd); } +/* Create an initial ramdisk */ +static int +ramdisk_create (struct cmd *cmd, long *val) +{ + return boot_script_ramdisk_create (cmd, (char **) val); +} + /* List of builtin symbols. */ static struct sym builtin_symbols[] = { { "task-create", VAL_FUNC, (long) create_task, VAL_TASK, 0 }, { "task-resume", VAL_FUNC, (long) resume_task, VAL_NONE, 1 }, { "prompt-task-resume", VAL_FUNC, (long) prompt_resume_task, VAL_NONE, 1 }, + { "ramdisk-create", VAL_FUNC, (long) ramdisk_create, VAL_STR, 0 }, }; #define NUM_BUILTIN (sizeof (builtin_symbols) / sizeof (builtin_symbols[0])) diff --git a/kern/bootstrap.c b/kern/bootstrap.c index 8b88d17d..d0afa1ef 100644 --- a/kern/bootstrap.c +++ b/kern/bootstrap.c @@ -51,6 +51,7 @@ #include #include #include +#include #if MACH_KDB #include @@ -816,6 +817,23 @@ boot_script_free (void *ptr, unsigned int size) kfree ((vm_offset_t)ptr, size); } +int +boot_script_ramdisk_create (struct cmd *cmd, char **name) +{ + struct multiboot_module *mod = cmd->hook; + vm_size_t size = mod->mod_end - mod->mod_start; + kern_return_t rc; + int no; + + rc = ramdisk_create (size, (void *) phystokv (mod->mod_start), &no); + if (rc != KERN_SUCCESS) + return BOOT_SCRIPT_MACH_ERROR; + + *name = boot_script_malloc (RAMDISK_NAMESZ); + sprintf(*name, RAMDISK_NAME "%d", no); + return 0; +} + int boot_script_task_create (struct cmd *cmd) { diff --git a/version.c.in b/version.c.in index d894d7fc..2c57314f 100644 --- a/version.c.in +++ b/version.c.in @@ -1,2 +1,2 @@ /* @configure_input@ */ -const char version[] = "@PACKAGE_NAME@ @PACKAGE_VERSION@"; +const char version[] = "@PACKAGE_NAME@ @PACKAGE_VERSION@@PACKAGE_VERSION_SUFFIX@"; diff --git a/vm/vm_map.c b/vm/vm_map.c index ffc8934b..4a133eb3 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -1035,7 +1035,8 @@ kern_return_t vm_map_enter( * extend from below.] */ - if ((object == VM_OBJECT_NULL) && + if (0 && + (object == VM_OBJECT_NULL) && (entry != vm_map_to_entry(map)) && (entry->vme_end == start) && (!entry->is_shared) && -- cgit v1.2.3