From 1f90561416433a6f85d37a908a70c185f355e5ca Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 21 Jul 2015 21:28:58 +0100 Subject: [PATCH] exec: extract type dependancies for pointers With the bits in cpu/*.h we can now express the pointer types separately so that we can build a platform with 32bit kernel and 16bit user pointers or the reverse (eg 286 'large' binaries with a small model kernel). --- Kernel/start.c | 23 ++++++++++++++--------- Kernel/syscall_exec16.c | 23 ++++++++++++++--------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/Kernel/start.c b/Kernel/start.c index 689c9fe7..8e37bae9 100644 --- a/Kernel/start.c +++ b/Kernel/start.c @@ -55,14 +55,18 @@ void fstabinit(void) } } -/* FIXME: pass remainder of boot argument to init, also word align */ +/* FIXME: pass remainder of boot argument to init */ +/* Remember two things when modifying this code + 1. Some processors need 2 byte alignment or better of arguments. We + lay it out for 4 + 2. We are going to end up with cases where user and kernel pointer + size differ due to memory models etc. We use uputp and we allow + room for the pointers to be bigger than kernel */ + void create_init(void) { uint8_t *j; - /* userspace: PROGLOAD + - 0 1 2 3 4 5 6 7 8 9 A B C */ - static const char arg[] = - { '/', 'i', 'n', 'i', 't', 0, 0, 1, 1, 0, 0, 0, 0 }; + static const char arg[] = { '/', 'i', 'n', 'i', 't' }; init_process = ptab_alloc(); udata.u_ptab = init_process; @@ -80,14 +84,15 @@ void create_init(void) *j = NO_FILE; } /* Poke the execve arguments into user data space so _execve() can read them back */ + uzero((void *)PROGLOAD, 32); uput(arg, (void *)PROGLOAD, sizeof(arg)); - /* Poke in argv[0] - FIXME: Endianisms... */ - uputw(PROGLOAD+1 , (void *)(PROGLOAD + 7)); + /* Poke in argv[0] */ + uputp(PROGLOAD+1 , (void *)(PROGLOAD + 8)); /* Set up things to look like the process is calling _execve() */ udata.u_argn = (arg_t)PROGLOAD; - udata.u_argn1 = (arg_t)(PROGLOAD + 0x7); /* Arguments (just "/init") */ - udata.u_argn2 = (arg_t)(PROGLOAD + 0xb); /* Environment (none) */ + udata.u_argn1 = (arg_t)(PROGLOAD + 0x8); /* Arguments (just "/init") */ + udata.u_argn2 = (arg_t)(PROGLOAD + 0x10); /* Environment (none) */ } #ifndef BOOTDEVICE diff --git a/Kernel/syscall_exec16.c b/Kernel/syscall_exec16.c index a3784794..d665f365 100644 --- a/Kernel/syscall_exec16.c +++ b/Kernel/syscall_exec16.c @@ -23,8 +23,10 @@ static int bload(inoptr i, uint16_t bl, uint16_t base, uint16_t len) bufdiscard((bufptr)buf); brelse((bufptr)buf); #else - /* Might be worth spotting sequential blocks and - merging ? */ + /* FIXME: allow for async queued I/O here. We want + an API something like breadasync() that either + does the cdread() or queues for a smart platform + or box with floppy tape devices */ udata.u_offset = (off_t)blk << 9; udata.u_count = 512; udata.u_base = (uint8_t *)base; @@ -254,13 +256,15 @@ nogood3: bool rargs(char **userspace_argv, struct s_argblk * argbuf) { char *ptr; /* Address of base of arg strings in user space */ + char *up = (char *)userspace_argv; uint8_t c; uint8_t *bufp; argbuf->a_argc = 0; /* Store argc in argbuf */ bufp = argbuf->a_buf; - while ((ptr = (char *) ugetw(userspace_argv++)) != NULL) { + while ((ptr = (char *) ugetp(up)) != NULL) { + up += sizeof(uptr_t); ++(argbuf->a_argc); /* Store argc in argbuf. */ do { *bufp++ = c = ugetc(ptr++); @@ -278,9 +282,9 @@ bool rargs(char **userspace_argv, struct s_argblk * argbuf) char **wargs(char *ptr, struct s_argblk *argbuf, int *cnt) // ptr is in userspace { - char **argv; /* Address of users argv[], just below ptr */ + char *argv; /* Address of users argv[], just below ptr */ int argc, arglen; - char **argbase; + char *argbase; uint8_t *sptr; sptr = argbuf->a_buf; @@ -294,7 +298,7 @@ char **wargs(char *ptr, struct s_argblk *argbuf, int *cnt) // ptr is in userspac /* Set argv to point below the argument strings */ argc = argbuf->a_argc; - argbase = argv = (char **) ptr - (argc + 1); + argbase = argv = ptr - sizeof(uptr_t) * (argc + 1); if (cnt) { *cnt = argc; @@ -302,15 +306,16 @@ char **wargs(char *ptr, struct s_argblk *argbuf, int *cnt) // ptr is in userspac /* Set each element of argv[] to point to its argument string */ while (argc--) { - uputw((uint16_t) ptr, argv++); + uputp((uptr_t) ptr, argv); + argv += sizeof(uptr_t); if (argc) { do ++ptr; while (*sptr++); } } - uputw(0, argv); /*;;26Feb- Add Null Pointer to end of array */ - return ((char **) argbase); + uputp(0, argv); /*;;26Feb- Add Null Pointer to end of array */ + return (char **)argbase; } /* -- 2.34.1