summaryrefslogtreecommitdiff
path: root/README
blob: 562d70cd795f8abaf5572970c24e1946a520d7e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
The GNU Hurd
============

This is not the GNU Hurd.  But it might become it at some day.

The intention is to port the GNU Hurd to run on the L4 microkernel.

This is work in progress.


How to build
------------

Building the code is straight forward:

$ autoreconf -f -i -s
$ ./configure --enable-maintainer-mode --prefix=/l4
$ make
$ make install
$ mkdir /l4/boot
$ install -s laden/laden /l4/boot
$ install -s wortel/wortel /l4/boot
$ install -s physmem/physmem /l4/boot
$ install -s task/task /l4/boot
$ install -s deva/deva /l4/boot
$ install -s ruth/ruth /l4/boot

You need at least automake 1.7 and autoconf 2.53.  Note that the
binaries MUST be stripped, otherwise they will overlap in memory (or
you can adjust the load addresses).


Installation on ia32
--------------------

Prerequisites: Pistachio-0.4 (or CVS) with the patch below.  You can
find information about how to download the Pistachio source
distribution (which includes the kernel and sigma0) at the following
URL:

http://www.l4ka.org/projects/pistachio/download.php

sigma0 must be built with a different link base than the default value
0x20000, because that conflicts with GRUB (on ia32).  I have
successfully used a link base of 0x40000.  Use the configure option
--with-s0-linkbase=0x40000 when configuring the user space of the L4
distribution.

You only need the ia32-kernel and sigma0 binary from the L4
distribution.  You may want to install the other programs and
utilities as well to test your L4 kernel, though.

Then set up GRUB to boot laden as the kernel, and the L4 kernel,
sigma0, wortel (the rootserver), physmem and task as its modules (in
that order).  Also, add some dummy entries for the not-yet-existing
modules deva, deva-store and rootfs (just repeat the task server entry
another three times)

Try the debug option (-D) to laden and wortel to see some output from
them.  They are silent by default.

Here is an example menu.lst file for GNU GRUB:

title The GNU Hurd on L4
root (hd0,0)
kernel /boot/laden -D
module /boot/ia32-kernel
module /boot/sigma0
module /boot/wortel -D
module /boot/physmem
module /boot/task
module /boot/deva
module /boot/task
module /boot/ruth


Pistachio Patch
---------------

There are a couple of patches you need to apply to the L4 kernel to be
able to use it with the Hurd on L4 servers.  These patches add missing
features, or tweak the kernel interfaces to meet our requirements.

You can apply all patches in one go by changing your working directory
to the pistachio source tree, and feed this README file through patch:

$ cd pistachio
$ patch -p1 < /my/path/to/hurd-l4/README

The following patch fixes a problem with IPC propagation and with
receiving from any local thread.

2004-10-28  Marcus Brinkmann  <marcus@gnu.org>

	* src/api/v4/ipc.cc (SYS_IPC): If receiving from any local
	thread, look up the first sending local thread.

2004-10-23  Marcus Brinkmann  <marcus@gnu.org>

	* src/api/v4/ipc.cc (SYS_IPC): If propagating, modify the
	originator's partner to wait for the new receiver if the
	originator is in a closed wait for the sender. Check if the
	receiver is waiting for the current sender, not for the
	originator thread.

Index: kernel/src/api/v4/ipc.cc
===================================================================
RCS file: /public-cvs/pistachio/kernel/src/api/v4/ipc.cc,v
retrieving revision 1.57.4.6
diff -u -r1.57.4.6 ipc.cc
--- pistachio/kernel/src/api/v4/ipc.cc	3 Jun 2004 13:58:57 -0000	1.57.4.6
+++ pistachio/kernel/src/api/v4/ipc.cc	23 Oct 2004 00:33:45 -0000
@@ -292,6 +292,9 @@
 		 && (current->get_space() == virt_sender->get_space() ||
 		     current->get_space() == to_tcb->get_space()))
 	    {
+		if (virt_sender->get_state().is_waiting() &&
+		    virt_sender->get_partner() == sender_id)
+		  virt_sender->set_partner(to_tid);
 		sender_id = current->get_virtual_sender();
 	    }
 	    else
@@ -313,7 +316,7 @@
 	// optimized for receive and wait any
 	if (EXPECT_FALSE(
 	    (!to_tcb->get_state().is_waiting())  ||
-	    ( to_tcb->get_partner() != sender_id &&
+	    ( to_tcb->get_partner() != current->get_global_id() &&
 	      !to_tcb->get_partner().is_anythread() &&
 	      !( to_tcb->get_partner().is_anylocalthread() && 
 		 to_tcb->get_space() == current->get_space() ) ) ))
@@ -517,9 +520,24 @@ SYS_IPC (threadid_t to_tid, threadid_t f
 	    }
 	}
 	else
-	{	/* anylocal */
-#warning wait_local incorrect
-	    from_tcb = current->send_head;
+	{
+	    /* anylocal */
+
+	    tcb_t *head = current->send_head;
+	    from_tcb = NULL;
+
+	    if (head)
+	    {
+	        tcb_t *tcb = head;
+	  
+	        do
+		{
+		    if (tcb->get_space () == current->get_space ())
+		        from_tcb = tcb;
+		    tcb = tcb->send_list.next;
+		}
+	        while (!from_tcb && tcb != head);
+	    }
 	}
 
 	TRACE_IPC("receive phase curr=%t, from=%t\n", current, from_tcb);


The following patch adds support for the ELF TLS ABI to
L4Ka::Pistachio.

This is based on Espen's suggestion to use %gs:4 instead of %gs:0 for
the UTCB, to free %gs:0 for the ELF thread pointer.

I am not sure this patch helps anybody here.  It certainly won't do
the trick for the L4Linux guys.  But it opens a compromise path were
L4 still supports the ELF standard (although not the GNU variant) on
ia32.

I am posting this patch just so that you know what I am up to, and to
define more precisely one of the possible options in the stale-mate
ELF TLS ABI vs L4 ABI discussion.  I will also work on alternatives to
this, so this is not the last word.

I chose to not save/restore the value in %gs:0, but to add a system
call to set it.  This is the simplest approach I can think of, and
should also be the fastest for now, as setting the value is rare (if
you have one user thread per kernel thread).  I also put the value
into the kernel tcb, not in the UTCB, because I think this matches
existing precedence (ie, on ia64, gr13 is also not preserved across
IPC).

So, this is a really simple patch.  Doesn't do much, but works for me.

The costs (apart from setting up the desired value) is writing the
value from the ktcb to %gs:0 on every thread switch except fast path
of IPC.  That's all.

I suck at hand-written assembler.  So the ordering of the commands
possibly can be further optimized (move the pop %edx down a bit?).

===File l4-tls-ia32.patch===============
2004-11-19  Marcus Brinkmann  <marcus@gnu.org>

	* kernel/include/glue/v4-ia32/config.h (ARCH_SYSCALL0): New macro.
	(user_set_gs0) [!ASSEMBLY && __cplusplus]: Define prototype.
	* kernel/include/glue/v4-ia32/ktcb.h (arch_ktcb_t): Add new
	member user_gs0.
	* kernel/include/glue/v4-ia32/syscalls.h (sys_set_gs0): New
	prototype.
	* kernel/include/glue/v4-ia32/tcb.h (tcb_t::init_stack):
	Initialize ARCH.user_gs0.
	(tcb_t::switch_to): Use %gs:4 for the UTCB, and set %gs:0 to
	the user-settable value DEST->get_arch()->user_gs0.
	* kernel/src/glue/v4-ia32/gs0.cc: New file.
	* kernel/src/glue/v4-ia32/init.cc: Make the IA32_UTCB segment
	two words large.
	* kernel/src/glue/v4-ia32/Makeconf (SOURCES): Add gs0.cc.
	* kernel/src/glue/v4-ia32/trap.S: Use %gs:4 for the UTCB.
	* kernel/src/glue/v4-ia32/user.cc (SYSCALL_STUB(system_clock)):
	Use %gs:4 for the UTCB.
	(SYSCALL_STUB(set_gs0)): New syscall stub.
	(exc_user_syscall): Handle SYSCALL_STUB(set_gs0).
	* user/include/l4/ia32/vregs.h (__L4_X86_Utcb): Use %gs:4
	instead of %gs:0.

diff -rupN pistachio/kernel/include/glue/v4-ia32/config.h pistachio/kernel/include/glue/v4-ia32/config.h
--- pistachio/kernel/include/glue/v4-ia32/config.h	2005-01-22 01:45:47.000000000 +0100
+++ pistachio/kernel/include/glue/v4-ia32/config.h	2005-01-22 02:14:14.000000000 +0100
@@ -54,6 +54,11 @@
 #define KIP_ARCH_PAGEINFO	{SHUFFLE2(rwx:6, size_mask:((1 << IA32_PAGE_BITS)) >> 10)}
 #endif
 #define KIP_SYSCALL(x)		((u8_t*)(x) - (u8_t*)&kip)
+#define ARCH_SYSCALL0		KIP_SYSCALL (user_set_gs0)
+
+#if !defined(ASSEMBLY) && defined(__cplusplus)
+extern "C" void SECTION (".user.syscall.set_gs0") user_set_gs0 (void);
+#endif
 
 /* configuration for KTCBs
  * make sure the KTCBs fit entirely into the TCB area
@@ -103,7 +108,7 @@
 #define PAGEDIR_STUFF_END	(THREAD_COUNT + IA32_PAGEDIR_SIZE)
 #endif
 
-/* V4 UTCB addressed via %gs:0 */
+/* V4 UTCB addressed via %gs:4 */
 #define MYUTCB_MAPPING		__UL(0xDF000000)
 
 /* trampoline to set up segment registers after sysexit */
diff -rupN pistachio/kernel/include/glue/v4-ia32/ktcb.h pistachio/kernel/include/glue/v4-ia32/ktcb.h
--- pistachio/kernel/include/glue/v4-ia32/ktcb.h	2004-10-06 21:13:40.000000000 +0200
+++ pistachio/kernel/include/glue/v4-ia32/ktcb.h	2005-01-22 02:14:14.000000000 +0100
@@ -34,6 +34,8 @@
 
 typedef struct 
 {
+  /* The value the user wants to see in %gs:0.  */
+  word_t user_gs0;
 } arch_ktcb_t;
 
 
diff -rupN pistachio/kernel/include/glue/v4-ia32/syscalls.h pistachio/kernel/include/glue/v4-ia32/syscalls.h
--- pistachio/kernel/include/glue/v4-ia32/syscalls.h	2003-09-24 21:12:22.000000000 +0200
+++ pistachio/kernel/include/glue/v4-ia32/syscalls.h	2005-01-22 02:14:14.000000000 +0100
@@ -184,6 +184,8 @@
 #define return_memory_control()	return
 
 
+void sys_set_gs0 (word_t user_gs0, ia32_exceptionframe_t *__frame);
+
 
 /* entry functions for exceptions */
 extern "C" void exc_user_sysipc(void);
diff -rupN pistachio/kernel/include/glue/v4-ia32/tcb.h pistachio/kernel/include/glue/v4-ia32/tcb.h
--- pistachio/kernel/include/glue/v4-ia32/tcb.h	2005-01-22 01:45:47.000000000 +0100
+++ pistachio/kernel/include/glue/v4-ia32/tcb.h	2005-01-22 02:14:14.000000000 +0100
@@ -173,6 +173,8 @@ INLINE void tcb_t::init_stack()
 {
     stack = get_stack_top();
     //TRACE("stack = %p\n", stack);
+
+    arch.user_gs0 = 0;
 }
 
 
@@ -254,7 +256,7 @@ INLINE void tcb_t::switch_to(tcb_t * des
 	"	jne	1f				\n"
 	"	movl	$1, __is_small			\n"
 	"1:	popl	%%eax				\n"
-	"	movl	%3, %%gs:0			\n"
+	"	movl	%3, %%gs:4			\n"
 	"	jmp	*%%eax				\n"
 
 	"2:	/* switch to large space */		\n"
@@ -281,7 +283,10 @@ INLINE void tcb_t::switch_to(tcb_t * des
 	"	movl	%%ecx, %%cr3			\n"
 
 	"4:	popl	%%edx		/* activation addr */		\n"
-	"	movl	%3, %%gs:0	/* update current UTCB */	\n"
+	"	movl	%3, %%gs:4	/* update current UTCB */	\n"
+
+	"       movl    %c8(%2), %%ecx	/* get dest.arch.user_gs0 */	\n"
+	"	movl    %%ecx, %%gs:0	/* install it */		\n"
 
 	"	jmp	*%%edx						\n"
 	"9:	movl	%2, %1		/* restore 'this' */		\n"
@@ -298,7 +303,8 @@ INLINE void tcb_t::switch_to(tcb_t * des
 	"i" (OFS_TCB_PDIR_CACHE),		// 6
 	"a" ((word_t) dest->space
 	     + (CONFIG_SMP_MAX_CPUS * IA32_PAGE_SIZE)
-	     + (SMALL_SPACE_ID >> IA32_PAGEDIR_BITS) * 4) // 7
+	     + (SMALL_SPACE_ID >> IA32_PAGEDIR_BITS) * 4), // 7
+	"i" (OFS_TCB_ARCH)			// 8
 	:
 	"ecx", "edx", "memory");
 
@@ -330,7 +336,10 @@ INLINE void tcb_t::switch_to(tcb_t * des
 	"movl	%7, %%cr3	\n\t"	/* reload pagedir */
 	"2:			\n\t"
 	"popl	%%edx		\n\t"	/* load activation addr */
-	"movl	%3, %%gs:0	\n\t"	/* update current UTCB */
+	"movl	%3, %%gs:4	\n\t"	/* update current UTCB */
+
+	"movl   %c9(%2), %%ecx	\n\t"	/* get dest.arch.user_gs0 */
+	"movl   %%ecx, %%gs:0	\n\t"	/* install it */
 
 	"jmp	*%%edx		\n\t"
 	"3:			\n\t"
@@ -348,10 +357,11 @@ INLINE void tcb_t::switch_to(tcb_t * des
 	"i" (OFS_TCB_PDIR_CACHE),		// 6
 	"a" (dest->pdir_cache),			// 7
 #ifdef CONFIG_CPU_IA32_P4
-	"c" (this->pdir_cache)			// 8
+	"c" (this->pdir_cache),			// 8
 #else
-	"c" (dest->pdir_cache)			// dummy
+	"c" (dest->pdir_cache),			// dummy
 #endif
+	"i" (OFS_TCB_ARCH)			// 9
 	: "edx", "memory"
 	);
 
diff -rupN pistachio/kernel/src/glue/v4-ia32/gs0.cc pistachio/kernel/src/glue/v4-ia32/gs0.cc
--- pistachio/kernel/src/glue/v4-ia32/gs0.cc	1970-01-01 01:00:00.000000000 +0100
+++ pistachio/kernel/src/glue/v4-ia32/gs0.cc	2005-01-22 02:14:14.000000000 +0100
@@ -0,0 +1,15 @@
+#include INC_API(tcb.h)
+#include INC_ARCH(trapgate.h)
+
+void
+sys_set_gs0 (word_t user_gs0,
+	     ia32_exceptionframe_t *__frame)
+{
+  get_current_tcb()->get_arch()->user_gs0 = user_gs0;
+
+  asm volatile ("	movl	%0, %%gs:0	\n"
+		:
+		: "r" (user_gs0));
+
+  return;
+}
diff -rupN pistachio/kernel/src/glue/v4-ia32/init.cc pistachio/kernel/src/glue/v4-ia32/init.cc
--- pistachio/kernel/src/glue/v4-ia32/init.cc	2005-01-22 01:45:49.000000000 +0100
+++ pistachio/kernel/src/glue/v4-ia32/init.cc	2005-01-22 02:14:14.000000000 +0100
@@ -222,12 +222,13 @@ static void setup_gdt(ia32_tss_t & tss, 
     gdt[gdt_idx(IA32_UDS)].set_seg(0, ~0, 3, ia32_segdesc_t::data);
 
     /* MyUTCB pointer, 
-     * we use a separate page for all processors allocated in space_t 
-     * and have one UTCB entry per cache line in the SMP case */
+     * we use a separate page for all processors allocated in space_t
+     * and have one user word and one UTCB entry per cache line in the
+     * SMP case */
     ASSERT(unsigned(cpuid * CACHE_LINE_SIZE) < IA32_PAGE_SIZE);
     gdt[gdt_idx(IA32_UTCB)].set_seg((u32_t)MYUTCB_MAPPING + 
 				    (cpuid * CACHE_LINE_SIZE),
-				    sizeof(threadid_t) - 1, 
+				    sizeof (word_t) + sizeof(threadid_t) - 1, 
 				    3, ia32_segdesc_t::data);
 
     /* the TSS
diff -rupN pistachio/kernel/src/glue/v4-ia32/Makeconf pistachio/kernel/src/glue/v4-ia32/Makeconf
--- pistachio/kernel/src/glue/v4-ia32/Makeconf	2004-03-16 05:05:06.000000000 +0100
+++ pistachio/kernel/src/glue/v4-ia32/Makeconf	2005-01-22 02:14:14.000000000 +0100
@@ -3,7 +3,7 @@ LDSCRIPT = $(SRCDIR)/src/glue/$(API)-$(A
 CURDIR = src/glue/v4-ia32
 SOURCES += $(addprefix $(CURDIR)/, init.cc idt.cc exception.cc \
 	space.cc debug.cc resources.cc thread.cc user.cc trap.S \
-	ctors.cc smp.cc trampoline.S)
+	ctors.cc smp.cc trampoline.S gs0.cc)
 
 SOURCES+=	src/generic/linear_ptab_walker.cc \
 		src/generic/mapping_alloc.cc \
diff -rupN pistachio/kernel/src/glue/v4-ia32/space.cc pistachio/kernel/src/glue/v4-ia32/space.cc
--- pistachio/kernel/src/glue/v4-ia32/space.cc	2005-01-22 01:45:49.000000000 +0100
+++ pistachio/kernel/src/glue/v4-ia32/space.cc	2005-01-22 02:14:14.000000000 +0100
@@ -329,7 +329,7 @@ void SECTION(".init.memory") space_t::in
 
     /* MYUTCB mapping
      * allocate a full page for all myutcb pointers.
-     * access must be performed via gs:0, when setting up the gdt
+     * access must be performed via gs:4, when setting up the gdt
      * each processor gets a full cache line to avoid bouncing 
      * page is user-writable and global
      */
diff -rupN pistachio/kernel/src/glue/v4-ia32/trap.S pistachio/kernel/src/glue/v4-ia32/trap.S
--- pistachio/kernel/src/glue/v4-ia32/trap.S	2004-11-17 01:48:13.000000000 +0100
+++ pistachio/kernel/src/glue/v4-ia32/trap.S	2005-01-22 02:14:14.000000000 +0100
@@ -175,7 +175,7 @@ fp_save_resources_done:
 	pushl	$fp_ipc_done
 	movl	OFS_TCB_MYSELF_LOCAL(%esi), %edi	// local id
 	movl	OFS_TCB_PDIR_CACHE(%esi), %eax		// new PDIR
-	movl	%edi, %gs:0
+	movl	%edi, %gs:4
 	movl	%esp, OFS_TCB_STACK(%ebx)		// store stack ptr
 	movl	OFS_TCB_STACK(%esi), %esp		// load stack ptr
 	popl	%ecx					// load dest addr
@@ -241,7 +241,7 @@ fp_save_resources_done:
 	movl	%ecx, %gs
 	movl	$1, __is_small
 1:	popl	%ecx
-	movl	%edi, %gs:0
+	movl	%edi, %gs:4
 	jmp	*%ecx
 
 2:	/* switch to large space */
@@ -268,7 +268,7 @@ fp_save_resources_done:
 	movl	%ecx, %cr3
 
 9:	popl	%ecx
-	movl	%edi, %gs:0
+	movl	%edi, %gs:4
 
 #endif /* CONFIG_IA32_SMALL_SPACES */
 
diff -rupN pistachio/kernel/src/glue/v4-ia32/user.cc pistachio/kernel/src/glue/v4-ia32/user.cc
--- pistachio/kernel/src/glue/v4-ia32/user.cc	2005-01-22 01:45:49.000000000 +0100
+++ pistachio/kernel/src/glue/v4-ia32/user.cc	2005-01-22 02:14:14.000000000 +0100
@@ -172,7 +172,7 @@ SYSCALL_STUB(system_clock)
 	"add	%c0(%%ecx), %%ecx	\n"	/* procdesc */
 #ifdef CONFIG_SMP
 	/* get processor # --> allow for differently clocked CPUs */
-	"mov	%%gs:0, %%eax		\n"	/* myutcb */
+	"mov	%%gs:4, %%eax		\n"	/* myutcb */
 	"mov	%c2(%%eax), %%eax	\n"
 	"shl	%3, %%eax		\n"
 	"add	%%eax, %%ecx		\n"
@@ -344,6 +344,14 @@ SYSCALL_STUB(memory_control)
 	: "i"(SYS_SYSCALL_NUM));
 }
 
+SYSCALL_STUB(set_gs0)
+{
+    __asm__ __volatile__(
+	SYSCALL_LABEL (set_gs0)
+	:
+	: "i"(SYS_SYSCALL_NUM));
+}
+
 
 #define IS_SYSCALL(x) ((frame->eip - (u32_t)get_current_space()->get_kip_page_area().get_base()) == ((u32_t)(&entry_##x) - (u32_t)get_kip() + 2))
 
@@ -399,6 +407,11 @@ IA32_EXC_NO_ERRORCODE(exc_user_syscall, 
 			  frame);
     }
 
+    else if (IS_SYSCALL(set_gs0))
+    {
+	sys_set_gs0(frame->eax, frame);
+    }
+
     else
 	printf("unknown syscall\n");
     return;
diff -rupN pistachio/user/include/l4/ia32/vregs.h pistachio/user/include/l4/ia32/vregs.h
--- pistachio/user/include/l4/ia32/vregs.h	2004-11-17 01:48:13.000000000 +0100
+++ pistachio/user/include/l4/ia32/vregs.h	2005-01-22 02:14:14.000000000 +0100
@@ -48,7 +48,7 @@ L4_INLINE L4_Word_t * __L4_X86_Utcb (voi
 
     __asm__ __volatile__ (
 	"/* __L4_X86_Utcb() */			\n"
-	"	mov %%gs:0, %0			\n"
+	"	mov %%gs:4, %0			\n"
 
 	: /* outputs */
 	"=r"(utcb)