summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2014-01-22 22:26:36 -0800
committerH. Peter Anvin <hpa@linux.intel.com>2014-01-22 22:26:36 -0800
commit385ca231a89d7efbdd04cd54720afa1dbe800c9b (patch)
tree4ec81f4f31c5b919aace15a612f935e4bf91e747
parentc5439c3cf188a8af949885f80205bd8054705737 (diff)
downloadtest16-385ca231a89d7efbdd04cd54720afa1dbe800c9b.tar.gz
test16-385ca231a89d7efbdd04cd54720afa1dbe800c9b.tar.xz
test16-385ca231a89d7efbdd04cd54720afa1dbe800c9b.zip
Introduce SYS structure; add <string.h>
Introduce SYS structure instead of magic pointers. Put it at 0xf000 so the stack ends up in its own page (allows us to set up page protections.) Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--include16/string.h6
-rw-r--r--include16/sys16.h25
-rw-r--r--lib16/conio.c5
-rw-r--r--lib16/strlen.c2
-rw-r--r--run16.c19
5 files changed, 47 insertions, 10 deletions
diff --git a/include16/string.h b/include16/string.h
new file mode 100644
index 0000000..ec50591
--- /dev/null
+++ b/include16/string.h
@@ -0,0 +1,6 @@
+#ifndef _STRING_H
+#define _STRING_H
+
+int strlen(const char *);
+
+#endif /* _STRING_H */
diff --git a/include16/sys16.h b/include16/sys16.h
new file mode 100644
index 0000000..6f5f6c6
--- /dev/null
+++ b/include16/sys16.h
@@ -0,0 +1,25 @@
+#ifndef SYS16_H
+#define SYS16_H
+
+#ifdef __SYS16__
+# define _PTR16(x) x
+#else
+# define _PTR16(x) unsigned int
+#endif
+
+struct system_struct {
+ unsigned int seg_base;
+ int argc;
+ _PTR16(char **)argv;
+};
+
+#undef _PTR16
+
+#define SYS_STRUCT_ADDR 0xf000
+
+#ifdef __SYS16__
+# define SYS ((struct system_struct *)SYS_STRUCT_ADDR)
+# define _KPTR(x) ((unsigned int)(x) + SYS->seg_base)
+#endif
+
+#endif /* SYS16_H */
diff --git a/lib16/conio.c b/lib16/conio.c
index 96b03ca..a02441a 100644
--- a/lib16/conio.c
+++ b/lib16/conio.c
@@ -1,4 +1,5 @@
-#define SEG_BASE (*(const unsigned int *)0xfffc)
+#include <string.h>
+#include <sys16.h>
void puts(const char *s)
{
@@ -9,6 +10,6 @@ void puts(const char *s)
: "=a" (rv)
: "a" (4), /* __NR_write */
"b" (1),
- "c" ((unsigned int)s + SEG_BASE),
+ "c" (_KPTR(s)),
"d" (strlen(s)));
}
diff --git a/lib16/strlen.c b/lib16/strlen.c
index cb7cdb4..7d6dd15 100644
--- a/lib16/strlen.c
+++ b/lib16/strlen.c
@@ -1,3 +1,5 @@
+#include <string.h>
+
int strlen(const char *c)
{
const char *c0 = c;
diff --git a/run16.c b/run16.c
index 7a81de8..3fe4c72 100644
--- a/run16.c
+++ b/run16.c
@@ -15,6 +15,8 @@
#include <asm/unistd.h>
#include <sys/mman.h>
+#include "include16/sys16.h"
+
static unsigned char toybox[65536] __attribute__((aligned(4096)));
#define LOAD_ADDR 0x1000
@@ -71,8 +73,7 @@ static void jump16(uint32_t offset)
target.offset = offset;
target.segment = 7;
- asm volatile("ljmpl *%0" : : "m" (target),
- "a" (LOAD_ADDR), "d" (offset));
+ asm volatile("ljmpl *%0" : : "m" (target), "a" (LOAD_ADDR));
}
static void run(const char *file)
@@ -81,6 +82,7 @@ static void run(const char *file)
const void *trampoline;
unsigned char *entrypoint;
uint32_t offset;
+ struct system_struct *SYS;
setup_ldt();
@@ -91,14 +93,14 @@ static void run(const char *file)
"1:\n"
" movw $15,%%cx\n"
" movw %%cx,%%ss\n"
- " movl %%edx,%%esp\n"
+ " movl %2,%%esp\n"
" movw %%cx,%%ds\n"
" movw %%cx,%%es\n"
" movw %%cx,%%fs\n"
" movw %%cx,%%gs\n"
" calll *%%eax\n"
" movzbl %%al,%%ebx\n"
- " movl %2,%%eax\n"
+ " movl %3,%%eax\n"
" int $0x80\n"
"2:\n"
" .code32\n"
@@ -106,14 +108,15 @@ static void run(const char *file)
" movl $1b,%0\n"
" movl $(2b - 1b),%1\n"
: "=r" (trampoline), "=r" (trampoline_len)
- : "i" (__NR_exit));
+ : "i" (SYS_STRUCT_ADDR), "i" (__NR_exit));
- offset = (sizeof toybox - trampoline_len - 4) & ~15;
+ offset = (sizeof toybox - trampoline_len) & ~15;
entrypoint = toybox + offset;
memcpy(entrypoint, trampoline, trampoline_len);
- /* Save the segment base address in the highest dword */
- *(uint32_t *)(toybox + sizeof toybox - 4) = (uint32_t)toybox;
+ /* Set up the system structure */
+ SYS = (struct system_struct *)(toybox + SYS_STRUCT_ADDR);
+ SYS->seg_base = (unsigned int)toybox;
load_file(file, offset);