Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
41 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
22
/*      Address Spaces test file                        */
23
 
24
#include <ll/i386/stdlib.h>
25
#include <ll/i386/error.h>
26
#include <ll/i386/mem.h>
27
#include <ll/i386/hw-arch.h>
28
#include <ll/i386/farptr.h>
29
#include <ll/sys/ll/ll-func.h>
30
#include <ll/sys/ll/aspace.h>
31
#include <ll/sys/ll/event.h>
32
#include <ll/string.h>
33
 
34
#define USE_NEW_HANDLERS
35
#define T  1000
36
#define WAIT()  for (w = 0; w < 0x5FFFFF; w++)                                 
37
 
38
extern DWORD GDT_base;
39
extern void int0x31(void);
40
 
41
#ifndef USE_NEW_HANDLERS
42
struct regs {
43
  DWORD flags;
44
  DWORD egs;
45
  DWORD efs;
46
  DWORD ees;
47
  DWORD eds;
48
  DWORD edi;
49
  DWORD esi;
50
  DWORD ebp;
51
  DWORD esp;
52
  DWORD ebx;
53
  DWORD edx;
54
  DWORD ecx;
55
  DWORD eax;
56
};
57
#endif
58
 
59
BYTE space[2048];
60
WORD th1, th2, thm;
61
 
62
char outstring[] = "Hi there!!!\n";
63
 
64
#ifdef USE_NEW_HANDLERS
65
void chandler(DWORD intnum, struct registers r)
66
#else
67
void chandler(struct regs r, DWORD intnum)
68
#endif
69
{
70
  message("[System Call] EAX = 0x%lx EBX = 0x%lx ECX = 0x%lx...\n",
71
                  r.eax, r.ebx, r.ecx);
72
 
73
  if (r.eax == 1) {
74
    message("Exit!!!\n");
75
    ll_context_load(thm);
76
  }
77
 
78
  if (r.eax == 2) {
79
    char string[20];
80
    DWORD p;
81
    unsigned int size;
82
 
83
    p = GDT_read(r.eds, NULL, NULL, NULL);
84
    p += r.ebx;
85
    size = r.ecx;
86
    if (size > 20) {
87
      size = 20;
88
    }
89
#if 0
90
    message("Buffer @0x%lx, len %u\n", p, size);
91
    l1_end();
92
    sti();
93
    l1_exit(0);
94
#endif
95
 
96
    memcpy(string, (void *)p, size);
97
    string[19] = 0;
98
    message("Write...\n");
99
    message("%s", string);
100
    return;
101
  }
102
 
103
  message("Unsupported System Call!!!\n");
104
}
105
 
106
 
107
/* For now, this is not called */
108
void killer(void)
109
{
110
  cli();
111
  message("Killer!!!\n");
112
  ll_context_load(thm);
113
}
114
 
115
/*
116
  And this is the thread that runs in the new AS... It cannot call
117
  any function (it is alone in its AS), so it simply plots a star
118
  on the screen and loops waiting for an event that switches to the
119
  main thread.
120
*/
121
void nullfun(void *p)
122
{
123
  /* Some asm to write on the screen (we cannot use libc... it is not
124
     linked in this AS */
125
  __asm__ __volatile__ ("movl $2, %eax");
126
  __asm__ __volatile__ ("movl $1000, %ebx");
127
  __asm__ __volatile__ ("movl $16, %ecx");
128
  __asm__ __volatile__ ("int $0x31");
129
  __asm__ __volatile__ ("movl $1, %eax");
130
  __asm__ __volatile__ ("int $0x31");
131
 
132
  /* should not arrive here... */
133
  for(;;);
134
  halt();
135
}
136
 
137
int main (int argc, char *argv[])
138
{
139
  DWORD sp1, sp2;
140
  void *res;
141
  AS as, ds;
142
  int ok;
143
 
144
  sp1 = get_SP();
145
  cli();
146
  res = ll_init();
147
 
148
  if (res == NULL) {
149
    message("Error in LowLevel initialization code...\n");
150
    sti();
151
    l1_exit(-1);
152
  }
153
  message("LowLevel started...\n");
154
 
155
#ifdef USE_NEW_HANDLERS
156
  l1_int_bind(0x31, chandler);
157
#else
158
  IDT_place(0x31, int0x31);
159
#endif
160
  as_init();
161
 
162
  message("Creating an Address Space\n");
163
  as = as_create();
164
  message("Created: ID = %d %x\n", as, as);
165
  message("Binding array @ 0x%lx\n", (DWORD)space);
166
  ok = as_bind(as, (DWORD)space, 0, sizeof(space));
167
 
168
  if (ok < 0) {
169
    message("Error in as_bind!!!\n");
170
  } else {
171
    message("Bound\n");
172
  }
173
 
174
  ds = get_DS();
175
  /* Let's create the image of the process...
176
   * 0 --> 1000 : text
177
   * 1000 --> 1000 + strlen(outstring) : initialized data
178
   * ? <-- 2048 : stack
179
   */
180
  fmemcpy(as, 0, ds, (DWORD)nullfun, 1000);
181
  fmemcpy(as, 1000, ds, (DWORD)outstring, strlen(outstring));
182
  /* Create a thread (in our AS) and a task (in a different AS) */
183
  th1 = ll_context_create(0, (void *)2048, NULL,killer, 0);
184
  ll_context_setspace(th1, as);
185
 
186
  /* Save our context, in order to permit to switch back to main */
187
  thm = ll_context_save();
188
  message("I am thread %x\n", thm);
189
  message("Thread 1 created\n");
190
  message("Switching to it...\n");
191
  ll_context_load(th1);
192
  message("Back to Main\n");
193
 
194
  cli();
195
  ll_end();
196
  sp2 = get_SP();
197
  message("End reached!\n");
198
  message("Actual stack : %lx - ", sp2);
199
  message("Begin stack : %lx\n", sp1);
200
  message("Check if same : %s\n",sp1 == sp2 ? "Ok :-)" : "No :-(");
201
 
202
  return 1;
203
}