exec: extract type dependancies for pointers
authorAlan Cox <alan@linux.intel.com>
Tue, 21 Jul 2015 20:28:58 +0000 (21:28 +0100)
committerAlan Cox <alan@linux.intel.com>
Tue, 21 Jul 2015 20:28:58 +0000 (21:28 +0100)
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
Kernel/syscall_exec16.c

index 689c9fe..8e37bae 100644 (file)
@@ -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
index a378479..d665f36 100644 (file)
@@ -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;
 }
 
 /*