Commit [9b14de] Maximize Restore History

Created basic .config handling

moved i386 specific stuff to x86_32 directories

barbux barbux 2008-03-23

1 2 3 .. 6 > >> (Page 1 of 6)
added main/kernel/.config
added main/kernel/.cvsignore
added main/kernel/boot/.cvsignore
added main/kernel/config
added main/kernel/config/.cvsignore
added main/kernel/config/master.config
added main/kernel/config/src
added main/kernel/config/src/.cvsignore
added main/kernel/config/src/Makefile
added main/kernel/drivers/.cvsignore
added main/kernel/drivers/ide/.cvsignore
added main/kernel/drivers/net/.cvsignore
added main/kernel/fs/.cvsignore
added main/kernel/fs/ext2/.cvsignore
added main/kernel/fs/fat/.cvsignore
added main/kernel/kernel/.cvsignore
added main/kernel/kernel/x86_32
added main/kernel/lib/.cvsignore
added main/kernel/lib/x86_32
added main/kernel/mm/.cvsignore
added main/kernel/mm/x86_32
removed main/kernel/lib/libbz2
removed main/kernel/lib/libbz2/bzlib.c
removed main/kernel/lib/libbz2/decompress.c
removed main/kernel/lib/libbz2/randtable.c
removed main/kernel/mm/memprocess.c
removed main/kernel/mm/memzone.c
removed main/kernel/mm/pagination.c
changed main
changed main/app
changed main/app/bed
changed main/app/bed/Makefile
changed main/app/calc
changed main/app/calc/Makefile
changed main/app/colors
changed main/app/colors/Makefile
changed main/app/compteur
changed main/app/compteur/Makefile
changed main/app/e2info
changed main/app/e2info/Makefile
changed main/app/fdisk
changed main/app/fdisk/Makefile
changed main/app/init
changed main/app/init/Makefile
changed main/app/loadkeys
changed main/app/loadkeys/Makefile
changed main/app/loadkeys2
changed main/app/loadkeys2/Makefile
changed main/app/obs
changed main/app/obs/Makefile
changed main/app/pagetest
changed main/app/pagetest/Makefile
changed main/app/ping
changed main/app/ping/Makefile
changed main/app/shell
changed main/app/shell/Makefile
changed main/app/skel
changed main/app/skel/Makefile
changed main/app/testjb
changed main/app/testjb/Makefile
changed main/kernel
changed main/kernel/Makefile
changed main/kernel/boot
changed main/kernel/drivers
changed main/kernel/drivers/Makefile
changed main/kernel/drivers/ide
changed main/kernel/drivers/ide/Makefile
changed main/kernel/drivers/net
changed main/kernel/drivers/net/Makefile
changed main/kernel/fs
changed main/kernel/fs/Makefile
changed main/kernel/fs/ext2
changed main/kernel/fs/ext2/Makefile
changed main/kernel/fs/fat
changed main/kernel/fs/fat/Makefile
changed main/kernel/kernel
changed main/kernel/kernel/Makefile
changed main/kernel/lib
changed main/kernel/lib/Makefile
changed main/kernel/mm
changed main/kernel/mm/Makefile
changed main/lib
changed main/lib/LibB
changed main/lib/LibB/Makefile
changed main/lib/LibB/src
changed main/lib/LibB/src/bz2
changed main/lib/LibB/src/bz2/Makefile
changed main/lib/bcurses
changed main/lib/bcurses/Makefile
changed main/mk
changed main/mk/flags.mk
changed main/mk/kern.lib.mk
changed main/mk/kern.module.mk
changed main/mk/rules.mk
copied main/kernel/kernel/cpuid.S -> main/kernel/kernel/x86_32/cpuid.S
copied main/kernel/kernel/debug.S -> main/kernel/kernel/x86_32/debug.S
copied main/kernel/kernel/entry.S -> main/kernel/kernel/x86_32/entry.S
copied main/kernel/kernel/features.S -> main/kernel/kernel/x86_32/features.S
copied main/kernel/kernel/head.S -> main/kernel/kernel/x86_32/head.S
copied main/kernel/kernel/i386.c -> main/kernel/kernel/x86_32/i386.c
copied main/kernel/kernel/i386_cpu.c -> main/kernel/kernel/x86_32/i386_cpu.c
copied main/kernel/kernel/idt.S -> main/kernel/kernel/x86_32/idt.S
copied main/kernel/kernel/interrupt.c -> main/kernel/kernel/x86_32/interrupt.c
copied main/kernel/kernel/traps.c -> main/kernel/kernel/x86_32/traps.c
copied main/kernel/lib/libbz2/Makefile -> main/kernel/mm/x86_32/asm.S
copied main/kernel/lib/libbz2/blocksort.c -> main/kernel/mm/x86_32/pagination.c
copied main/kernel/lib/libbz2/compress.c -> main/kernel/mm/x86_32/memzone.c
copied main/kernel/lib/libbz2/crctable.c -> main/kernel/config/src/parse.c
copied main/kernel/lib/libbz2/huffman.c -> main/kernel/mm/x86_32/rbmap.c
copied main/kernel/lib/memset.S -> main/kernel/lib/x86_32/memset.S
copied main/kernel/mm/asm.S -> main/kernel/mm/x86_32/mem.c
copied main/kernel/mm/mem.c -> main/kernel/mm/x86_32/mem_map.c
copied main/kernel/mm/mem_map.c -> main/kernel/mm/x86_32/memprocess.c
copied main/kernel/mm/rbmap.c -> main/kernel/kernel/x86_32/test.S
main/kernel/.config Diff Switch to side-by-side view
Loading...
main/kernel/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/boot/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/config
Directory.
main/kernel/config/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/config/master.config Diff Switch to side-by-side view
Loading...
main/kernel/config/src/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/config/src/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/drivers/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/drivers/ide/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/drivers/net/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/fs/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/fs/ext2/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/fs/fat/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/kernel/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/lib/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/mm/.cvsignore Diff Switch to side-by-side view
Loading...
main/kernel/lib/libbz2
File was removed.
main/kernel/lib/libbz2/bzlib.c
File was removed.
main/kernel/mm/memprocess.c
File was removed.
main/kernel/mm/memzone.c
File was removed.
main/kernel/mm/pagination.c
File was removed.
main
Directory.
main/app
Directory.
main/app/bed
Directory.
main/app/bed/Makefile Diff Switch to side-by-side view
Loading...
main/app/calc
Directory.
main/app/calc/Makefile Diff Switch to side-by-side view
Loading...
main/app/colors
Directory.
main/app/colors/Makefile Diff Switch to side-by-side view
Loading...
main/app/compteur
Directory.
main/app/compteur/Makefile Diff Switch to side-by-side view
Loading...
main/app/e2info
Directory.
main/app/e2info/Makefile Diff Switch to side-by-side view
Loading...
main/app/fdisk
Directory.
main/app/fdisk/Makefile Diff Switch to side-by-side view
Loading...
main/app/init
Directory.
main/app/init/Makefile Diff Switch to side-by-side view
Loading...
main/app/loadkeys
Directory.
main/app/loadkeys/Makefile Diff Switch to side-by-side view
Loading...
main/app/loadkeys2
Directory.
main/app/loadkeys2/Makefile Diff Switch to side-by-side view
Loading...
main/app/obs
Directory.
main/app/obs/Makefile Diff Switch to side-by-side view
Loading...
main/app/pagetest
Directory.
main/app/pagetest/Makefile Diff Switch to side-by-side view
Loading...
main/app/ping
Directory.
main/app/ping/Makefile Diff Switch to side-by-side view
Loading...
main/app/shell
Directory.
main/app/shell/Makefile Diff Switch to side-by-side view
Loading...
main/app/skel
Directory.
main/app/skel/Makefile Diff Switch to side-by-side view
Loading...
main/app/testjb
Directory.
main/app/testjb/Makefile Diff Switch to side-by-side view
Loading...
main/kernel
Directory.
main/kernel/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/boot
Directory.
main/kernel/drivers
Directory.
main/kernel/drivers/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/drivers/ide/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/drivers/net/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/fs
Directory.
main/kernel/fs/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/fs/ext2
Directory.
main/kernel/fs/ext2/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/fs/fat
Directory.
main/kernel/fs/fat/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/kernel
Directory.
main/kernel/kernel/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/lib
Directory.
main/kernel/lib/Makefile Diff Switch to side-by-side view
Loading...
main/kernel/mm
Directory.
main/kernel/mm/Makefile Diff Switch to side-by-side view
Loading...
main/lib
Directory.
main/lib/LibB
Directory.
main/lib/LibB/Makefile Diff Switch to side-by-side view
Loading...
main/lib/LibB/src
Directory.
main/lib/LibB/src/bz2/Makefile Diff Switch to side-by-side view
Loading...
main/lib/bcurses
Directory.
main/lib/bcurses/Makefile Diff Switch to side-by-side view
Loading...
main/mk
Directory.
main/mk/flags.mk Diff Switch to side-by-side view
Loading...
main/mk/kern.lib.mk Diff Switch to side-by-side view
Loading...
main/mk/kern.module.mk Diff Switch to side-by-side view
Loading...
main/mk/rules.mk Diff Switch to side-by-side view
Loading...
main/kernel/kernel/cpuid.S to main/kernel/kernel/x86_32/cpuid.S
--- a/main/kernel/kernel/cpuid.S
+++ b/main/kernel/kernel/x86_32/cpuid.S
@@ -1,4 +1,4 @@
-/* $Id: cpuid.S,v 1.1 2004/07/10 23:22:42 rmp91 Exp $
+/* $Id: cpuid.S,v 1.1 2008/03/23 05:26:52 barbux Exp $
  *
  * Low-level function for CPU identification
  *
main/kernel/kernel/debug.S to main/kernel/kernel/x86_32/debug.S
--- a/main/kernel/kernel/debug.S
+++ b/main/kernel/kernel/x86_32/debug.S
@@ -1,4 +1,4 @@
-/* $Id: debug.S,v 1.2 2006/10/08 22:22:50 rmp91 Exp $
+/* $Id: debug.S,v 1.1 2008/03/23 05:26:52 barbux Exp $
  * 
  * Low-level assembly routines for kernel debugging
  *
main/kernel/kernel/entry.S to main/kernel/kernel/x86_32/entry.S
--- a/main/kernel/kernel/entry.S
+++ b/main/kernel/kernel/x86_32/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.12 2006/11/11 16:50:43 rmp91 Exp $ */
+/* $Id: entry.S,v 1.1 2008/03/23 05:26:52 barbux Exp $ */
 
 /* Fichier d entree dans le kernel
  * C est par ici que le system repasse en mode systeme
main/kernel/kernel/features.S to main/kernel/kernel/x86_32/features.S
--- a/main/kernel/kernel/features.S
+++ b/main/kernel/kernel/x86_32/features.S
@@ -1,4 +1,4 @@
-/* $Id: features.S,v 1.2 2006/10/24 19:16:43 rmp91 Exp $
+/* $Id: features.S,v 1.1 2008/03/23 05:26:52 barbux Exp $
  *
  * IA-32 control registers features enabling & disabling
  * Model Specific Registers (MSR) read & write
main/kernel/kernel/head.S to main/kernel/kernel/x86_32/head.S
--- a/main/kernel/kernel/head.S
+++ b/main/kernel/kernel/x86_32/head.S
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.12 2006/10/21 14:33:35 rmp91 Exp $ */
+/* $Id: head.S,v 1.1 2008/03/23 05:26:52 barbux Exp $ */
 
 #define ASM 1
 #include <multiboot.h>
main/kernel/kernel/i386.c to main/kernel/kernel/x86_32/i386.c
--- a/main/kernel/kernel/i386.c
+++ b/main/kernel/kernel/x86_32/i386.c
@@ -1,4 +1,4 @@
-/* $Id: i386.c,v 1.2 2006/11/11 16:50:43 rmp91 Exp $ */
+/* $Id: i386.c,v 1.1 2008/03/23 05:26:52 barbux Exp $ */
 
 #include <string.h>
 
main/kernel/kernel/i386_cpu.c to main/kernel/kernel/x86_32/i386_cpu.c
--- a/main/kernel/kernel/i386_cpu.c
+++ b/main/kernel/kernel/x86_32/i386_cpu.c
@@ -1,4 +1,4 @@
-/* $Id: i386_cpu.c,v 1.3 2006/10/14 16:01:58 rmp91 Exp $ */
+/* $Id: i386_cpu.c,v 1.1 2008/03/23 05:26:52 barbux Exp $ */
 
 /*
  * i386_cpu.c
main/kernel/kernel/idt.S to main/kernel/kernel/x86_32/idt.S
--- a/main/kernel/kernel/idt.S
+++ b/main/kernel/kernel/x86_32/idt.S
@@ -1,4 +1,4 @@
-# $Id: idt.S,v 1.2 2006/09/13 22:30:49 barbux Exp $
+# $Id: idt.S,v 1.1 2008/03/23 05:26:52 barbux Exp $
 #
 # Interrupt Descriptor Table (IDT) handling
 #
main/kernel/kernel/interrupt.c to main/kernel/kernel/x86_32/interrupt.c
--- a/main/kernel/kernel/interrupt.c
+++ b/main/kernel/kernel/x86_32/interrupt.c
@@ -1,4 +1,4 @@
-/* $Id: interrupt.c,v 1.16 2006/11/11 16:50:43 rmp91 Exp $ */
+/* $Id: interrupt.c,v 1.1 2008/03/23 05:26:52 barbux Exp $ */
 
 /*
  * interrupt.c
main/kernel/kernel/traps.c to main/kernel/kernel/x86_32/traps.c
--- a/main/kernel/kernel/traps.c
+++ b/main/kernel/kernel/x86_32/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.3 2006/11/11 16:50:44 rmp91 Exp $ */
+/* $Id: traps.c,v 1.1 2008/03/23 05:26:52 barbux Exp $ */
 
 /*
  * traps.c
main/kernel/lib/libbz2/Makefile to main/kernel/mm/x86_32/asm.S
--- a/main/kernel/lib/libbz2/Makefile
+++ b/main/kernel/mm/x86_32/asm.S
@@ -1,55 +1,128 @@
-SHELL=/bin/sh
+/* $Id: asm.S,v 1.1 2008/03/23 05:26:53 barbux Exp $
+ *
+ * Assembly routines for memory managing
+ *
+ */
 
-# To assist in cross-compiling
-CC=gcc
-AR=ar
-RANLIB=ranlib
-LDFLAGS=
+.globl pg_table_linear_fill
+.globl pg_table_linear_or
+.globl pg_table_linear_and
+.globl flush_one_tlb
+.globl flush_all_tlb
+.globl flush_pge_tlb
 
-# Suitably paranoid flags to avoid bugs in gcc-2.7
-BIGFILES=-D_FILE_OFFSET_BITS=64
-CFLAGS=-D_KERNEL_BARBUX -I../../include/ -DBZ_NO_STDIO -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce $(BIGFILES)
+#include <mem.h>
 
-OBJS= blocksort.o  \
-      huffman.o    \
-      crctable.o   \
-      randtable.o  \
-      compress.o   \
-      decompress.o \
-      bzlib.o
+.align 4
 
-all: libbz2.a
+pg_table_linear_fill:
+	pushl %ebp
+	movl %esp, %ebp
 
-libbz2.a: $(OBJS)
-	rm -f libbz2.a
-	$(AR) cq libbz2.a $(OBJS)
-	@if ( test -f $(RANLIB) -o -f /usr/bin/ranlib -o \
-                -f /bin/ranlib -o -f /usr/ccs/bin/ranlib ) ; then \
-                echo $(RANLIB) libbz2.a ; \
-                $(RANLIB) libbz2.a ; \
-	fi
+	pushl %ecx
+	pushl %edi
+	pushl %ebx
+	
+	movl 0x10(%ebp), %eax
+	andl $0xfff, %eax	# Only first 12 bits counts
 
-blocksort.o: blocksort.c
-#	@cat words0
-	$(CC) $(CFLAGS) -c blocksort.c
+	movl 0xc(%ebp), %ebx
+	andl $0xfffff000, %ebx	# Mask 20 high bits
 
-huffman.o: huffman.c
-	$(CC) $(CFLAGS) -c huffman.c
+	orl %ebx, %eax
 
-crctable.o: crctable.c
-	$(CC) $(CFLAGS) -c crctable.c
+	movl 0x14(%ebp), %ecx	# Count
 
-randtable.o: randtable.c
-	$(CC) $(CFLAGS) -c randtable.c
+	movl 0x8(%ebp), %edi
 
-compress.o: compress.c
-	$(CC) $(CFLAGS) -c compress.c
+	cld
 
-decompress.o: decompress.c
-	$(CC) $(CFLAGS) -c decompress.c
+1:	
+	stosl
+	addl $PAGE_SIZE, %eax
+	loop 1b
 
-bzlib.o: bzlib.c
-	$(CC) $(CFLAGS) -c bzlib.c
 
-clean:
-	rm -f *.o *.a
+	popl %ebx
+	popl %edi
+	popl %ecx
+	
+	popl %ebp
+
+	ret
+
+
+.align 4
+
+pg_table_linear_or:
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%ecx
+	pushl	%edi
+
+	movl	0x8(%ebp), %edi
+	movl	0xc(%ebp), %eax
+	movl	0x10(%ebp), %ecx
+
+1:
+	orl	%eax, (%edi)
+	addl	$4, %edi
+	loop 	1b
+
+	popl	%edi
+	popl	%ecx
+
+	popl	%ebp
+	ret
+
+
+.align 4
+
+pg_table_linear_and:
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%ecx
+	pushl	%edi
+
+	movl	0x8(%ebp), %edi
+	movl	0xc(%ebp), %eax
+	movl	0x10(%ebp), %ecx
+
+1:
+	andl	%eax, (%edi)
+	addl	$4, %edi
+	loop 	1b
+
+	popl	%edi
+	popl	%ecx
+
+	popl	%ebp
+	ret
+
+.align 4
+
+flush_one_tlb:
+	invlpg 0x4(%esp)
+	ret
+
+.align 4
+
+flush_all_tlb:
+	movl %cr3, %eax
+	movl %eax, %cr3
+	ret
+
+#define PGE_BITMASK	0x000080
+
+.align 4
+
+flush_pge_tlb:
+	pushl $PGE_BITMASK
+	call cr4_feat_disable
+	call flush_all_tlb
+	call cr4_feat_enable
+	addl $4, %esp
+	ret
+
main/kernel/lib/libbz2/blocksort.c to main/kernel/mm/x86_32/pagination.c
--- a/main/kernel/lib/libbz2/blocksort.c
+++ b/main/kernel/mm/x86_32/pagination.c
@@ -1,1141 +1,745 @@
-
-/*-------------------------------------------------------------*/
-/*--- Block sorting machinery                               ---*/
-/*---                                           blocksort.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward@acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
-
-  To get some idea how the block sorting algorithms in this file 
-  work, read my paper 
-     On the Performance of BWT Sorting Algorithms
-  in Proceedings of the IEEE Data Compression Conference 2000,
-  Snowbird, Utah, USA, 27-30 March 2000.  The main sort in this
-  file implements the algorithm called  cache  in the paper.
---*/
-
-
-#include "bzlib_private.h"
-
-/*---------------------------------------------*/
-/*--- Fallback O(N log(N)^2) sorting        ---*/
-/*--- algorithm, for repetitive blocks      ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static 
-__inline__
-void fallbackSimpleSort ( UInt32* fmap, 
-                          UInt32* eclass, 
-                          Int32   lo, 
-                          Int32   hi )
-{
-   Int32 i, j, tmp;
-   UInt32 ec_tmp;
-
-   if (lo == hi) return;
-
-   if (hi - lo > 3) {
-      for ( i = hi-4; i >= lo; i-- ) {
-         tmp = fmap[i];
-         ec_tmp = eclass[tmp];
-         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
-            fmap[j-4] = fmap[j];
-         fmap[j-4] = tmp;
-      }
-   }
-
-   for ( i = hi-1; i >= lo; i-- ) {
-      tmp = fmap[i];
-      ec_tmp = eclass[tmp];
-      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
-         fmap[j-1] = fmap[j];
-      fmap[j-1] = tmp;
-   }
-}
-
-
-/*---------------------------------------------*/
-#define fswap(zz1, zz2) \
-   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define fvswap(zzp1, zzp2, zzn)       \
-{                                     \
-   Int32 yyp1 = (zzp1);               \
-   Int32 yyp2 = (zzp2);               \
-   Int32 yyn  = (zzn);                \
-   while (yyn > 0) {                  \
-      fswap(fmap[yyp1], fmap[yyp2]);  \
-      yyp1++; yyp2++; yyn--;          \
-   }                                  \
-}
-
-
-#define fmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define fpush(lz,hz) { stackLo[sp] = lz; \
-                       stackHi[sp] = hz; \
-                       sp++; }
-
-#define fpop(lz,hz) { sp--;              \
-                      lz = stackLo[sp];  \
-                      hz = stackHi[sp]; }
-
-#define FALLBACK_QSORT_SMALL_THRESH 10
-#define FALLBACK_QSORT_STACK_SIZE   100
-
-
-static
-void fallbackQSort3 ( UInt32* fmap, 
-                      UInt32* eclass,
-                      Int32   loSt, 
-                      Int32   hiSt )
-{
-   Int32 unLo, unHi, ltLo, gtHi, n, m;
-   Int32 sp, lo, hi;
-   UInt32 med, r, r3;
-   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
-   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
-
-   r = 0;
-
-   sp = 0;
-   fpush ( loSt, hiSt );
-
-   while (sp > 0) {
-
-      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
-
-      fpop ( lo, hi );
-      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
-         fallbackSimpleSort ( fmap, eclass, lo, hi );
-         continue;
-      }
-
-      /* Random partitioning.  Median of 3 sometimes fails to
-         avoid bad cases.  Median of 9 seems to help but 
-         looks rather expensive.  This too seems to work but
-         is cheaper.  Guidance for the magic constants 
-         7621 and 32768 is taken from Sedgewick's algorithms
-         book, chapter 35.
-      */
-      r = ((r * 7621) + 1) % 32768;
-      r3 = r % 3;
-      if (r3 == 0) med = eclass[fmap[lo]]; else
-      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
-                   med = eclass[fmap[hi]];
-
-      unLo = ltLo = lo;
-      unHi = gtHi = hi;
-
-      while (1) {
-         while (1) {
-            if (unLo > unHi) break;
-            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
-            if (n == 0) { 
-               fswap(fmap[unLo], fmap[ltLo]); 
-               ltLo++; unLo++; 
-               continue; 
-            };
-            if (n > 0) break;
-            unLo++;
-         }
-         while (1) {
-            if (unLo > unHi) break;
-            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
-            if (n == 0) { 
-               fswap(fmap[unHi], fmap[gtHi]); 
-               gtHi--; unHi--; 
-               continue; 
-            };
-            if (n < 0) break;
-            unHi--;
-         }
-         if (unLo > unHi) break;
-         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
-      }
-
-      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
-
-      if (gtHi < ltLo) continue;
-
-      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
-      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
-
-      n = lo + unLo - ltLo - 1;
-      m = hi - (gtHi - unHi) + 1;
-
-      if (n - lo > hi - m) {
-         fpush ( lo, n );
-         fpush ( m, hi );
-      } else {
-         fpush ( m, hi );
-         fpush ( lo, n );
-      }
-   }
-}
-
-#undef fmin
-#undef fpush
-#undef fpop
-#undef fswap
-#undef fvswap
-#undef FALLBACK_QSORT_SMALL_THRESH
-#undef FALLBACK_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
-      nblock > 0
-      eclass exists for [0 .. nblock-1]
-      ((UChar*)eclass) [0 .. nblock-1] holds block
-      ptr exists for [0 .. nblock-1]
-
-   Post:
-      ((UChar*)eclass) [0 .. nblock-1] holds block
-      All other areas of eclass destroyed
-      fmap [0 .. nblock-1] holds sorted order
-      bhtab [ 0 .. 2+(nblock/32) ] destroyed
-*/
-
-#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
-#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
-#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
-#define      WORD_BH(zz)  bhtab[(zz) >> 5]
-#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
-
-static
-void fallbackSort ( UInt32* fmap, 
-                    UInt32* eclass, 
-                    UInt32* bhtab,
-                    Int32   nblock,
-                    Int32   verb )
-{
-   Int32 ftab[257];
-   Int32 ftabCopy[256];
-   Int32 H, i, j, k, l, r, cc, cc1;
-   Int32 nNotDone;
-   Int32 nBhtab;
-   UChar* eclass8 = (UChar*)eclass;
-
-   /*--
-      Initial 1-char radix sort to generate
-      initial fmap and initial BH bits.
-   --*/
-   if (verb >= 4)
-      VPrintf0 ( "        bucket sorting ...\n" );
-   for (i = 0; i < 257;    i++) ftab[i] = 0;
-   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
-   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
-   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
-
-   for (i = 0; i < nblock; i++) {
-      j = eclass8[i];
-      k = ftab[j] - 1;
-      ftab[j] = k;
-      fmap[k] = i;
-   }
-
-   nBhtab = 2 + (nblock / 32);
-   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
-   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
-
-   /*--
-      Inductively refine the buckets.  Kind-of an
-      "exponential radix sort" (!), inspired by the
-      Manber-Myers suffix array construction algorithm.
-   --*/
-
-   /*-- set sentinel bits for block-end detection --*/
-   for (i = 0; i < 32; i++) { 
-      SET_BH(nblock + 2*i);
-      CLEAR_BH(nblock + 2*i + 1);
-   }
-
-   /*-- the log(N) loop --*/
-   H = 1;
-   while (1) {
-
-      if (verb >= 4) 
-         VPrintf1 ( "        depth %6d has ", H );
-
-      j = 0;
-      for (i = 0; i < nblock; i++) {
-         if (ISSET_BH(i)) j = i;
-         k = fmap[i] - H; if (k < 0) k += nblock;
-         eclass[k] = j;
-      }
-
-      nNotDone = 0;
-      r = -1;
-      while (1) {
-
-	 /*-- find the next non-singleton bucket --*/
-         k = r + 1;
-         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
-         if (ISSET_BH(k)) {
-            while (WORD_BH(k) == 0xffffffff) k += 32;
-            while (ISSET_BH(k)) k++;
-         }
-         l = k - 1;
-         if (l >= nblock) break;
-         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
-         if (!ISSET_BH(k)) {
-            while (WORD_BH(k) == 0x00000000) k += 32;
-            while (!ISSET_BH(k)) k++;
-         }
-         r = k - 1;
-         if (r >= nblock) break;
-
-         /*-- now [l, r] bracket current bucket --*/
-         if (r > l) {
-            nNotDone += (r - l + 1);
-            fallbackQSort3 ( fmap, eclass, l, r );
-
-            /*-- scan bucket and generate header bits-- */
-            cc = -1;
-            for (i = l; i <= r; i++) {
-               cc1 = eclass[fmap[i]];
-               if (cc != cc1) { SET_BH(i); cc = cc1; };
+/* $Id: pagination.c,v 1.1 2008/03/23 05:26:53 barbux Exp $ */
+
+////////////////
+// Pagination
+////////////////
+
+#include <mem.h>
+#include <rbmap.h>
+#include <paging.h>
+#include <process.h>
+#include <stdio.h>
+#include <bstdarg.h>
+#include <vsprintf.h>
+#include <barbux.h>
+#include <cpuid.h>
+#include <multiboot.h>
+#include <panic.h>
+#include <console.h>
+#include <features.h>
+
+#ifndef MM_NG
+
+#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
+
+void (*flush_tlb) (void *page);
+
+/* Initialize paging */
+
+void paging_init (void);
+
+/* Link physical page to virtual page. Allocates page table if needed
+ * NOTE: does not allocate the corresponding physical page
+ * 0 = succes, -1 virt addr already in use
+ */
+int page_link (pg_entry_t **pg_dir, void *phys_page, void *virt_page, int flags);
+/* Free a page table */
+void page_table_free (pg_entry_t **pg_dir, int table);
+/* Check if all pages in table are unused */
+int page_table_empty (pg_entry_t **pg_dir, int table);
+/* Test if at least of the bits of mask is set on page */
+int page_bits (pg_entry_t **pg_dir, void *page, int mask);
+/* For debugging */
+void page_dump (pg_entry_t **pg_dir, void *page, char *str);
+
+static pg_entry_t *last_mapped_page = NULL;
+static pg_entry_t *page_map_cache = NULL;
+
+void page_add_flags (pg_entry_t **pg_dir, void *page, int flags)
+{
+    pg_entry_t *p;
+
+    p = pg_dir[PAGE_DIR(page)];
+
+    if (! (((pg_entry_t) p) & PG_DIR_PRESENT))
+        panic ("page_add_flags(): trying to modify attributes of page with no associated page table");
+    p = (pg_entry_t *) page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+
+    p[PAGE_TABLE(page)] |= (pg_entry_t) flags;
+    flush_tlb (page);
+
+    page_unmap (pg_get_cr3 (), p);
+}
+
+void pages_add_flags (pg_entry_t **pg_dir, void *start_page, int flags, int count)
+{
+    pg_entry_t *p;
+
+    p = pg_dir[PAGE_DIR(start_page)];
+
+    if (! (((pg_entry_t) p) & PG_DIR_PRESENT))
+        panic ("pages_add_flags(): trying to modify attributes of pages with no associated page table");
+    if (PAGE_TABLE (start_page) + count > PG_TABLE_ENTRIES)
+        panic ("pages_add_flags(): repeat count will take us out of page table");
+
+    p = (pg_entry_t *) page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+
+    pg_table_linear_or (p + PAGE_TABLE(start_page), (uint32_t) flags, count);
+    flush_all_tlb ();
+
+    page_unmap (pg_get_cr3 (), p);
+}
+
+
+void page_rm_flags (pg_entry_t **pg_dir, void *page, int flags)
+{
+    pg_entry_t *p;
+
+    p = pg_dir[PAGE_DIR(page)];
+
+    if (! (((pg_entry_t) p) & PG_DIR_PRESENT))
+        panic ("page_rm_flags(): trying to modify attributes of page with no associated page table");
+    p = (pg_entry_t *) page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+
+    p[PAGE_TABLE(page)] &= ~((pg_entry_t) flags);
+    flush_tlb (page);
+
+    page_unmap (pg_get_cr3 (), p);
+}
+
+void pages_rm_flags (pg_entry_t **pg_dir, void *start_page, int flags, int count)
+{
+    pg_entry_t *p;
+
+    p = pg_dir[PAGE_DIR(start_page)];
+
+    if (! (((pg_entry_t) p) & PG_DIR_PRESENT))
+        panic ("pages_rm_flags(): trying to modify attributes of pages with no associated page table");
+    if (PAGE_TABLE (start_page) + count >= PG_TABLE_ENTRIES)
+        panic ("pages_rm_flags(): repeat count will take us out of page table");
+
+    p = (pg_entry_t *) page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+
+    pg_table_linear_and (p + PAGE_TABLE(start_page), (uint32_t) ~(flags), count);
+    flush_all_tlb ();
+
+    page_unmap (pg_get_cr3 (), p);
+}
+
+
+void page_table_alloc (pg_entry_t **pg_dir, int table)
+{
+    pg_entry_t *entry;
+    pg_entry_t *p;
+    void *phys_addr;
+
+    if (((pg_entry_t) pg_dir[table]) & PG_DIR_PRESENT)
+        panic ("page_table_alloc(): trying to realloc present table");
+
+    /* First allocate a new page */
+    entry = (pg_entry_t *) page_alloc_any (pg_get_cr3 (), &phys_addr);
+
+    page_zerofill (entry);
+
+    p = (pg_entry_t *) &pg_dir[table];
+
+    *p = ((pg_entry_t) phys_addr) & PG_DIR_ADDR;    /* Set address */
+    *p |= PG_DIR_RW | PG_DIR_US;            /* Set flags */
+    *p |= PG_DIR_PRESENT;                /* Mark table as present */
+
+    flush_all_tlb ();
+
+    page_unmap (pg_get_cr3 (), entry);
+}
+
+void page_table_free (pg_entry_t **pg_dir, int table)
+{
+    void *page;
+    pg_entry_t *p;
+
+    if (! (((pg_entry_t) pg_dir[table]) & PG_DIR_PRESENT))
+        panic ("page_table_free(): trying to free non-present page table");
+
+    if (!page_table_empty (pg_dir, table))
+        panic ("page_table_free(): trying to free non-empty page table");
+
+    p = (pg_entry_t * ) &(pg_dir[table]);
+    page = (void *) PG_ENTRY_TO_ADDR(*p);
+
+    *p &= ~(PG_DIR_PRESENT);
+
+    flush_all_tlb ();
+
+    rbmap_free (page);
+}
+
+
+int page_table_empty (pg_entry_t **pg_dir, int table)
+{
+    int i;
+    pg_entry_t *p, *page;
+    int empty = 1;
+
+    if (!(((pg_entry_t) pg_dir[table]) & PG_DIR_PRESENT))
+        return 1;
+
+    page = (pg_entry_t *) page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR (pg_dir[table]));
+
+    /* Let's hope the compiler can optimize it, or rewrite it ourselves in assembly */
+    for (p = page, i = 0; i < PG_TABLE_ENTRIES; i++, p++)
+    {
+        if ((*p) & PG_TABLE_PRESENT)
+        {
+            empty = 0;
+            goto out;
+        }
+    }
+
+out:
+    page_unmap (pg_get_cr3 (), page);
+    return empty;
+}
+
+
+int page_link (pg_entry_t **pg_dir, void *phys_page, void *virt_page, int flags)
+{
+    int table = (int) PAGE_DIR(virt_page);
+    pg_entry_t *p;
+    void *page;
+
+    p = pg_dir[table];
+
+    if (!(((pg_entry_t) p) & PG_DIR_PRESENT))
+    {
+        page_table_alloc (pg_dir, table);
+        p = pg_dir[table];        /* Refresh entry */
+    }
+
+    /* Don't forget to mask 12 lower bits before using as a pointer */
+    page = page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+    p = (pg_entry_t *) page;
+    p += (int) PAGE_TABLE (virt_page);
+
+    /* Clear alloc bit */
+    *p &= ~(PG_TABLE_ALLOC);
+
+    if ((*p) & PG_TABLE_PRESENT)
+    {
+        page_unmap (pg_get_cr3 (), page);
+        return -1;
+    }
+
+    *p = 1;        /* Set present before all */
+    *p |= (pg_entry_t) (((pg_entry_t) phys_page) & PG_TABLE_ADDR);
+    *p |= PG_TABLE_RW | flags;    /* User & RW */
+    flush_tlb (virt_page);
+
+    page_unmap (pg_get_cr3 (), page);
+
+    return 0;
+}
+
+
+void *page_find_free (pg_entry_t **pg_dir)
+{
+    int i, j;
+    pg_entry_t *p;
+    void *page;
+    void *res;
+
+    /* Pass 1: check for free addresses in allocated page tables */
+    for (i = 0; i < PG_DIR_ENTRIES; i++) 
+    {
+        p = pg_dir[i];
+        if (! (((pg_entry_t) p) & PG_DIR_PRESENT))
+        {
+            continue;
+        }
+
+        page = page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+        p = (pg_entry_t *) page;
+        for (j = 0; j < PG_TABLE_ENTRIES; j++, p++) 
+        {
+            if ((*p) & PG_TABLE_PRESENT || (*p)  & PG_TABLE_ALLOC)
+            {
+                continue;
             }
-         }
-      }
-
-      if (verb >= 4) 
-         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
-
-      H *= 2;
-      if (H > nblock || nNotDone == 0) break;
-   }
-
-   /*-- 
-      Reconstruct the original block in
-      eclass8 [0 .. nblock-1], since the
-      previous phase destroyed it.
-   --*/
-   if (verb >= 4)
-      VPrintf0 ( "        reconstructing block ...\n" );
-   j = 0;
-   for (i = 0; i < nblock; i++) {
-      while (ftabCopy[j] == 0) j++;
-      ftabCopy[j]--;
-      eclass8[fmap[i]] = (UChar)j;
-   }
-   AssertH ( j < 256, 1005 );
-}
-
-#undef       SET_BH
-#undef     CLEAR_BH
-#undef     ISSET_BH
-#undef      WORD_BH
-#undef UNALIGNED_BH
-
-
-/*---------------------------------------------*/
-/*--- The main, O(N^2 log(N)) sorting       ---*/
-/*--- algorithm.  Faster for "normal"       ---*/
-/*--- non-repetitive blocks.                ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-__inline__
-Bool mainGtU ( UInt32  i1, 
-               UInt32  i2,
-               UChar*  block, 
-               UInt16* quadrant,
-               UInt32  nblock,
-               Int32*  budget )
-{
-   Int32  k;
-   UChar  c1, c2;
-   UInt16 s1, s2;
-
-   AssertD ( i1 != i2, "mainGtU" );
-   /* 1 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 2 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 3 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 4 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 5 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 6 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 7 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 8 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 9 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 10 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 11 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 12 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-
-   k = nblock + 8;
-
-   do {
-      /* 1 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 2 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 3 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 4 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 5 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 6 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 7 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 8 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-
-      if (i1 >= nblock) i1 -= nblock;
-      if (i2 >= nblock) i2 -= nblock;
-
-      k -= 8;
-      (*budget)--;
-   }
-      while (k >= 0);
-
-   return False;
-}
-
-
-/*---------------------------------------------*/
-/*--
-   Knuth's increments seem to work better
-   than Incerpi-Sedgewick here.  Possibly
-   because the number of elems to sort is
-   usually small, typically <= 20.
---*/
-static
-Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
-                   9841, 29524, 88573, 265720,
-                   797161, 2391484 };
-
-static
-void mainSimpleSort ( UInt32* ptr,
-                      UChar*  block,
-                      UInt16* quadrant,
-                      Int32   nblock,
-                      Int32   lo, 
-                      Int32   hi, 
-                      Int32   d,
-                      Int32*  budget )
-{
-   Int32 i, j, h, bigN, hp;
-   UInt32 v;
-
-   bigN = hi - lo + 1;
-   if (bigN < 2) return;
-
-   hp = 0;
-   while (incs[hp] < bigN) hp++;
-   hp--;
-
-   for (; hp >= 0; hp--) {
-      h = incs[hp];
-
-      i = lo + h;
-      while (True) {
-
-         /*-- copy 1 --*/
-         if (i > hi) break;
-         v = ptr[i];
-         j = i;
-         while ( mainGtU ( 
-                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
-                 ) ) {
-            ptr[j] = ptr[j-h];
-            j = j - h;
-            if (j <= (lo + h - 1)) break;
-         }
-         ptr[j] = v;
-         i++;
-
-         /*-- copy 2 --*/
-         if (i > hi) break;
-         v = ptr[i];
-         j = i;
-         while ( mainGtU ( 
-                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
-                 ) ) {
-            ptr[j] = ptr[j-h];
-            j = j - h;
-            if (j <= (lo + h - 1)) break;
-         }
-         ptr[j] = v;
-         i++;
-
-         /*-- copy 3 --*/
-         if (i > hi) break;
-         v = ptr[i];
-         j = i;
-         while ( mainGtU ( 
-                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
-                 ) ) {
-            ptr[j] = ptr[j-h];
-            j = j - h;
-            if (j <= (lo + h - 1)) break;
-         }
-         ptr[j] = v;
-         i++;
-
-         if (*budget < 0) return;
-      }
-   }
-}
-
-
-/*---------------------------------------------*/
-/*--
-   The following is an implementation of
-   an elegant 3-way quicksort for strings,
-   described in a paper "Fast Algorithms for
-   Sorting and Searching Strings", by Robert
-   Sedgewick and Jon L. Bentley.
---*/
-
-#define mswap(zz1, zz2) \
-   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define mvswap(zzp1, zzp2, zzn)       \
-{                                     \
-   Int32 yyp1 = (zzp1);               \
-   Int32 yyp2 = (zzp2);               \
-   Int32 yyn  = (zzn);                \
-   while (yyn > 0) {                  \
-      mswap(ptr[yyp1], ptr[yyp2]);    \
-      yyp1++; yyp2++; yyn--;          \
-   }                                  \
-}
-
-static 
-__inline__
-UChar mmed3 ( UChar a, UChar b, UChar c )
-{
-   UChar t;
-   if (a > b) { t = a; a = b; b = t; };
-   if (b > c) { 
-      b = c;
-      if (a > b) b = a;
-   }
-   return b;
-}
-
-#define mmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
-                          stackHi[sp] = hz; \
-                          stackD [sp] = dz; \
-                          sp++; }
-
-#define mpop(lz,hz,dz) { sp--;             \
-                         lz = stackLo[sp]; \
-                         hz = stackHi[sp]; \
-                         dz = stackD [sp]; }
-
-
-#define mnextsize(az) (nextHi[az]-nextLo[az])
-
-#define mnextswap(az,bz)                                        \
-   { Int32 tz;                                                  \
-     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
-     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
-     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
-
-
-#define MAIN_QSORT_SMALL_THRESH 20
-#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
-#define MAIN_QSORT_STACK_SIZE 100
-
-static
-void mainQSort3 ( UInt32* ptr,
-                  UChar*  block,
-                  UInt16* quadrant,
-                  Int32   nblock,
-                  Int32   loSt, 
-                  Int32   hiSt, 
-                  Int32   dSt,
-                  Int32*  budget )
-{
-   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
-   Int32 sp, lo, hi, d;
-
-   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
-   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
-   Int32 stackD [MAIN_QSORT_STACK_SIZE];
-
-   Int32 nextLo[3];
-   Int32 nextHi[3];
-   Int32 nextD [3];
-
-   sp = 0;
-   mpush ( loSt, hiSt, dSt );
-
-   while (sp > 0) {
-
-      AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
-
-      mpop ( lo, hi, d );
-      if (hi - lo < MAIN_QSORT_SMALL_THRESH || 
-          d > MAIN_QSORT_DEPTH_THRESH) {
-         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
-         if (*budget < 0) return;
-         continue;
-      }
-
-      med = (Int32) 
-            mmed3 ( block[ptr[ lo         ]+d],
-                    block[ptr[ hi         ]+d],
-                    block[ptr[ (lo+hi)>>1 ]+d] );
-
-      unLo = ltLo = lo;
-      unHi = gtHi = hi;
-
-      while (True) {
-         while (True) {
-            if (unLo > unHi) break;
-            n = ((Int32)block[ptr[unLo]+d]) - med;
-            if (n == 0) { 
-               mswap(ptr[unLo], ptr[ltLo]); 
-               ltLo++; unLo++; continue; 
-            };
-            if (n >  0) break;
-            unLo++;
-         }
-         while (True) {
-            if (unLo > unHi) break;
-            n = ((Int32)block[ptr[unHi]+d]) - med;
-            if (n == 0) { 
-               mswap(ptr[unHi], ptr[gtHi]); 
-               gtHi--; unHi--; continue; 
-            };
-            if (n <  0) break;
-            unHi--;
-         }
-         if (unLo > unHi) break;
-         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
-      }
-
-      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
-
-      if (gtHi < ltLo) {
-         mpush(lo, hi, d+1 );
-         continue;
-      }
-
-      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
-      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
-
-      n = lo + unLo - ltLo - 1;
-      m = hi - (gtHi - unHi) + 1;
-
-      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
-      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
-      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
-
-      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
-      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
-      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
-
-      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
-      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
-
-      mpush (nextLo[0], nextHi[0], nextD[0]);
-      mpush (nextLo[1], nextHi[1], nextD[1]);
-      mpush (nextLo[2], nextHi[2], nextD[2]);
-   }
-}
-
-#undef mswap
-#undef mvswap
-#undef mpush
-#undef mpop
-#undef mmin
-#undef mnextsize
-#undef mnextswap
-#undef MAIN_QSORT_SMALL_THRESH
-#undef MAIN_QSORT_DEPTH_THRESH
-#undef MAIN_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
-      nblock > N_OVERSHOOT
-      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
-      ((UChar*)block32) [0 .. nblock-1] holds block
-      ptr exists for [0 .. nblock-1]
-
-   Post:
-      ((UChar*)block32) [0 .. nblock-1] holds block
-      All other areas of block32 destroyed
-      ftab [0 .. 65536 ] destroyed
-      ptr [0 .. nblock-1] holds sorted order
-      if (*budget < 0), sorting was abandoned
-*/
-
-#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
-#define SETMASK (1 << 21)
-#define CLEARMASK (~(SETMASK))
-
-static
-void mainSort ( UInt32* ptr, 
-                UChar*  block,
-                UInt16* quadrant, 
-                UInt32* ftab,
-                Int32   nblock,
-                Int32   verb,
-                Int32*  budget )
-{
-   Int32  i, j, k, ss, sb;
-   Int32  runningOrder[256];
-   Bool   bigDone[256];
-   Int32  copyStart[256];
-   Int32  copyEnd  [256];
-   UChar  c1;
-   Int32  numQSorted;
-   UInt16 s;
-   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
-
-   /*-- set up the 2-byte frequency table --*/
-   for (i = 65536; i >= 0; i--) ftab[i] = 0;
-
-   j = block[0] << 8;
-   i = nblock-1;
-   for (; i >= 3; i -= 4) {
-      quadrant[i] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
-      ftab[j]++;
-      quadrant[i-1] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
-      ftab[j]++;
-      quadrant[i-2] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
-      ftab[j]++;
-      quadrant[i-3] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
-      ftab[j]++;
-   }
-   for (; i >= 0; i--) {
-      quadrant[i] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
-      ftab[j]++;
-   }
-
-   /*-- (emphasises close relationship of block & quadrant) --*/
-   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
-      block   [nblock+i] = block[i];
-      quadrant[nblock+i] = 0;
-   }
-
-   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
-
-   /*-- Complete the initial radix sort --*/
-   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
-
-   s = block[0] << 8;
-   i = nblock-1;
-   for (; i >= 3; i -= 4) {
-      s = (s >> 8) | (block[i] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i;
-      s = (s >> 8) | (block[i-1] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i-1;
-      s = (s >> 8) | (block[i-2] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i-2;
-      s = (s >> 8) | (block[i-3] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i-3;
-   }
-   for (; i >= 0; i--) {
-      s = (s >> 8) | (block[i] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i;
-   }
-
-   /*--
-      Now ftab contains the first loc of every small bucket.
-      Calculate the running order, from smallest to largest
-      big bucket.
-   --*/
-   for (i = 0; i <= 255; i++) {
-      bigDone     [i] = False;
-      runningOrder[i] = i;
-   }
-
-   {
-      Int32 vv;
-      Int32 h = 1;
-      do h = 3 * h + 1; while (h <= 256);
-      do {
-         h = h / 3;
-         for (i = h; i <= 255; i++) {
-            vv = runningOrder[i];
-            j = i;
-            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
-               runningOrder[j] = runningOrder[j-h];
-               j = j - h;
-               if (j <= (h - 1)) goto zero;
+            res = (void *) PAGE_ADDR(i, j);
+            goto found;
+        }
+        page_unmap (pg_get_cr3 (), page);
+    }
+
+    /* Pass 2: find an unallocated table, allocate it and return the first entry of the table */
+    for (i = 0; i < PG_DIR_ENTRIES; i++)
+    {
+        if (((pg_entry_t) pg_dir[i]) & PG_DIR_PRESENT)
+        {
+            continue;
+        }
+
+        page_table_alloc (pg_dir, i);
+        page = page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(pg_dir[i]));
+        res = (void *) PAGE_ADDR(i, 0);
+        p = (pg_entry_t *) page;
+        goto found;
+    }
+
+    return NULL;
+
+found:
+    *p |= PG_TABLE_ALLOC;
+    page_unmap (pg_get_cr3 (), page);
+    return res;
+}
+
+
+int page_bits (pg_entry_t **pg_dir, void *page, int mask)
+{
+    void *pg;
+    int used = 0;
+    pg_entry_t *p = pg_dir[PAGE_DIR(page)];
+
+    if (!(((pg_entry_t) p) & PG_DIR_PRESENT))
+    {
+        return 0;
+    }
+
+    pg = page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+    p = (pg_entry_t *) pg;
+    if (p[PAGE_TABLE(page)] & mask)
+    {
+        used = 1;
+    }
+
+    page_unmap (pg_get_cr3 (), pg);
+    return used;
+}
+
+int page_used (pg_entry_t **pg_dir, void *page)
+{
+    return page_bits (pg_dir, page, PG_TABLE_PRESENT);
+}
+
+void page_dump (pg_entry_t **pg_dir, void *page, char *str)
+{
+    void *pg;
+    pg_entry_t *p = pg_dir[PAGE_DIR(page)];
+
+    if (!(((pg_entry_t) p) & PG_DIR_PRESENT))
+    {
+        panic ("page_dump(): associated page table is empty");
+    }
+
+    pg = page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+    p = (pg_entry_t *) pg;
+
+    sprintf (str, "Page address 0x%.8x, Directory at 0x%.8x, Table #%d, Entry %d, Addr: 0x%.8x Value: 0x%.8x",
+             (uint32_t) page,
+             (uint32_t) pg_dir,
+             PAGE_DIR(page),
+             PAGE_TABLE(page),
+             (uint32_t) &p[PAGE_TABLE(page)],
+             (uint32_t) p[PAGE_TABLE(page)]);
+
+    page_unmap (pg_get_cr3 (), pg);
+}
+
+void *page_addr (pg_entry_t **pg_dir, void *page)
+{
+    pg_entry_t *p;
+    void *phys_page;
+
+    /* First meg is identically mapped */
+    if (page < (void *) DYNAMIC_RAM_OFFSET)
+    {
+        return page;
+    }
+
+    p = pg_dir[PAGE_DIR(page)];
+    if (!(((pg_entry_t) p) & PG_DIR_PRESENT))
+    {
+        panic ("page_addr(): trying to get address of non present page (empty l2 entry)");
+    }
+
+    p = (pg_entry_t *) PG_ENTRY_TO_ADDR (p);
+    p = (pg_entry_t *) page_map_any (pg_get_cr3 (), p);
+
+    if (!(p[PAGE_TABLE(page)] & PG_TABLE_PRESENT))
+    {
+        panic ("page_addr(): trying to get address of non present page (empty l1 entry)");
+    }
+
+    phys_page = (void *) (p[PAGE_TABLE(page)] & PG_TABLE_ADDR);
+
+    page_unmap (pg_get_cr3 (), p);
+
+    return phys_page;
+}
+
+void page_free (pg_entry_t **pg_dir, void *page)
+{
+    pg_entry_t *p;
+    void *phys_page;
+
+    if (! page_used (pg_dir, page))
+        panic ("page_free(): trying to free free page");
+
+    p = (pg_entry_t *) PG_ENTRY_TO_ADDR(pg_dir[PAGE_DIR(page)]);
+    p = (pg_entry_t *) page_map_any (pg_get_cr3 (), p);
+
+    phys_page = (void *) (p[PAGE_TABLE(page)] & PG_TABLE_ADDR);
+    p[PAGE_TABLE(page)] &= ~(PG_TABLE_PRESENT);        /* Clear present bit */
+    flush_tlb (page);
+    rbmap_free (phys_page);                    /* Free associated physical page */
+
+    page_unmap (pg_get_cr3 (), p);
+}
+
+int page_alloc (pg_entry_t **pg_dir, void *virt_page)
+{
+    return page_alloc_flags (pg_dir, virt_page, NULL, 0);
+}
+
+int page_alloc2 (pg_entry_t **pg_dir, void *virt_page, void **phys_page)
+{
+    return page_alloc_flags (pg_dir, virt_page, phys_page, 0);
+}
+
+int page_alloc_flags (pg_entry_t **pg_dir, void *virt_page, void **phys_page, int flags)
+{
+    void *page = NULL;
+
+    if (page_bits (pg_dir, virt_page, PG_TABLE_PRESENT) != 0)
+    {
+        return -1;
+    }
+
+    page = rbmap_alloc_any ();
+
+    if (page_link (pg_dir, page, virt_page, flags) != 0)
+    {
+        rbmap_free (page);
+        return -1;
+    }
+
+    if (phys_page != 0)
+    {
+        *phys_page = page;
+    }
+
+    return 0;
+}
+
+void *page_alloc_any (pg_entry_t **pg_dir, void **phys_page)
+{
+    return page_alloc_any_flags (pg_dir, phys_page, 0);
+}
+
+void *page_alloc_any_flags (pg_entry_t **pg_dir, void **phys_page, int flags)
+{
+    void *virt_page = NULL;
+    void *new_phys_page = NULL;
+
+    new_phys_page = rbmap_alloc_any ();
+
+    while (! virt_page)
+    {
+        if (! (virt_page = page_find_free (pg_dir)))
+        {
+            panic ("page_alloc_any(): no more virtual addresses available");
+        }
+        if (page_link (pg_dir, new_phys_page, virt_page, flags))
+        {
+            virt_page = NULL;
+        }
+    }
+
+    if (phys_page)
+        *phys_page = new_phys_page;
+
+    return virt_page;
+}
+
+void *page_id_alloc (pg_entry_t **pg_dir)
+{
+    /* XXX: We are using e820 map here. This makes mm arch dependent */
+    int i;
+
+    for (i = 0; i < minfo.map.n_entries; i++) {
+        uint32_t beg, end;
+
+        if (minfo.map.entries[i].type != E820_RAM)
+            continue;
+
+        /* XXX: Casting 64 bit integers to 32 bits integer may no be safe */
+        beg = (uint32_t) minfo.map.entries[i].start;
+        end = beg + (uint32_t) minfo.map.entries[i].size;
+
+        /* Round up to page size */
+        beg = ((beg / PAGE_SIZE) + 1) * PAGE_SIZE;
+        end = (end / PAGE_SIZE) * PAGE_SIZE;
+
+        while (beg < end) {
+            if (rbmap_is_free ((void *) beg) && !page_used (pg_dir, (void *) beg)) {
+                if (!rbmap_alloc ((void *) beg)) {
+                    if (!page_link (pg_dir, (void *) beg, (void *) beg, 0))
+                        return ((void *) beg);
+                    else
+                        rbmap_free ((void *) beg);
+                }
             }
-            zero:
-            runningOrder[j] = vv;
-         }
-      } while (h != 1);
-   }
-
-   /*--
-      The main sorting loop.
-   --*/
-
-   numQSorted = 0;
-
-   for (i = 0; i <= 255; i++) {
-
-      /*--
-         Process big buckets, starting with the least full.
-         Basically this is a 3-step process in which we call
-         mainQSort3 to sort the small buckets [ss, j], but
-         also make a big effort to avoid the calls if we can.
-      --*/
-      ss = runningOrder[i];
-
-      /*--
-         Step 1:
-         Complete the big bucket [ss] by quicksorting
-         any unsorted small buckets [ss, j], for j != ss.  
-         Hopefully previous pointer-scanning phases have already
-         completed many of the small buckets [ss, j], so
-         we don't have to sort them at all.
-      --*/
-      for (j = 0; j <= 255; j++) {
-         if (j != ss) {
-            sb = (ss << 8) + j;
-            if ( ! (ftab[sb] & SETMASK) ) {
-               Int32 lo = ftab[sb]   & CLEARMASK;
-               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
-               if (hi > lo) {
-                  if (verb >= 4)
-                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
-                                "done %d   this %d\n",
-                                ss, j, numQSorted, hi - lo + 1 );
-                  mainQSort3 ( 
-                     ptr, block, quadrant, nblock, 
-                     lo, hi, BZ_N_RADIX, budget 
-                  );   
-                  numQSorted += (hi - lo + 1);
-                  if (*budget < 0) return;
-               }
+            beg += PAGE_SIZE;
+        }
+    }
+
+    return NULL;
+}
+
+
+int page_share (pg_entry_t **src_pg_dir, void *src_page, pg_entry_t **dest_pg_dir, void *dest_page)
+{
+    void *phys_page;
+    pg_entry_t *p;
+
+    p = src_pg_dir[PAGE_DIR(src_page)];
+
+    if (! (((pg_entry_t) p) & PG_DIR_PRESENT))
+        panic ("page_share(): trying to share non-existent virtual page");
+    p = (pg_entry_t *) page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+
+    if (! (p[PAGE_TABLE(src_page)] & PG_TABLE_PRESENT))
+        panic ("page_share(): trying to share non-existent virtual page");
+
+    phys_page = (void *) PG_ENTRY_TO_ADDR(p[PAGE_TABLE(src_page)]);
+
+    /* Ok we got physical page */
+    if (rbmap_share (phys_page))
+        panic ("page_share(): trying to share non-allocated physical page");
+
+    if (page_link (dest_pg_dir, phys_page, dest_page, 0)) {
+        rbmap_unshare (phys_page);
+        page_unmap (pg_get_cr3 (), p);
+        return -1;
+    }
+
+    /* Set shared pages read-only */
+    page_rm_flags (src_pg_dir, src_page, PG_TABLE_RW);
+    page_rm_flags (dest_pg_dir, dest_page, PG_TABLE_RW);
+
+    page_unmap (pg_get_cr3 (), p);
+
+    return 0;
+}
+
+
+void *page_share_any (pg_entry_t **src_pg_dir, void *src_page, pg_entry_t **dest_pg_dir)
+{
+    void *phys_page;
+    void *dest_page = NULL;
+    pg_entry_t *p;
+
+    p = src_pg_dir[PAGE_DIR(src_page)];
+
+    if (! (((pg_entry_t) p) & PG_DIR_PRESENT))
+        panic ("page_share(): trying to share non-existent virtual page");
+    p = (pg_entry_t *) page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR(p));
+
+    if (! (p[PAGE_TABLE(src_page)] & PG_TABLE_PRESENT))
+        panic ("page_share(): trying to share non-existent virtual page");
+
+    phys_page = (void *) PG_ENTRY_TO_ADDR(p[PAGE_TABLE(src_page)]);
+
+    /* Ok we got physical page */
+    if (rbmap_share (phys_page))
+        panic ("page_share(): trying to share non-allocated physical page");
+
+    while (!dest_page) {
+        if (! (dest_page = page_find_free (dest_pg_dir)))
+            panic ("page_share_any(): no more virtual addresses available");
+        if (page_link (dest_pg_dir, phys_page, dest_page, 0))
+            dest_page = NULL;
+    }
+
+    /* Set shared pages read-only */
+    page_rm_flags (src_pg_dir, src_page, PG_TABLE_RW);
+    page_rm_flags (dest_pg_dir, dest_page, PG_TABLE_RW);
+
+    page_unmap (pg_get_cr3 (), p);
+
+    return dest_page;
+}
+
+
+void page_unshare (pg_entry_t **pg_dir, void *page)
+{
+    void *phys_page = page_addr (pg_dir, page);
+
+    page_unmap (pg_dir, page);
+
+    rbmap_unshare (phys_page);
+}
+
+int page_map (pg_entry_t **pg_dir, void *phys_page, void *virt_page)
+{
+    return page_link (pg_dir, phys_page, virt_page, 0);
+}
+
+void *page_map_any (pg_entry_t **pg_dir, void *page)
+{
+    uint32_t virt_page = (uint32_t) PG_MAP_CACHE_ADDR;
+    pg_entry_t *p = NULL;
+
+    /* First MB is identically mapped */
+    if (page < (void *) DYNAMIC_RAM_OFFSET)
+        return page;
+
+    if (!last_mapped_page)  {
+        p = page_map_cache;
+        *p = 0;
+    }
+    else {
+        pg_entry_t e, mask, *free = NULL;
+
+        e = ((pg_entry_t) page) | PG_TABLE_CACHE | PG_TABLE_RW | PG_TABLE_PRESENT;
+        mask = PG_TABLE_ADDR | PG_TABLE_CACHE | PG_TABLE_RW | PG_TABLE_PRESENT;
+
+        for (p = last_mapped_page; p >= page_map_cache; p--) {
+            if ((*p & mask) == e) {
+                virt_page += ((uint32_t) (p - page_map_cache)) << PAGE_SIZE_LOG;
+                goto mark;
             }
-            ftab[sb] |= SETMASK;
-         }
-      }
-
-      AssertH ( !bigDone[ss], 1006 );
-
-      /*--
-         Step 2:
-         Now scan this big bucket [ss] so as to synthesise the
-         sorted order for small buckets [t, ss] for all t,
-         including, magically, the bucket [ss,ss] too.
-         This will avoid doing Real Work in subsequent Step 1's.
-      --*/
-      {
-         for (j = 0; j <= 255; j++) {
-            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
-            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
-         }
-         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
-            k = ptr[j]-1; if (k < 0) k += nblock;
-            c1 = block[k];
-            if (!bigDone[c1])
-               ptr[ copyStart[c1]++ ] = k;
-         }
-         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
-            k = ptr[j]-1; if (k < 0) k += nblock;
-            c1 = block[k];
-            if (!bigDone[c1]) 
-               ptr[ copyEnd[c1]-- ] = k;
-         }
-      }
-
-      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
-                || 
-                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
-                   Necessity for this case is demonstrated by compressing 
-                   a sequence of approximately 48.5 million of character 
-                   251; 1.0.0/1.0.1 will then die here. */
-                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
-                1007 )
-
-      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
-
-      /*--
-         Step 3:
-         The [ss] big bucket is now done.  Record this fact,
-         and update the quadrant descriptors.  Remember to
-         update quadrants in the overshoot area too, if
-         necessary.  The "if (i < 255)" test merely skips
-         this updating for the last bucket processed, since
-         updating for the last bucket is pointless.
-
-         The quadrant array provides a way to incrementally
-         cache sort orderings, as they appear, so as to 
-         make subsequent comparisons in fullGtU() complete
-         faster.  For repetitive blocks this makes a big
-         difference (but not big enough to be able to avoid
-         the fallback sorting mechanism, exponential radix sort).
-
-         The precise meaning is: at all times:
-
-            for 0 <= i < nblock and 0 <= j <= nblock
-
-            if block[i] != block[j], 
-
-               then the relative values of quadrant[i] and 
-                    quadrant[j] are meaningless.
-
-               else {
-                  if quadrant[i] < quadrant[j]
-                     then the string starting at i lexicographically
-                     precedes the string starting at j
-
-                  else if quadrant[i] > quadrant[j]
-                     then the string starting at j lexicographically
-                     precedes the string starting at i
-
-                  else
-                     the relative ordering of the strings starting
-                     at i and j has not yet been determined.
-               }
-      --*/
-      bigDone[ss] = True;
-
-      if (i < 255) {
-         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
-         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
-         Int32 shifts   = 0;
-
-         while ((bbSize >> shifts) > 65534) shifts++;
-
-         for (j = bbSize-1; j >= 0; j--) {
-            Int32 a2update     = ptr[bbStart + j];
-            UInt16 qVal        = (UInt16)(j >> shifts);
-            quadrant[a2update] = qVal;
-            if (a2update < BZ_N_OVERSHOOT)
-               quadrant[a2update + nblock] = qVal;
-         }
-         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
-      }
-
-   }
-
-   if (verb >= 4)
-      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
-                 nblock, numQSorted, nblock - numQSorted );
-}
-
-#undef BIGFREQ
-#undef SETMASK
-#undef CLEARMASK
-
-
-/*---------------------------------------------*/
-/* Pre:
-      nblock > 0
-      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
-      ((UChar*)arr2)  [0 .. nblock-1] holds block
-      arr1 exists for [0 .. nblock-1]
-
-   Post:
-      ((UChar*)arr2) [0 .. nblock-1] holds block
-      All other areas of block destroyed
-      ftab [ 0 .. 65536 ] destroyed
-      arr1 [0 .. nblock-1] holds sorted order
-*/
-void BZ2_blockSort ( EState* s )
-{
-   UInt32* ptr    = s->ptr; 
-   UChar*  block  = s->block;
-   UInt32* ftab   = s->ftab;
-   Int32   nblock = s->nblock;
-   Int32   verb   = s->verbosity;
-   Int32   wfact  = s->workFactor;
-   UInt16* quadrant;
-   Int32   budget;
-   Int32   budgetInit;
-   Int32   i;
-
-   if (nblock < 10000) {
-      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
-   } else {
-      /* Calculate the location for quadrant, remembering to get
-         the alignment right.  Assumes that &(block[0]) is at least
-         2-byte aligned -- this should be ok since block is really
-         the first section of arr2.
-      */
-      i = nblock+BZ_N_OVERSHOOT;
-      if (i & 1) i++;
-      quadrant = (UInt16*)(&(block[i]));
-
-      /* (wfact-1) / 3 puts the default-factor-30
-         transition point at very roughly the same place as 
-         with v0.1 and v0.9.0.  
-         Not that it particularly matters any more, since the
-         resulting compressed stream is now the same regardless
-         of whether or not we use the main sort or fallback sort.
-      */
-      if (wfact < 1  ) wfact = 1;
-      if (wfact > 100) wfact = 100;
-      budgetInit = nblock * ((wfact-1) / 3);
-      budget = budgetInit;
-
-      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
-      if (verb >= 3) 
-         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
-                    budgetInit - budget,
-                    nblock, 
-                    (float)(budgetInit - budget) /
-                    (float)(nblock==0 ? 1 : nblock) ); 
-      if (budget < 0) {
-         if (verb >= 2) 
-            VPrintf0 ( "    too repetitive; using fallback"
-                       " sorting algorithm\n" );
-         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
-      }
-   }
-
-   s->origPtr = -1;
-   for (i = 0; i < s->nblock; i++)
-      if (ptr[i] == 0)
-         { s->origPtr = i; break; };
-
-   AssertH( s->origPtr != -1, 1003 );
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                       blocksort.c ---*/
-/*-------------------------------------------------------------*/
+            else if (!free && !(*p & PG_TABLE_PRESENT))
+                free = p;
+        }
+        for (p = page_map_cache + PG_TABLE_ENTRIES; p > last_mapped_page; p--) {
+            if ((*p & mask) == e) {
+                virt_page += ((uint32_t) (p - page_map_cache)) << PAGE_SIZE_LOG;
+                goto mark;
+            }
+            else if (!free && !(*p & PG_TABLE_PRESENT))
+                free = p;
+        }
+
+        p = free;
+        if (!p)
+            for (p = page_map_cache; p < page_map_cache + PG_TABLE_ENTRIES; p++)
+                if (*p & PG_TABLE_CACHE)
+                    break;
+        if (!p)
+            panic ("page_map_any(): page mapping cache is full");
+
+        virt_page += ((uint32_t) (p - page_map_cache)) << PAGE_SIZE_LOG;
+        *p = 0;
+    }
+
+mark:
+
+    *p &= ~(PG_TABLE_CACHE);
+
+    if (*p == 0) {
+        *p = PG_TABLE_PRESENT | PG_TABLE_ALLOC | PG_TABLE_RW;
+        *p |= ((pg_entry_t ) page) & PG_TABLE_ADDR;
+        flush_tlb ((void *) virt_page);
+    }
+
+    last_mapped_page = p;
+    return (void *) virt_page;
+}
+
+
+void page_unmap (pg_entry_t **pg_dir, void *page)
+{
+    pg_entry_t *p;
+    void *phys_page;
+
+    /* First MB is identically mapped */
+    if (page < (void *) DYNAMIC_RAM_OFFSET)
+        return;
+
+    if (page >= (void *) PG_MAP_CACHE_ADDR && page < (void *) (PG_MAP_CACHE_ADDR + PAGE_SIZE)) {
+        /* Page in cache */
+        pg_entry_t *p = page_map_cache;
+
+        p += (int) PAGE_TABLE (page);
+
+        if (! (*p & PG_TABLE_PRESENT))
+            panic ("page_unmap(): trying to unmap unused page");
+        else    /* Set cache bit */
+            *p |= PG_TABLE_CACHE;
+    }
+    else {
+        if (! page_used (pg_dir, page))
+            panic ("page_unmap(): trying to unmap unused page");
+
+        p = (pg_entry_t *) PG_ENTRY_TO_ADDR(pg_dir[PAGE_DIR(page)]);
+
+        p = (pg_entry_t *) page_map_any (pg_get_cr3(), p);
+
+        phys_page = (void *) (p[PAGE_TABLE(page)] & PG_TABLE_ADDR);
+        p[PAGE_TABLE(page)] &= ~(PG_TABLE_PRESENT);        /* Clear present bit */
+        flush_tlb (page);
+
+        page_unmap (pg_get_cr3(), p);
+
+        if (page_table_empty (pg_dir, PAGE_DIR(page)))
+            page_table_free (pg_dir, PAGE_DIR(page));
+    }
+}
+
+
+void page_flush (pg_entry_t **pg_dir)
+{
+    int i;
+    int j;
+    pg_entry_t *p;
+
+    for (i = 0; i < PG_DIR_ENTRIES; i++) {
+        if (! (((pg_entry_t) pg_dir[i]) & PG_DIR_PRESENT))
+            continue;
+        p = (pg_entry_t *) page_map_any (pg_get_cr3 (), (void *) PG_ENTRY_TO_ADDR (pg_dir[i]));
+        for (j = 0; j < PG_TABLE_ENTRIES; j++) {
+            void * addr = (void *) PG_ENTRY_TO_ADDR (p[j]);
+            if (p[j] & PG_TABLE_PRESENT) {
+                if (addr >= (void *) DYNAMIC_RAM_OFFSET)
+                    rbmap_free ((void *) addr);
+                p[j] &= ~(PG_TABLE_PRESENT);
+            }
+        }
+        page_unmap (pg_get_cr3(), p);
+        page_table_free (pg_dir, i);
+    }
+}
+
+void paging_init (void)
+{
+    pg_entry_t **pg_dir = (pg_entry_t **) KERNEL_PG_DIR;
+
+    page_zerofill (pg_dir);
+    page_zerofill ((void *) KERNEL_PG_TABLE0);
+
+    /* C version didn't work so I switch to assembly ;)) */
+    pg_table_linear_fill ((pg_entry_t *) (KERNEL_PG_TABLE0), 0,
+                          PG_TABLE_RW | PG_TABLE_PRESENT,
+                          KERNEL_ID_PAGES);
+
+    pg_dir[0] = (pg_entry_t *) ((unsigned int)KERNEL_PG_TABLE0 | PG_DIR_RW | PG_DIR_PRESENT);
+
+    /* Page Mapping cache */
+    memset4 ((void *) KERNEL_PG_MAP_CACHE, PG_TABLE_ALLOC, PG_TABLE_ENTRIES);
+    pg_dir[PG_MAP_CACHE_DIR] = (pg_entry_t *) ((unsigned int)KERNEL_PG_MAP_CACHE | PG_DIR_RW | PG_DIR_PRESENT);
+    page_map_cache = (pg_entry_t *) KERNEL_PG_MAP_CACHE;
+}
+
+void mm_init (void)
+{
+    /*    if (cpuinfos.x86 > 3)
+        flush_tlb = flush_one_tlb;
+        else */
+    flush_tlb = (void (*) (void *)) flush_all_tlb;
+}
+
+void Pagination(multiboot_info_t * mbi)
+{
+    /* Retreive multiboot given memory info */
+    e820_map_init (mbi);
+
+    /* Initialize la table d'occupation de la RAM */
+    rbmap_init ();
+
+    /* Initialize la pagination */
+    paging_init ();
+}
+
+#endif
+
main/kernel/lib/libbz2/compress.c to main/kernel/mm/x86_32/memzone.c
--- a/main/kernel/lib/libbz2/compress.c
+++ b/main/kernel/mm/x86_32/memzone.c
@@ -1,714 +1,372 @@
-
-/*-------------------------------------------------------------*/
-/*--- Compression machinery (not incl block sorting)        ---*/
-/*---                                            compress.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward@acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
-
-/*--
-   CHANGES
-   ~~~~~~~
-   0.9.0 -- original version.
-
-   0.9.0a/b -- no changes in this file.
-
-   0.9.0c
-      * changed setting of nGroups in sendMTFValues() so as to 
-        do a bit better on small files
---*/
-
-#include "bzlib_private.h"
-
-
-/*---------------------------------------------------*/
-/*--- Bit stream I/O                              ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-void BZ2_bsInitWrite ( EState* s )
-{
-   s->bsLive = 0;
-   s->bsBuff = 0;
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsFinishWrite ( EState* s )
-{
-   while (s->bsLive > 0) {
-      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
-      s->numZ++;
-      s->bsBuff <<= 8;
-      s->bsLive -= 8;
-   }
-}
-
-
-/*---------------------------------------------------*/
-#define bsNEEDW(nz)                           \
-{                                             \
-   while (s->bsLive >= 8) {                   \
-      s->zbits[s->numZ]                       \
-         = (UChar)(s->bsBuff >> 24);          \
-      s->numZ++;                              \
-      s->bsBuff <<= 8;                        \
-      s->bsLive -= 8;                         \
-   }                                          \
-}
-
-
-/*---------------------------------------------------*/
-static
-__inline__
-void bsW ( EState* s, Int32 n, UInt32 v )
-{
-   bsNEEDW ( n );
-   s->bsBuff |= (v << (32 - s->bsLive - n));
-   s->bsLive += n;
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsPutUInt32 ( EState* s, UInt32 u )
-{
-   bsW ( s, 8, (u >> 24) & 0xffL );
-   bsW ( s, 8, (u >> 16) & 0xffL );
-   bsW ( s, 8, (u >>  8) & 0xffL );
-   bsW ( s, 8,  u        & 0xffL );
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsPutUChar ( EState* s, UChar c )
-{
-   bsW( s, 8, (UInt32)c );
-}
-
-
-/*---------------------------------------------------*/
-/*--- The back end proper                         ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-static
-void makeMaps_e ( EState* s )
-{
-   Int32 i;
-   s->nInUse = 0;
-   for (i = 0; i < 256; i++)
-      if (s->inUse[i]) {
-         s->unseqToSeq[i] = s->nInUse;
-         s->nInUse++;
-      }
-}
-
-
-/*---------------------------------------------------*/
-static
-void generateMTFValues ( EState* s )
-{
-   UChar   yy[256];
-   Int32   i, j;
-   Int32   zPend;
-   Int32   wr;
-   Int32   EOB;
-
-   /* 
-      After sorting (eg, here),
-         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
-         and
-         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 
-         holds the original block data.
-
-      The first thing to do is generate the MTF values,
-      and put them in
-         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
-      Because there are strictly fewer or equal MTF values
-      than block values, ptr values in this area are overwritten
-      with MTF values only when they are no longer needed.
-
-      The final compressed bitstream is generated into the
-      area starting at
-         (UChar*) (&((UChar*)s->arr2)[s->nblock])
-
-      These storage aliases are set up in bzCompressInit(),
-      except for the last one, which is arranged in 
-      compressBlock().
-   */
-   UInt32* ptr   = s->ptr;
-   UChar* block  = s->block;
-   UInt16* mtfv  = s->mtfv;
-
-   makeMaps_e ( s );
-   EOB = s->nInUse+1;
-
-   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
-
-   wr = 0;
-   zPend = 0;
-   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
-
-   for (i = 0; i < s->nblock; i++) {
-      UChar ll_i;
-      AssertD ( wr <= i, "generateMTFValues(1)" );
-      j = ptr[i]-1; if (j < 0) j += s->nblock;
-      ll_i = s->unseqToSeq[block[j]];
-      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
-
-      if (yy[0] == ll_i) { 
-         zPend++;
-      } else {
-
-         if (zPend > 0) {
-            zPend--;
-            while (True) {
-               if (zPend & 1) {
-                  mtfv[wr] = BZ_RUNB; wr++; 
-                  s->mtfFreq[BZ_RUNB]++; 
-               } else {
-                  mtfv[wr] = BZ_RUNA; wr++; 
-                  s->mtfFreq[BZ_RUNA]++; 
-               }
-               if (zPend < 2) break;
-               zPend = (zPend - 2) / 2;
-            };
-            zPend = 0;
-         }
-         {
-            register UChar  rtmp;
-            register UChar* ryy_j;
-            register UChar  rll_i;
-            rtmp  = yy[1];
-            yy[1] = yy[0];
-            ryy_j = &(yy[1]);
-            rll_i = ll_i;
-            while ( rll_i != rtmp ) {
-               register UChar rtmp2;
-               ryy_j++;
-               rtmp2  = rtmp;
-               rtmp   = *ryy_j;
-               *ryy_j = rtmp2;
-            };
-            yy[0] = rtmp;
-            j = ryy_j - &(yy[0]);
-            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
-         }
-
-      }
-   }
-
-   if (zPend > 0) {
-      zPend--;
-      while (True) {
-         if (zPend & 1) {
-            mtfv[wr] = BZ_RUNB; wr++; 
-            s->mtfFreq[BZ_RUNB]++; 
-         } else {
-            mtfv[wr] = BZ_RUNA; wr++; 
-            s->mtfFreq[BZ_RUNA]++; 
-         }
-         if (zPend < 2) break;
-         zPend = (zPend - 2) / 2;
-      };
-      zPend = 0;
-   }
-
-   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
-
-   s->nMTF = wr;
-}
-
-
-/*---------------------------------------------------*/
-#define BZ_LESSER_ICOST  0
-#define BZ_GREATER_ICOST 15
-
-static
-void sendMTFValues ( EState* s )
-{
-   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
-   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
-   Int32 nGroups, nBytes;
-
-   /*--
-   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-   is a global since the decoder also needs it.
-
-   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-   are also globals only used in this proc.
-   Made global to keep stack frame size small.
-   --*/
-
-
-   UInt16 cost[BZ_N_GROUPS];
-   Int32  fave[BZ_N_GROUPS];
-
-   UInt16* mtfv = s->mtfv;
-
-   if (s->verbosity >= 3)
-      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
-                "%d+2 syms in use\n", 
-                s->nblock, s->nMTF, s->nInUse );
-
-   alphaSize = s->nInUse+2;
-   for (t = 0; t < BZ_N_GROUPS; t++)
-      for (v = 0; v < alphaSize; v++)
-         s->len[t][v] = BZ_GREATER_ICOST;
-
-   /*--- Decide how many coding tables to use ---*/
-   AssertH ( s->nMTF > 0, 3001 );
-   if (s->nMTF < 200)  nGroups = 2; else
-   if (s->nMTF < 600)  nGroups = 3; else
-   if (s->nMTF < 1200) nGroups = 4; else
-   if (s->nMTF < 2400) nGroups = 5; else
-                       nGroups = 6;
-
-   /*--- Generate an initial set of coding tables ---*/
-   { 
-      Int32 nPart, remF, tFreq, aFreq;
-
-      nPart = nGroups;
-      remF  = s->nMTF;
-      gs = 0;
-      while (nPart > 0) {
-         tFreq = remF / nPart;
-         ge = gs-1;
-         aFreq = 0;
-         while (aFreq < tFreq && ge < alphaSize-1) {
-            ge++;
-            aFreq += s->mtfFreq[ge];
-         }
-
-         if (ge > gs 
-             && nPart != nGroups && nPart != 1 
-             && ((nGroups-nPart) % 2 == 1)) {
-            aFreq -= s->mtfFreq[ge];
-            ge--;
-         }
-
-         if (s->verbosity >= 3)
-            VPrintf5( "      initial group %d, [%d .. %d], "
-                      "has %d syms (%4.1f%%)\n",
-                      nPart, gs, ge, aFreq, 
-                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
- 
-         for (v = 0; v < alphaSize; v++)
-            if (v >= gs && v <= ge) 
-               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
-               s->len[nPart-1][v] = BZ_GREATER_ICOST;
- 
-         nPart--;
-         gs = ge+1;
-         remF -= aFreq;
-      }
-   }
-
-   /*--- 
-      Iterate up to BZ_N_ITERS times to improve the tables.
-   ---*/
-   for (iter = 0; iter < BZ_N_ITERS; iter++) {
-
-      for (t = 0; t < nGroups; t++) fave[t] = 0;
-
-      for (t = 0; t < nGroups; t++)
-         for (v = 0; v < alphaSize; v++)
-            s->rfreq[t][v] = 0;
-
-      /*---
-        Set up an auxiliary length table which is used to fast-track
-	the common case (nGroups == 6). 
-      ---*/
-      if (nGroups == 6) {
-         for (v = 0; v < alphaSize; v++) {
-            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
-            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
-            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
-	 }
-      }
-
-      nSelectors = 0;
-      totc = 0;
-      gs = 0;
-      while (True) {
-
-         /*--- Set group start & end marks. --*/
-         if (gs >= s->nMTF) break;
-         ge = gs + BZ_G_SIZE - 1; 
-         if (ge >= s->nMTF) ge = s->nMTF-1;
-
-         /*-- 
-            Calculate the cost of this group as coded
-            by each of the coding tables.
-         --*/
-         for (t = 0; t < nGroups; t++) cost[t] = 0;
-
-         if (nGroups == 6 && 50 == ge-gs+1) {
-            /*--- fast track the common case ---*/
-            register UInt32 cost01, cost23, cost45;
-            register UInt16 icv;
-            cost01 = cost23 = cost45 = 0;
-
-#           define BZ_ITER(nn)                \
-               icv = mtfv[gs+(nn)];           \
-               cost01 += s->len_pack[icv][0]; \
-               cost23 += s->len_pack[icv][1]; \
-               cost45 += s->len_pack[icv][2]; \
-
-            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
-            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
-            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
-            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
-            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
-            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
-            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
-            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
-            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
-            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
-
-#           undef BZ_ITER
-
-            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
-            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
-            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
-
-         } else {
-	    /*--- slow version which correctly handles all situations ---*/
-            for (i = gs; i <= ge; i++) { 
-               UInt16 icv = mtfv[i];
-               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
-            }
-         }
- 
-         /*-- 
-            Find the coding table which is best for this group,
-            and record its identity in the selector table.
-         --*/
-         bc = 999999999; bt = -1;
-         for (t = 0; t < nGroups; t++)
-            if (cost[t] < bc) { bc = cost[t]; bt = t; };
-         totc += bc;
-         fave[bt]++;
-         s->selector[nSelectors] = bt;
-         nSelectors++;
-
-         /*-- 
-            Increment the symbol frequencies for the selected table.
-          --*/
-         if (nGroups == 6 && 50 == ge-gs+1) {
-            /*--- fast track the common case ---*/
-
-#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
-
-            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
-            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
-            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
-            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
-            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
-            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
-            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
-            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
-            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
-            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
-
-#           undef BZ_ITUR
-
-         } else {
-	    /*--- slow version which correctly handles all situations ---*/
-            for (i = gs; i <= ge; i++)
-               s->rfreq[bt][ mtfv[i] ]++;
-         }
-
-         gs = ge+1;
-      }
-      if (s->verbosity >= 3) {
-         VPrintf2 ( "      pass %d: size is %d, grp uses are ", 
-                   iter+1, totc/8 );
-         for (t = 0; t < nGroups; t++)
-            VPrintf1 ( "%d ", fave[t] );
-         VPrintf0 ( "\n" );
-      }
-
-      /*--
-        Recompute the tables based on the accumulated frequencies.
-      --*/
-      for (t = 0; t < nGroups; t++)
-         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
-                                 alphaSize, 20 );
-   }
-
-
-   AssertH( nGroups < 8, 3002 );
-   AssertH( nSelectors < 32768 &&
-            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
-            3003 );
-
-
-   /*--- Compute MTF values for the selectors. ---*/
-   {
-      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
-      for (i = 0; i < nGroups; i++) pos[i] = i;
-      for (i = 0; i < nSelectors; i++) {
-         ll_i = s->selector[i];
-         j = 0;
-         tmp = pos[j];
-         while ( ll_i != tmp ) {
-            j++;
-            tmp2 = tmp;
-            tmp = pos[j];
-            pos[j] = tmp2;
-         };
-         pos[0] = tmp;
-         s->selectorMtf[i] = j;
-      }
-   };
-
-   /*--- Assign actual codes for the tables. --*/
-   for (t = 0; t < nGroups; t++) {
-      minLen = 32;
-      maxLen = 0;
-      for (i = 0; i < alphaSize; i++) {
-         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
-         if (s->len[t][i] < minLen) minLen = s->len[t][i];
-      }
-      AssertH ( !(maxLen > 20), 3004 );
-      AssertH ( !(minLen < 1),  3005 );
-      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
-                          minLen, maxLen, alphaSize );
-   }
-
-   /*--- Transmit the mapping table. ---*/
-   { 
-      Bool inUse16[16];
-      for (i = 0; i < 16; i++) {
-          inUse16[i] = False;
-          for (j = 0; j < 16; j++)
-             if (s->inUse[i * 16 + j]) inUse16[i] = True;
-      }
-     
-      nBytes = s->numZ;
-      for (i = 0; i < 16; i++)
-         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
-
-      for (i = 0; i < 16; i++)
-         if (inUse16[i])
-            for (j = 0; j < 16; j++) {
-               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
-            }
-
-      if (s->verbosity >= 3) 
-         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
-   }
-
-   /*--- Now the selectors. ---*/
-   nBytes = s->numZ;
-   bsW ( s, 3, nGroups );
-   bsW ( s, 15, nSelectors );
-   for (i = 0; i < nSelectors; i++) { 
-      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
-      bsW(s,1,0);
-   }
-   if (s->verbosity >= 3)
-      VPrintf1( "selectors %d, ", s->numZ-nBytes );
-
-   /*--- Now the coding tables. ---*/
-   nBytes = s->numZ;
-
-   for (t = 0; t < nGroups; t++) {
-      Int32 curr = s->len[t][0];
-      bsW ( s, 5, curr );
-      for (i = 0; i < alphaSize; i++) {
-         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
-         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
-         bsW ( s, 1, 0 );
-      }
-   }
-
-   if (s->verbosity >= 3)
-      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
-
-   /*--- And finally, the block data proper ---*/
-   nBytes = s->numZ;
-   selCtr = 0;
-   gs = 0;
-   while (True) {
-      if (gs >= s->nMTF) break;
-      ge = gs + BZ_G_SIZE - 1; 
-      if (ge >= s->nMTF) ge = s->nMTF-1;
-      AssertH ( s->selector[selCtr] < nGroups, 3006 );
-
-      if (nGroups == 6 && 50 == ge-gs+1) {
-            /*--- fast track the common case ---*/
-            UInt16 mtfv_i;
-            UChar* s_len_sel_selCtr 
-               = &(s->len[s->selector[selCtr]][0]);
-            Int32* s_code_sel_selCtr
-               = &(s->code[s->selector[selCtr]][0]);
-
-#           define BZ_ITAH(nn)                      \
-               mtfv_i = mtfv[gs+(nn)];              \
-               bsW ( s,                             \
-                     s_len_sel_selCtr[mtfv_i],      \
-                     s_code_sel_selCtr[mtfv_i] )
-
-            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
-            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
-            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
-            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
-            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
-            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
-            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
-            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
-            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
-            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
-
-#           undef BZ_ITAH
-
-      } else {
-	 /*--- slow version which correctly handles all situations ---*/
-         for (i = gs; i <= ge; i++) {
-            bsW ( s, 
-                  s->len  [s->selector[selCtr]] [mtfv[i]],
-                  s->code [s->selector[selCtr]] [mtfv[i]] );
-         }
-      }
-
-
-      gs = ge+1;
-      selCtr++;
-   }
-   AssertH( selCtr == nSelectors, 3007 );
-
-   if (s->verbosity >= 3)
-      VPrintf1( "codes %d\n", s->numZ-nBytes );
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_compressBlock ( EState* s, Bool is_last_block )
-{
-   if (s->nblock > 0) {
-
-      BZ_FINALISE_CRC ( s->blockCRC );
-      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
-      s->combinedCRC ^= s->blockCRC;
-      if (s->blockNo > 1) s->numZ = 0;
-
-      if (s->verbosity >= 2)
-         VPrintf4( "    block %d: crc = 0x%8x, "
-                   "combined CRC = 0x%8x, size = %d\n",
-                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
-
-      BZ2_blockSort ( s );
-   }
-
-   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
-
-   /*-- If this is the first block, create the stream header. --*/
-   if (s->blockNo == 1) {
-      BZ2_bsInitWrite ( s );
-      bsPutUChar ( s, BZ_HDR_B );
-      bsPutUChar ( s, BZ_HDR_Z );
-      bsPutUChar ( s, BZ_HDR_h );
-      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
-   }
-
-   if (s->nblock > 0) {
-
-      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
-      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
-      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
-
-      /*-- Now the block's CRC, so it is in a known place. --*/
-      bsPutUInt32 ( s, s->blockCRC );
-
-      /*-- 
-         Now a single bit indicating (non-)randomisation. 
-         As of version 0.9.5, we use a better sorting algorithm
-         which makes randomisation unnecessary.  So always set
-         the randomised bit to 'no'.  Of course, the decoder
-         still needs to be able to handle randomised blocks
-         so as to maintain backwards compatibility with
-         older versions of bzip2.
-      --*/
-      bsW(s,1,0);
-
-      bsW ( s, 24, s->origPtr );
-      generateMTFValues ( s );
-      sendMTFValues ( s );
-   }
-
-
-   /*-- If this is the last block, add the stream trailer. --*/
-   if (is_last_block) {
-
-      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
-      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
-      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
-      bsPutUInt32 ( s, s->combinedCRC );
-      if (s->verbosity >= 2)
-         VPrintf1( "    final combined CRC = 0x%x\n   ", s->combinedCRC );
-      bsFinishWrite ( s );
-   }
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                        compress.c ---*/
-/*-------------------------------------------------------------*/
+/* $Id: memzone.c,v 1.1 2008/03/23 05:26:53 barbux Exp $ */
+
+////////////////
+// MemZone.c
+////////////////
+
+
+#include <memzone.h>
+#include <kalloc.h>
+#include <mem.h>
+#include <string.h>
+#include <stdio.h>
+#include <paging.h>
+#include <barbux.h>
+#include <process.h>
+#include <rbmap.h>
+#include <panic.h>
+
+struct cr3stack
+{
+    int cr3place;
+    struct cr3stack * next;
+};
+
+// Process informations
+// max_used is the number of the next greater free cr3 zone. 
+// free_stack is the stack containing the free numbers of cr3 zones. 
+// The algorithm, to find a cr3 zone, is:
+// If the stack is not empty, get the number in it
+// Else, use the max_free, and increment it
+// When destroying a space, add the cr3 zone in the stack
+
+static int max_free = 0;
+static struct cr3stack * free_stack = 0;
+
+struct Space
+{
+    int max_section;
+    int cur_section;
+    int numprocess;
+    int cr3place;
+    unsigned long cr3;
+    unsigned long phys_cr3;
+    unsigned long phys_meminfo;
+    union
+    {
+        struct SSection * mem;
+        struct DSection * first;
+    };
+};
+
+static struct Space proc0_space;
+
+struct SSection
+{
+    void * base;
+    int size;
+};
+
+struct DSection
+{
+    void * base;
+    int size;
+    struct DSection * next;
+};
+
+// Create a space. If max_sections = -1, the space is dynamic
+struct Space * mm_create_space(int max_section)
+{
+    struct Space * s = (struct Space *)kalloc(sizeof(struct Space));
+    if(s == 0) return 0;
+
+    if(max_section > 0)
+    {
+        struct SSection * d = (struct SSection *)kalloc(max_section * sizeof(struct SSection));
+        if(d == 0)
+        {
+            kfree(s);
+            return 0;
+        }
+        s->mem = d;
+    }
+    else if(max_section == -1)
+    {
+        s->first = 0;
+    }
+    else
+    {
+        kfree(s);
+        return 0;
+    }
+    s->max_section = max_section;
+    s->cur_section = 0;
+    // Allocate the cr3
+    if(free_stack != 0)
+    {
+        struct cr3stack * f = free_stack;
+        s->cr3place = free_stack->cr3place;
+        free_stack = free_stack->next;
+        kfree(f);
+    }
+    else
+    {
+        s->cr3place = max_free;
+        max_free++;
+    }
+
+    if (!(s->cr3 = (unsigned long) page_alloc_any ((pg_entry_t **) KERNEL_PG_DIR, (void **) &s->phys_cr3)))
+        panic ("mm_create_space(): unable to alloc process page directory");
+
+    return s;
+}
+
+int mm_delete_space(struct Space * uspace)
+{
+#ifndef MM_NG
+    page_free ((pg_entry_t **) KERNEL_PG_DIR, (void *) (uspace->cr3));
+#endif
+    kfree(uspace);
+    return 0;
+}
+
+// Add a section to the space. If shared != 0, the zone is shared with
+// the kernel at the shared address
+int mm_add_section(struct Space * uspace, void * base, int size, void * shared)
+{
+#ifndef MM_NG
+    int  m;
+#endif
+
+    if(uspace->max_section > 0)
+    {
+        if(uspace->cur_section >= uspace->max_section)
+        {
+            return -1;
+        }
+        else
+        {
+            int i;
+            uspace->mem[uspace->cur_section].base = base;
+            uspace->mem[uspace->cur_section].size = size;
+            uspace->cur_section++;
+            for(i = 0; i < size; i++)
+            {
+#ifndef MM_NG
+                if (page_alloc_flags ((pg_entry_t **) uspace->cr3, (void *) (base + i * PAGE_SIZE), (void **) &m, PG_TABLE_US))
+                {
+                    return -1;
+                }
+                else if(shared != 0)
+                {
+                    if (page_map ((pg_entry_t **) KERNEL_PG_DIR, (void *) m, shared + (i * PAGE_SIZE)))
+                        panic ("mm_add_section(): unable to map allocated pages in kernel address space");
+                }
+#endif
+            }
+        }
+    }
+    else
+    {
+        int i;
+        struct DSection * d = (struct DSection *)kalloc(sizeof(struct DSection));
+        d->base = base;
+        d->size = size;
+        for(i = 0; i < size; i++)
+        {
+#ifndef MM_NG
+            printk ("NEWMM: mm_add_section(): Using strange uspace->numprocess as cr3, may crash ;-)\n");
+            if (page_alloc_flags ((pg_entry_t **) uspace->numprocess, base + (i * PAGE_SIZE), (void **) &m, PG_TABLE_US))
+            {
+                return -1;
+            }
+            else if(shared != 0)
+            {
+                page_map ((pg_entry_t **) KERNEL_PG_DIR, (void *) m, shared);
+                shared += 0x1000;
+            }
+#endif
+        }
+        d->next = uspace->first;
+        uspace->first = d;
+        uspace->cur_section++;
+    }
+    return 0;
+}
+
+// Resize the section
+int mm_resize_section(struct Space * uspace, void * base, int increment)
+{
+    return -1;
+}
+
+// Remove the section
+int mm_remove_section(struct Space * uspace, void * base)
+{
+    if(uspace->max_section > 0)
+    {
+        int i;
+        int found = -1;
+        // Search for the section
+        for(i = 0; i < uspace->cur_section; i++)
+        {
+            if(uspace->mem[i].base == base)
+            {
+                found = i;
+                break;
+            }
+        }
+        if(found == -1) return -1;
+        // We free the section
+        for(i = 0; i < uspace->mem[found].size; i++)
+        {
+#ifndef MM_NG
+            page_free ((pg_entry_t **) uspace->numprocess, uspace->mem[found].base + (i * PAGE_SIZE));
+#endif
+        }
+        // And we copy everything back
+        if(found != uspace->cur_section - 1)
+        {
+            int nbcopy = uspace->cur_section - 1 - found;
+            struct SSection * zonemem = (struct SSection *)kalloc(nbcopy*sizeof(struct SSection));
+            memcpy(zonemem, uspace->mem[found + 1].base, nbcopy*sizeof(struct SSection));
+            memcpy(uspace->mem[found].base, zonemem, nbcopy*sizeof(struct SSection));
+            kfree(zonemem);
+        }
+        uspace->cur_section--;
+    }
+    else
+    {
+        // Search for the section, keep the previous section to link
+        struct DSection * d = uspace->first;
+        struct DSection * p = d;
+        while(d != 0)
+        {
+            if(d->base != base)
+            {
+                p = d;
+                d = d->next;
+            }
+            else
+            {
+                int i;
+                // We free the section
+                for(i = 0; i < d->size; i++)
+                { 
+#ifndef MM_NG
+                    page_free ((pg_entry_t **) uspace->numprocess, d->base + (i * PAGE_SIZE));
+#endif
+                }
+                // And we link back.
+                if(d == p) // Fist...
+                {
+                    uspace->first = d->next;
+                }
+                else
+                {
+                    p->next = d->next;
+                }
+                break;
+            }
+        }
+        uspace->cur_section--;
+    }
+    return 0;
+}
+
+// Get the number of sections
+int mm_get_number_of_section(struct Space * uspace)
+{
+    return uspace->cur_section;
+}
+
+// Get the nth base pointer
+void * mm_get_base(struct Space * uspace,int n)
+{
+    if(n >= uspace->cur_section) return 0;
+    if(uspace->max_section > 0)
+    {
+        return uspace->mem[n].base;
+    }
+    else
+    {
+        int count = uspace->cur_section - n - 1;
+        struct DSection * d = uspace->first;
+        while(d != 0)
+        {
+            if(count == 0) return d->base;
+            else
+            {
+                count--;
+                d = d->next;
+            }
+        }
+        return 0;
+    }
+}
+
+// Get the size of the structure
+int mm_get_size(struct Space * uspace,void * base)
+{
+    if(uspace->max_section > 0)
+    {
+        int i;
+        int found = -1;
+        // Search for the section
+        for(i = 0; i < uspace->cur_section; i++)
+        {
+            if(uspace->mem[i].base == base)
+            {
+                found = i;
+                break;
+            }
+        }
+        if(found == -1) return -1;
+        return uspace->mem[found].size;
+    }
+    else
+    {
+        // Search for the section, keep the previous section to link
+        struct DSection * d = uspace->first;
+        while(d != 0)
+        {
+            if(d->base != base)
+            {
+                d = d->next;
+            }
+            else
+            {
+                return d->size;
+            }
+        }
+    }
+    return -1;
+}
+
+// Create a space for numprocess which is the exact copy of uspace
+struct Space * mm_copy(struct Space * uspace, int numprocess)
+{
+    return 0;
+}
+
+// Get the process number for a process
+int mm_get_numprocess(struct Space * uspace)
+{
+    return uspace->numprocess;
+}
+
+// Get the cr3 of the userspace
+unsigned long mm_get_cr3(struct Space * uspace)
+{
+    return uspace->cr3;
+}
+
+unsigned long mm_get_phys_cr3(struct Space * uspace)
+{
+    return uspace->phys_cr3;
+}
+
+unsigned long mm_get_phys_meminfo(struct Space * uspace)
+{
+    return uspace->phys_meminfo;
+}
+
+struct Space *init_proc0_space(void)
+{
+    memset(&proc0_space, 0, sizeof(struct Space));
+    proc0_space.max_section = -1;
+    proc0_space.cr3 = (unsigned long) KERNEL_PG_DIR;
+    proc0_space.phys_cr3 = (unsigned long) KERNEL_PG_DIR;
+
+    return &proc0_space;
+}
main/kernel/lib/libbz2/crctable.c to main/kernel/config/src/parse.c
--- a/main/kernel/lib/libbz2/crctable.c
+++ b/main/kernel/config/src/parse.c
@@ -1,144 +1,189 @@
-
-/*-------------------------------------------------------------*/
-/*--- Table for doing CRCs                                  ---*/
-/*---                                            crctable.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward@acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
 
 
-#include "bzlib_private.h"
-
-/*--
-  I think this is an implementation of the AUTODIN-II,
-  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
-  from code by Rob Warnock, in Section 51 of the
-  comp.compression FAQ.
---*/
-
-UInt32 BZ2_crc32Table[256] = {
-
-   /*-- Ugly, innit? --*/
-
-   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
-   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
-   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
-   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
-   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
-   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
-   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
-   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
-   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
-   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
-   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
-   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
-   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
-   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
-   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
-   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
-   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
-   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
-   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
-   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
-   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
-   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
-   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
-   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
-   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
-   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
-   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
-   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
-   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
-   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
-   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
-   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
-   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
-   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
-   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
-   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
-   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
-   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
-   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
-   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
-   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
-   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
-   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
-   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
-   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
-   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
-   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
-   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
-   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
-   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
-   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
-   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
-   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
-   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
-   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
-   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
-   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
-   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
-   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
-   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
-   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
-   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
-   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
-   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
+enum state_t
+{
+    out_e,
+    name_parsed_e,
+    in_name_e,
+    value_parsed_e,
+    in_value_e
 };
 
+struct configValue
+{
+    char * name;
+    char * value;
+};
 
-/*-------------------------------------------------------------*/
-/*--- end                                        crctable.c ---*/
-/*-------------------------------------------------------------*/
+struct tabConfigValue
+{
+    struct configValue * tab;
+    int size;
+    int alloc;
+};
+
+void addToTab(struct tabConfigValue *tab, struct configValue value)
+{
+    if (tab->size == tab->alloc)
+    {
+        tab->alloc = tab->alloc * 2;
+        tab->tab = (struct configValue *) realloc((void*)tab->tab, tab->alloc * sizeof(struct configValue));
+    }
+    memcpy(&(tab->tab[tab->size]), &value, sizeof(struct configValue));
+    tab->size = tab->size + 1;
+}
+
+struct configValue * getValue(const char * name, struct tabConfigValue *tab)
+{
+    int i;
+    for (i=0; i<tab->size; ++i)
+    {
+        if (strcmp(name, tab->tab[i].name)==0)
+        {
+            return &tab->tab[i];
+        }
+    }
+    printf("Error : %s is not a valid name\n", name);
+    exit(1);
+}
+
+int myGetline(char ** buffer, int * size, FILE * stream)
+{
+    int result = getline(buffer, size, stream);
+    if (result > 0)
+    {
+        if ((*buffer)[result-1] == '\n')
+        {
+            (*buffer)[result-1] = 0;
+            return result - 1;
+        }
+    }
+    return result;
+}
+
+int main(int argc, char ** argv)
+{
+    if (argc != 4)
+    {
+        printf("Usage : %s <masterconfig file> <config file> <Makefile.conf>\n", argv[0]);
+        return 1;
+    }
+    // first we parse the config file
+    FILE * afile = fopen(argv[2], "r");
+
+    int size = 200;
+    char * buffer = (char*) malloc(size);
+
+    struct tabConfigValue aTab;
+    aTab.size = 0;
+    aTab.alloc = 10;
+    aTab.tab = (struct configValue *) malloc(aTab.alloc * sizeof (struct configValue));
+
+    while (myGetline(&buffer, &size, afile) >= 0)
+    {
+        if (buffer[0] == 0 || buffer[0] == '#')
+        {
+            continue;
+        }
+        // search the = caracter
+        int i;
+        for (i=0; buffer[i] != 0; ++i)
+        {
+            if (buffer[i] == '=') break;
+        }
+        if (buffer[i] == 0)
+        {
+            printf("Error at that line in %s : %s\n", argv[2], buffer);
+            return 1;
+        }
+        //replace the = by \0
+        buffer[i] = 0;
+        struct configValue aValue;
+        aValue.name = strdup(buffer);
+        aValue.value = strdup(&buffer[i+1]);
+        addToTab(&aTab, aValue);
+    }
+
+    fclose(afile);
+
+    // then we parse the master config file
+    // When we find something to generate, we generate it
+    FILE * aMasterFile = fopen(argv[1], "r");
+    FILE * aMakeFile = fopen(argv[3], "w");
+
+    struct configValue * aCurrentValue = NULL;
+    int state = out_e;
+    int lineNo = 0;
+    int generate = 0;
+    while (myGetline(&buffer, &size, afile) >= 0)
+    {
+        ++lineNo;
+        if (state != in_value_e && (buffer[0] == 0 || buffer[0] == '#'))
+        {
+            continue;
+        }
+        switch (state)
+        {
+        case out_e:
+            aCurrentValue = getValue(buffer, &aTab);
+            state = name_parsed_e;
+            break;
+        case name_parsed_e:
+            if (strcmp(buffer, "{")==0)
+            {
+                state = in_name_e;
+            }
+            else
+            {
+                printf("Error at line %d in file %s ( \"{\" expected)\n", lineNo, argv[1]);
+                return 1;
+            }
+            break;
+        case in_name_e:
+            if (strcmp(buffer, "}")==0)
+            {
+                state = out_e;
+            }
+            else if (strcmp(buffer, aCurrentValue->value) == 0)
+            {
+                generate = 1;
+                state = value_parsed_e;
+            }
+            else
+            {
+                generate = 0;
+                state = value_parsed_e;
+            }
+            break;
+        case value_parsed_e:
+            if (strcmp(buffer, "{")==0)
+            {
+                state = in_value_e;
+            }
+            else
+            {
+                printf("Error at line %d in file %s ( \"{\" expected)\n", lineNo, argv[1]);
+                return 1;
+            }
+            break;
+        case in_value_e:
+            if (strcmp(buffer, "}")==0)
+            {
+                state = in_name_e;
+            }
+            else
+            {
+                if (generate == 1)
+                {
+                    fprintf(aMakeFile, "%s\n", buffer);
+                }
+            }
+            break;
+        }
+    }
+    fclose (aMakeFile);
+    fclose (aMasterFile);
+}
main/kernel/lib/libbz2/huffman.c to main/kernel/mm/x86_32/rbmap.c
--- a/main/kernel/lib/libbz2/huffman.c
+++ b/main/kernel/mm/x86_32/rbmap.c
@@ -1,228 +1,340 @@
-
-/*-------------------------------------------------------------*/
-/*--- Huffman coding low-level stuff                        ---*/
-/*---                                             huffman.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
-  This file is a part of bzip2 and/or libbzip2, a program and
-  library for lossless, block-sorting data compression.
-
-  Copyright (C) 1996-2002 Julian R Seward.  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-  1. Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-  2. The origin of this software must not be misrepresented; you must 
-     not claim that you wrote the original software.  If you use this 
-     software in a product, an acknowledgment in the product 
-     documentation would be appreciated but is not required.
-
-  3. Altered source versions must be plainly marked as such, and must
-     not be misrepresented as being the original software.
-
-  4. The name of the author may not be used to endorse or promote 
-     products derived from this software without specific prior written 
-     permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  Julian Seward, Cambridge, UK.
-  jseward@acm.org
-  bzip2/libbzip2 version 1.0 of 21 March 2000
-
-  This program is based on (at least) the work of:
-     Mike Burrows
-     David Wheeler
-     Peter Fenwick
-     Alistair Moffat
-     Radford Neal
-     Ian H. Witten
-     Robert Sedgewick
-     Jon L. Bentley
-
-  For more information on these sources, see the manual.
---*/
-
-
-#include "bzlib_private.h"
-
-/*---------------------------------------------------*/
-#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
-#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
-#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
-
-#define ADDWEIGHTS(zw1,zw2)                           \
-   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
-   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
-
-#define UPHEAP(z)                                     \
-{                                                     \
-   Int32 zz, tmp;                                     \
-   zz = z; tmp = heap[zz];                            \
-   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
-      heap[zz] = heap[zz >> 1];                       \
-      zz >>= 1;                                       \
-   }                                                  \
-   heap[zz] = tmp;                                    \
-}
-
-#define DOWNHEAP(z)                                   \
-{                                                     \
-   Int32 zz, yy, tmp;                                 \
-   zz = z; tmp = heap[zz];                            \
-   while (True) {                                     \
-      yy = zz << 1;                                   \
-      if (yy > nHeap) break;                          \
-      if (yy < nHeap &&                               \
-          weight[heap[yy+1]] < weight[heap[yy]])      \
-         yy++;                                        \
-      if (weight[tmp] < weight[heap[yy]]) break;      \
-      heap[zz] = heap[yy];                            \
-      zz = yy;                                        \
-   }                                                  \
-   heap[zz] = tmp;                                    \
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbMakeCodeLengths ( UChar *len, 
-                             Int32 *freq,
-                             Int32 alphaSize,
-                             Int32 maxLen )
-{
-   /*--
-      Nodes and heap entries run from 1.  Entry 0
-      for both the heap and nodes is a sentinel.
-   --*/
-   Int32 nNodes, nHeap, n1, n2, i, j, k;
-   Bool  tooLong;
-
-   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
-   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
-   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 
-
-   for (i = 0; i < alphaSize; i++)
-      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
-
-   while (True) {
-
-      nNodes = alphaSize;
-      nHeap = 0;
-
-      heap[0] = 0;
-      weight[0] = 0;
-      parent[0] = -2;
-
-      for (i = 1; i <= alphaSize; i++) {
-         parent[i] = -1;
-         nHeap++;
-         heap[nHeap] = i;
-         UPHEAP(nHeap);
-      }
-
-      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
-   
-      while (nHeap > 1) {
-         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
-         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
-         nNodes++;
-         parent[n1] = parent[n2] = nNodes;
-         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
-         parent[nNodes] = -1;
-         nHeap++;
-         heap[nHeap] = nNodes;
-         UPHEAP(nHeap);
-      }
-
-      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
-
-      tooLong = False;
-      for (i = 1; i <= alphaSize; i++) {
-         j = 0;
-         k = i;
-         while (parent[k] >= 0) { k = parent[k]; j++; }
-         len[i-1] = j;
-         if (j > maxLen) tooLong = True;
-      }
-      
-      if (! tooLong) break;
-
-      for (i = 1; i < alphaSize; i++) {
-         j = weight[i] >> 8;
-         j = 1 + (j / 2);
-         weight[i] = j << 8;
-      }
-   }
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbAssignCodes ( Int32 *code,
-                         UChar *length,
-                         Int32 minLen,
-                         Int32 maxLen,
-                         Int32 alphaSize )
-{
-   Int32 n, vec, i;
-
-   vec = 0;
-   for (n = minLen; n <= maxLen; n++) {
-      for (i = 0; i < alphaSize; i++)
-         if (length[i] == n) { code[i] = vec; vec++; };
-      vec <<= 1;
-   }
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbCreateDecodeTables ( Int32 *limit,
-                                Int32 *base,
-                                Int32 *perm,
-                                UChar *length,
-                                Int32 minLen,
-                                Int32 maxLen,
-                                Int32 alphaSize )
-{
-   Int32 pp, i, j, vec;
-
-   pp = 0;
-   for (i = minLen; i <= maxLen; i++)
-      for (j = 0; j < alphaSize; j++)
-         if (length[j] == i) { perm[pp] = j; pp++; };
-
-   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
-   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
-
-   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
-
-   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
-   vec = 0;
-
-   for (i = minLen; i <= maxLen; i++) {
-      vec += (base[i+1] - base[i]);
-      limit[i] = vec-1;
-      vec <<= 1;
-   }
-   for (i = minLen + 1; i <= maxLen; i++)
-      base[i] = ((limit[i-1] + 1) << 1) - base[i];
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                         huffman.c ---*/
-/*-------------------------------------------------------------*/
+/* $Id: rbmap.c,v 1.1 2008/03/23 05:26:53 barbux Exp $
+ *
+ * RAM BitMAP implementation
+ *
+ */
+ 
+#include <btypes.h>
+#include <mem.h>
+#include <rbmap.h>
+#include <paging.h>
+#include <process.h>
+#include <stdio.h>
+#include <panic.h>
+#include <console.h>
+
+/* #define RBMAP_DEBUG(_f, _a...) early_printk(_f, ## _a) */
+#define RBMAP_DEBUG(_f, _a...) ((void) 0)
+
+
+/* Check if page can be used */
+int rbmap_page_check (void *page);
+/* Mark page as used */
+void rbmap_page_alloc (void *page);
+/* Mark page as free */
+void rbmap_page_free (void *page);
+/* Allocates and link a new entry in the bmap index */
+rbmap_t *rbmap_entry_alloc (int id);
+/* Free and unlink an entry from the bmap index */
+void rbmap_entry_free (int id);
+/* Is the whole entry pointing on free pages ? */
+int rbmap_is_empty_entry (int id);
+/* Process the page physical address to entry and table offset */
+void rbmap_page_addr (void *page, int *entry, int *offset);
+
+
+/* RAM BitMAP index */
+static rbmap_t *rbmap[RAM_BITMAP_IDX_ENTRIES];
+/* An allocated but unused page 
+ * We use it to ensure there will only be at least one free page to create a new entry
+ */
+static void *next_page = NULL;
+
+void rbmap_init (void)
+{
+	RBMAP_DEBUG("rbmap_init()\n");
+
+	memset4 (rbmap, 0, RAM_BITMAP_IDX_ENTRIES);
+	
+	rbmap[0] = (rbmap_t *) RAM_BITMAP_ENTRY_0;
+
+	page_zerofill ((void *) RAM_BITMAP_ENTRY_0);	/* Clears entry 0 */
+
+	/* Mark first meg as used */
+	/* XXX: Must be sure that DYNAMIC OFFSET % RAM_BITMAP_PAGES_PER_ENTRY == 0 */
+	memset1 (rbmap[0], 0xff, (uint32_t) DYNAMIC_RAM_OFFSET / RAM_BITMAP_PAGES_PER_ENTRY);
+	minfo.used_pages = (uint32_t) DYNAMIC_RAM_OFFSET / PAGE_SIZE;
+	
+	/* Prealloc next_page */
+	next_page = rbmap_find_free_page ();
+	rbmap_page_alloc (next_page);
+}
+
+
+void rbmap_page_addr (void *page, int *entry, int *offset)
+{
+	uint32_t addr;
+	
+	addr = ((uint32_t) page) >> PAGE_SIZE_LOG;
+
+	if (offset)
+		*offset = addr & (RAM_BITMAP_PAGES_PER_ENTRY - 1);
+	addr >>= RAM_BITMAP_ENTRY_SIZE_LOG;
+
+	if (entry)
+		*entry = addr & (RAM_BITMAP_IDX_ENTRIES - 1);
+}
+
+int rbmap_is_free (void *page)
+{
+	int entry, offset;
+
+	rbmap_page_addr (page, &entry, &offset);
+
+	if (! rbmap[entry] || ! (rbmap[entry])[offset])
+		return 1;
+	return 0;
+}
+
+int rbmap_is_empty_entry (int id)
+{
+	int i;
+	uint32_t *p;
+	
+	if (! rbmap[id])
+		return 1;
+
+	p = (uint32_t *) rbmap[id];
+
+	for (i = 0; i < RAM_BITMAP_ENTRY_SIZE / 4; i++, p++)
+		if (*p)
+			return 0;
+	return 1;
+}
+
+void rbmap_page_alloc (void *page)
+{
+	int entry, offset;
+	rbmap_t *p;
+
+	RBMAP_DEBUG("rbmap_page_alloc(0x%x)\n",  page);
+
+	rbmap_page_addr (page, &entry, &offset);
+
+	if (! rbmap[entry])
+		p = rbmap_entry_alloc (entry);
+	else
+		p = rbmap[entry];
+
+	if (p[offset])
+		panic ("rbmap_page_alloc(): trying to allocate used page");
+
+	p[offset] = 1;
+	minfo.used_pages++;
+}
+
+void rbmap_page_free (void *page)
+{
+	int entry, offset;
+	rbmap_t *p;
+	
+	if (page < (void *) DYNAMIC_RAM_OFFSET)
+		panic ("bmap_page_free(): attempting to free staticaly allocated page!");
+	
+	rbmap_page_addr (page, &entry, &offset);
+	
+	p = rbmap[entry];
+
+	if (! p[offset])
+		panic ("rbmap_page_free(): attempting to free free page");
+
+	p[offset] = 0;
+	
+	minfo.used_pages--;
+
+	if (rbmap_is_empty_entry (entry))
+		rbmap_entry_free (entry);
+}
+
+rbmap_t *rbmap_entry_alloc (int id)
+{
+	rbmap_t *new_entry;
+
+	RBMAP_DEBUG("rbmap_entry_alloc(%d) (next_page 0x%x)\n", id, next_page);
+
+	if (rbmap[id])
+		panic ("rbmap_entry_alloc(): trying to realloc allocated entry!");
+
+	/* rbmap manage PAs, but we need a VA to access it! */
+	new_entry = (rbmap_t *) page_map_any((pg_entry_t **) KERNEL_PG_DIR, next_page);
+	if (new_entry == NULL)
+		panic("rbmap_entry_alloc(): out of virtual memory!");
+	page_zerofill (new_entry);
+
+	rbmap[id] = new_entry;
+
+	next_page = rbmap_find_free_page ();
+	rbmap_alloc (next_page);
+
+	return new_entry;
+}
+
+void rbmap_entry_free (int id)
+{
+	if (id == 0)
+		panic ("rbmap_entry_free(): trying to free static entry #0!");
+
+	if (! rbmap[id])
+		panic ("rbmap_entry_free(): attempting to free free entry!");
+	
+	rbmap_page_free (rbmap[id]);
+
+	rbmap[id] = NULL;
+}
+
+int rbmap_page_check (void *page)
+{
+	int i;
+
+	if (page < (void *) DYNAMIC_RAM_OFFSET || page > (void *) (((minfo.lowmem + minfo.highmem) * 1024) - PAGE_SIZE))
+		return 0;
+
+	for (i = 0; i < minfo.map.n_entries; i++) {
+		uint32_t beg, end;
+		
+		/* XXX: Casting 64 bit integers to 32 bits integer may no be safe */
+		beg = (uint32_t) minfo.map.entries[i].start;
+		end = beg + (uint32_t) minfo.map.entries[i].size;
+
+		/* Round up to page size */
+		beg = ((beg / PAGE_SIZE) + 1) * PAGE_SIZE;
+		end = (end / PAGE_SIZE) * PAGE_SIZE;
+
+		if (beg > (uint32_t) page || (end - PAGE_SIZE) < (uint32_t) page)
+			continue;
+
+		/* Area matched */
+		if (minfo.map.entries[i].type == E820_RAM)
+			return 1;		/* Page is in usable RAM area */
+		else
+			return 0;
+
+	}
+
+	return 0;
+}
+
+void * rbmap_find_free_page (void)
+{
+	int i;
+
+	RBMAP_DEBUG("rbmap_find_free_page()\n");
+
+	/* TODO: count avail pages to speed up when full memory */
+
+	for (i = 0; i < minfo.map.n_entries; i++) {
+		uint32_t beg, end;
+
+		if (minfo.map.entries[i].type != E820_RAM)
+			continue;	/* Not usable, pass */
+		
+		/* XXX: Casting 64 bit integers to 32 bits integer may no be safe */
+		beg = (uint32_t) minfo.map.entries[i].start;
+		end = beg + (uint32_t) minfo.map.entries[i].size;
+		
+		if (end < (uint32_t) DYNAMIC_RAM_OFFSET)
+			continue;
+
+		/* Search only in dynamic ram area */
+		if (beg < (uint32_t) DYNAMIC_RAM_OFFSET)
+			beg = (uint32_t) DYNAMIC_RAM_OFFSET;
+
+		/* Round up to page size */
+		beg = ((beg / PAGE_SIZE) + 1) * PAGE_SIZE;
+		end = (end / PAGE_SIZE) * PAGE_SIZE;
+
+		while (beg < end) {
+			if (rbmap_is_free ((void *) beg))
+				return (void *) beg;
+			beg += PAGE_SIZE;
+		}
+	}
+
+	return NULL;
+}
+
+
+int rbmap_alloc (void *page)
+{
+	RBMAP_DEBUG("rbmap_alloc(0x%x)\n", page);
+
+	if (!rbmap_page_check (page))
+		return -1;
+
+	if (!rbmap_is_free (page))
+		return -1;
+
+	rbmap_page_alloc (page);
+
+	return 0;
+}
+
+void rbmap_free (void *page)
+{
+	if (!rbmap_page_check (page))
+		panic ("rbmap_free(): trying to free unusable page!");
+
+	if (rbmap_is_free (page))
+		panic ("rbmap_free(): attempting to free free page!");
+
+	rbmap_page_free (page);
+}
+
+
+void *rbmap_alloc_any (void)
+{
+	void *phys_page = NULL;
+	
+	RBMAP_DEBUG("rbmap_alloc_any()\n");
+	
+	while (!phys_page) 
+	{
+		if (!(phys_page = rbmap_find_free_page ()))
+			panic ("rbmap_alloc_any(): no more physical page available");
+
+		if (rbmap_alloc (phys_page))	/* Someone has allocated it before us */
+			phys_page = NULL;
+	}
+
+	return phys_page;
+}
+
+
+int rbmap_share (void *page)
+{
+	int entry, offset;
+	rbmap_t *p;
+	
+	rbmap_page_addr (page, &entry, &offset);
+
+	p = rbmap[entry];
+
+	if (! p[offset])
+		return -1;
+
+	p[offset]++;
+
+	return 0;
+}
+
+
+int rbmap_unshare (void *page)
+{
+	int entry, offset;
+	rbmap_t *p;
+	
+	rbmap_page_addr (page, &entry, &offset);
+
+	p = rbmap[entry];
+
+	if (! p[offset])
+		return -1;
+
+	p[offset]--;
+	
+	if (! p[offset])
+		minfo.used_pages--;
+
+	return 0;
+}
+
main/kernel/lib/memset.S to main/kernel/lib/x86_32/memset.S
--- a/main/kernel/lib/memset.S
+++ b/main/kernel/lib/x86_32/memset.S
@@ -1,4 +1,4 @@
-/* $Id: memset.S,v 1.3 2004/07/17 21:51:01 rmp91 Exp $
+/* $Id: memset.S,v 1.1 2008/03/23 05:26:53 barbux Exp $
  *
  * Low-level assembly routines for fast memory setting
  *
main/kernel/mm/asm.S to main/kernel/mm/x86_32/mem.c
--- a/main/kernel/mm/asm.S
+++ b/main/kernel/mm/x86_32/mem.c
@@ -1,128 +1,106 @@
-/* $Id: asm.S,v 1.2 2006/11/11 16:50:44 rmp91 Exp $
- *
- * Assembly routines for memory managing
- *
- */
+/* $Id: mem.c,v 1.1 2008/03/23 05:26:53 barbux Exp $ */
 
-.globl pg_table_linear_fill
-.globl pg_table_linear_or
-.globl pg_table_linear_and
-.globl flush_one_tlb
-.globl flush_all_tlb
-.globl flush_pge_tlb
+//////////////////
+// Gestion de la mémoire
+/////////////////
 
 #include <mem.h>
+#include <string.h>
+#include <process.h>
+#include <console.h>
+#include <multiboot.h>
+#include <panic.h>
 
-.align 4
+#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
 
-pg_table_linear_fill:
-	pushl %ebp
-	movl %esp, %ebp
+struct mem_info minfo;
 
-	pushl %ecx
-	pushl %edi
-	pushl %ebx
+void e820_map_init (multiboot_info_t * mbi)
+{
+	int i=0;
+
+	// Check for MMAP information
+	if (!CHECK_FLAG (mbi->flags, 6))
+	{
+		panic("MMAP information not provided by multiboot loader");
+	}
 	
-	movl 0x10(%ebp), %eax
-	andl $0xfff, %eax	# Only first 12 bits counts
+	// Multiboot structure
+	memory_map_t *mmap;
 
-	movl 0xc(%ebp), %ebx
-	andl $0xfffff000, %ebx	# Mask 20 high bits
+	minfo.map.n_entries = 0;
 
-	orl %ebx, %eax
+	for (mmap = (memory_map_t *) mbi->mmap_addr;
+			(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
+			mmap = (memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof (mmap->size)))
+	{
+		minfo.map.entries[i].start = (mmap->base_addr_high << 16) + mmap->base_addr_low;
+		minfo.map.entries[i].size = (mmap->length_high << 16) + mmap->length_low;
+		minfo.map.entries[i].type = mmap->type;
+		++i;
+	}
+	minfo.map.n_entries = i;
 
-	movl 0x14(%ebp), %ecx	# Count
+	// check for mem size 
+	if (!CHECK_FLAG (mbi->flags, 0))
+	{
+		panic("memory size info not provided by multiboot loader");
+	}
+	
+	minfo.lowmem = mbi->mem_lower;
+	minfo.highmem = mbi->mem_upper;
+	// XXX put a value that mean multiboot
+	minfo.src = 0xe801;
+	
+	minfo.phys_pages = ((minfo.lowmem + minfo.highmem) * 1024) / PAGE_SIZE;
+	minfo.used_pages = 0;
+}
 
-	movl 0x8(%ebp), %edi
+const char *e820_str (uint32_t type)
+{
+	switch (type) {
+		case E820_RAM:
+			return "Usable";
+		case E820_RESERVED:
+			return "Reserved";
+		case E820_ACPI:
+			return "ACPI Data";
+		case E820_NVS:
+			return "ACPI NVS";
+		default:
+			return "Unknown";
+	}
+}
 
-	cld
+void print_mem_infos (void)
+{
+	if (minfo.map.n_entries > 0) {
+		int i;
 
-1:	
-	stosl
-	addl $PAGE_SIZE, %eax
-	loop 1b
+		printk ("e820 map (%d entries):\n", minfo.map.n_entries);
+		for (i = 0; i < minfo.map.n_entries; i++)
+			printk ("0x%.8X - 0x%.8x, type: %s\n",
+				(uint32_t) minfo.map.entries[i].start,
+				(uint32_t) (minfo.map.entries[i].start + minfo.map.entries[i].size),
+				e820_str (minfo.map.entries[i].type)
+			);
+	}
+	else
+		printk ("No e820 map, complain to your BIOS constructor\n");
 
+	printk ("Memory infos (from multiboot): low %d kB, high %d kB, total %d kB\n",
+		(int) minfo.lowmem, (int) minfo.highmem,
+		(int) (minfo.lowmem + minfo.highmem));
 
-	popl %ebx
-	popl %edi
-	popl %ecx
-	
-	popl %ebp
+	printk ("Physical pages: %d used, %d free, %d total\n", minfo.used_pages,
+		minfo.phys_pages - minfo.used_pages,
+		minfo.phys_pages);
+}
 
-	ret
+extern char sbss[];
+extern char ebss[];
 
-
-.align 4
-
-pg_table_linear_or:
-	pushl	%ebp
-	movl	%esp, %ebp
-
-	pushl	%ecx
-	pushl	%edi
-
-	movl	0x8(%ebp), %edi
-	movl	0xc(%ebp), %eax
-	movl	0x10(%ebp), %ecx
-
-1:
-	orl	%eax, (%edi)
-	addl	$4, %edi
-	loop 	1b
-
-	popl	%edi
-	popl	%ecx
-
-	popl	%ebp
-	ret
-
-
-.align 4
-
-pg_table_linear_and:
-	pushl	%ebp
-	movl	%esp, %ebp
-
-	pushl	%ecx
-	pushl	%edi
-
-	movl	0x8(%ebp), %edi
-	movl	0xc(%ebp), %eax
-	movl	0x10(%ebp), %ecx
-
-1:
-	andl	%eax, (%edi)
-	addl	$4, %edi
-	loop 	1b
-
-	popl	%edi
-	popl	%ecx
-
-	popl	%ebp
-	ret
-
-.align 4
-
-flush_one_tlb:
-	invlpg 0x4(%esp)
-	ret
-
-.align 4
-
-flush_all_tlb:
-	movl %cr3, %eax
-	movl %eax, %cr3
-	ret
-
-#define PGE_BITMASK	0x000080
-
-.align 4
-
-flush_pge_tlb:
-	pushl $PGE_BITMASK
-	call cr4_feat_disable
-	call flush_all_tlb
-	call cr4_feat_enable
-	addl $4, %esp
-	ret
-
+void init_bss()
+{
+	memset(sbss, 0, (int) (ebss - sbss));
+}
main/kernel/mm/mem.c to main/kernel/mm/x86_32/mem_map.c
--- a/main/kernel/mm/mem.c
+++ b/main/kernel/mm/x86_32/mem_map.c
@@ -1,106 +1,138 @@
-/* $Id: mem.c,v 1.9 2006/10/10 21:59:30 rmp91 Exp $ */
+/* $Id: mem_map.c,v 1.1 2008/03/23 05:26:53 barbux Exp $
+ *
+ * Physical memory manager. Keep track of allocated & free physical pages.
+ *
+ */
 
-//////////////////
-// Gestion de la mémoire
-/////////////////
+#ifdef MM_NG
 
+#include <btypes.h>
+#include <list.h>
 #include <mem.h>
-#include <string.h>
-#include <process.h>
-#include <console.h>
-#include <multiboot.h>
-#include <panic.h>
+#include <mm.h>
+#include <paging.h>
+#include <stdio.h>
 
-#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
 
-struct mem_info minfo;
+struct zone zones[MAX_ZONES];
+struct page *mem_map;
 
-void e820_map_init (multiboot_info_t * mbi)
+void zone_init (int id, const char *name, paddr_t start, uint32_t size);
+uint32_t mem_map_lowmem_init (void);
+void mem_map_fixup (uint32_t size);
+
+static int lowmem_initialized = 0;
+/* static int highmem_initialized = 0; */
+
+/* Initialize physical memory manager */
+void mem_init (void)
 {
-	int i=0;
+	uint32_t sz;
 
-	// Check for MMAP information
-	if (!CHECK_FLAG (mbi->flags, 6))
-	{
-		panic("MMAP information not provided by multiboot loader");
-	}
-	
-	// Multiboot structure
-	memory_map_t *mmap;
+	e820_map_init ();
 
-	minfo.map.n_entries = 0;
+	mem_map = (struct page *) (KERN_PHYS_END_ADDR + KERNEL_OFFSET);	
 
-	for (mmap = (memory_map_t *) mbi->mmap_addr;
-			(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
-			mmap = (memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof (mmap->size)))
-	{
-		minfo.map.entries[i].start = (mmap->base_addr_high << 16) + mmap->base_addr_low;
-		minfo.map.entries[i].size = (mmap->length_high << 16) + mmap->length_low;
-		minfo.map.entries[i].type = mmap->type;
-		++i;
-	}
-	minfo.map.n_entries = i;
+	/* Init the first 896 MB map */
+	sz = mem_map_lowmem_init ();
+	/* Fix memrory map */
+	mem_map_fixup (sz);
 
-	// check for mem size 
-	if (!CHECK_FLAG (mbi->flags, 0))
-	{
-		panic("memory size info not provided by multiboot loader");
-	}
-	
-	minfo.lowmem = mbi->mem_lower;
-	minfo.highmem = mbi->mem_upper;
-	// XXX put a value that mean multiboot
-	minfo.src = 0xe801;
-	
-	minfo.phys_pages = ((minfo.lowmem + minfo.highmem) * 1024) / PAGE_SIZE;
-	minfo.used_pages = 0;
+	/* Initialize zones */
+	zone_init (0, "LOWMEM", 0, sz);
+
+	lowmem_initialized = 1;
 }
 
-const char *e820_str (uint32_t type)
+
+/* Fill mem_map for the first 896 MB. Return the number of pages initialized.
+ * XXX: This require 1 page for each MB of RAM
+ * Since we only initialize lowmem, we need at most 896 pages (about 3-4 MB).
+ */
+
+uint32_t mem_map_lowmem_init (void)
 {
-	switch (type) {
-		case E820_RAM:
-			return "Usable";
-		case E820_RESERVED:
-			return "Reserved";
-		case E820_ACPI:
-			return "ACPI Data";
-		case E820_NVS:
-			return "ACPI NVS";
-		default:
-			return "Unknown";
+	uint32_t count;
+
+	for (count = 0; count < minfo.phys_pages && count < LOWMEM_PAGES; count++)
+		memset4 (&mem_map[count], 0, sizeof (struct page) / 4);
+
+	return count;
+}
+
+
+/* Fix up mem_map, avoid some physical pages from being allocated */
+
+void mem_map_fixup (uint32_t size)
+{
+	int i;
+	uint32_t page;
+
+	/* Page 0 is unusable on some computers */
+	mem_map[0].flags = PAGE_UNUSABLE;
+	minfo.usable_pages = size - 1;
+
+	for (page = 0, i = 0; i < minfo.map.n_entries; i++) {
+		uint32_t start_page, end_page;
+
+		/* Round to pages, discard incomplete pages */
+		start_page = (((uint32_t) minfo.map.entries[i].start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+		end_page = ((uint32_t) (minfo.map.entries[i].start + minfo.map.entries[i].size)) >> PAGE_SHIFT;
+
+		/* Holes in e820 are not usable */
+		while (page  < start_page) {
+			mem_map[page++].flags = PAGE_UNUSABLE;
+			minfo.usable_pages--;
+		}
+
+		if (minfo.map.entries[i].type != E820_RAM) {
+			while (page <= end_page) {
+				mem_map[page++].flags = PAGE_UNUSABLE;
+				minfo.usable_pages--;
+			}
+		}
+		else
+			page = end_page + 1;
+	}
+
+	for (page = KERN_PHYS_ADDR >> PAGE_SHIFT; page < (KERN_PHYS_END_ADDR >> PAGE_SHIFT) + size; page++)
+		mem_map[page].flags = PAGE_KERNEL;
+}
+
+
+void zone_init (int id, const char *name, paddr_t start, uint32_t size)
+{
+	zones[id].name = name;
+	zones[id].start = start;
+	zones[id].size = size;
+	zones[id].map = &mem_map[start >> PAGE_SHIFT];
+
+	if (!lowmem_initialized) {	/* Can't page_alloc() now */
+		uint32_t page;
+		struct page *ptr;
+		int i;
+		paddr_t p;
+
+		for (p = LOWMEM_BUDDY_START, i = 0; i < FREE_AREA_CNT; i++) {
+			zones[id].areas[i].list.prev = zones[id].areas[i].list.next = NULL;
+			zones[id].areas[i].map = (uint8_t *) (p + KERNEL_OFFSET);
+			if (i > 0)
+				/* Setting one word after won't harm */
+				memset4 ((void *) (p + KERNEL_OFFSET), 0, (((size >> PAGE_SHIFT) / (1 << i)) / 64) + 1);
+			p += ((size >> PAGE_SHIFT) / (1 << i)) / 16;
+		}
+
+		p  = ((p + PAGE_SIZE - 1) >> PAGE_SHIFT);
+
+		for (page = (LOWMEM_BUDDY_START  >> PAGE_SHIFT); page < p; page++)
+			mem_map[page].flags = PAGE_KERNEL;
+
+		/* Ok now fill bitmaps and free lists */
+		for (ptr = zones[id].map, i = 0; i < (size - start) >> PAGE_SHIFT; ptr++, i++);
+			
 	}
 }
 
-void print_mem_infos (void)
-{
-	if (minfo.map.n_entries > 0) {
-		int i;
 
-		printk ("e820 map (%d entries):\n", minfo.map.n_entries);
-		for (i = 0; i < minfo.map.n_entries; i++)
-			printk ("0x%.8X - 0x%.8x, type: %s\n",
-				(uint32_t) minfo.map.entries[i].start,
-				(uint32_t) (minfo.map.entries[i].start + minfo.map.entries[i].size),
-				e820_str (minfo.map.entries[i].type)
-			);
-	}
-	else
-		printk ("No e820 map, complain to your BIOS constructor\n");
+#endif	/* MM_NG */
 
-	printk ("Memory infos (from multiboot): low %d kB, high %d kB, total %d kB\n",
-		(int) minfo.lowmem, (int) minfo.highmem,
-		(int) (minfo.lowmem + minfo.highmem));
-
-	printk ("Physical pages: %d used, %d free, %d total\n", minfo.used_pages,
-		minfo.phys_pages - minfo.used_pages,
-		minfo.phys_pages);
-}
-
-extern char sbss[];
-extern char ebss[];
-
-void init_bss()
-{
-	memset(sbss, 0, (int) (ebss - sbss));
-}
main/kernel/mm/mem_map.c to main/kernel/mm/x86_32/memprocess.c
--- a/main/kernel/mm/mem_map.c
+++ b/main/kernel/mm/x86_32/memprocess.c
@@ -1,138 +1,125 @@
-/* $Id: mem_map.c,v 1.2 2006/01/14 16:03:30 rmp91 Exp $
- *
- * Physical memory manager. Keep track of allocated & free physical pages.
- *
- */
+/* $Id: memprocess.c,v 1.1 2008/03/23 05:26:53 barbux Exp $ */
 
-#ifdef MM_NG
+#include <memprocess.h>
+#include <process.h>
+#include <mem.h>
+#include <memzone.h>
+#include <rbmap.h>
+#include <paging.h>
+#include <panic.h>
+#include <console.h>
 
-#include <btypes.h>
-#include <list.h>
-#include <mem.h>
-#include <mm.h>
-#include <paging.h>
-#include <stdio.h>
+int create_mem_process(MemProc * memProc, struct process * proc)
+{
+	int i;
+	unsigned int e;
+	/* Unused so removed ;) */
+	/* int NumProcess = memProc->In.NumProcess; */
+	unsigned long * cr3, * tt;
+	// On commence par créer pgtable et ttpage
+	// pg_table
+	//  printk("coucou\n");
+	struct Space * aSpace = mm_create_space(3);
+	proc->space = aSpace;
+	memProc->Out.cr3 = (unsigned int) mm_get_phys_cr3(aSpace);
+	proc->meminfo = (void *) mm_get_phys_meminfo(proc->space);
 
+	//  printk("coucou2\n");
+	e = 0xc0000000;
 
-struct zone zones[MAX_ZONES];
-struct page *mem_map;
+	// Mettons tout ça ŕ 0
+	cr3 = (unsigned long *) mm_get_cr3(aSpace);
+	tt = (unsigned long *) mm_get_cr3(aSpace) + 0x1000/sizeof(unsigned long);
+	//  printk("coucou3 %x %x\n",cr3,tt);
+	for(i = 0; i < 1024; i++)
+	{
+		cr3[i] = 0;
+	}
+	//  printk("coucou4\n");
 
-void zone_init (int id, const char *name, paddr_t start, uint32_t size);
-uint32_t mem_map_lowmem_init (void);
-void mem_map_fixup (uint32_t size);
+	// On enregistre la zone de code
+	memProc->Out.CodeEntry = (void *)e;
 
-static int lowmem_initialized = 0;
-/* static int highmem_initialized = 0; */
+	// On implante les pages de code, et on les partage
+	if (mm_add_section(aSpace, memProc->In.CodeEntry, memProc->In.NbCodePage, (void *) e))
+		panic ("CreateMemProcess(): unable to allocate code pages");
+	e += 0x1000 * memProc->In.NbCodePage;
+	// On enregistre la zone de data
+	memProc->Out.DataEntry = (void *)e;
 
-/* Initialize physical memory manager */
-void mem_init (void)
+	// On implante les pages de data, et on les partage
+	if (mm_add_section(aSpace, memProc->In.DataEntry, memProc->In.NbDataPages, (void *) e))
+		panic ("CreateMemProcess(): unable to allocate data pages");
+	e += 0x1000 * (memProc->In.NbDataPages);
+
+	// On implante les pages de stack, et on les partage
+	if (mm_add_section(aSpace, memProc->In.StackEntry, memProc->In.NbStackPages, (void *) e))
+		panic ("CreateMemProcess(): unable to allocate stack pages");
+	e += 0x1000 * memProc->In.NbStackPages;
+
+	// On enregistre la zone de stack
+	memProc->Out.StackEntry = (void *)(e - 0x1);
+
+	// On mappe le premier méga du kernel
+	for(i=0; i < KERNEL_ID_PAGES; i++)
+	{
+#ifndef MM_NG
+		page_map ((pg_entry_t **) cr3, (void *) (i * PAGE_SIZE), (void *) (i * PAGE_SIZE));
+#endif
+	}
+
+    // On mappe la pile kernel du process
+    e = (proc->stack - KSTACK_SZ) & 0xfffff000;
+    while (e < proc->stack) {
+        if (page_map((pg_entry_t **) cr3, page_addr((pg_entry_t **) KERNEL_PG_DIR, (void *) e),
+          (void *) e) != 0) {
+            panic("create_mem_process(): unable to map new process' kernel stack");
+        }
+        e += PAGE_SIZE;
+    }
+
+	return 0;
+}
+
+int kernel_clean(MemProc * memProc)
 {
-	uint32_t sz;
-
-	e820_map_init ();
-
-	mem_map = (struct page *) (KERN_PHYS_END_ADDR + KERNEL_OFFSET);	
-
-	/* Init the first 896 MB map */
-	sz = mem_map_lowmem_init ();
-	/* Fix memrory map */
-	mem_map_fixup (sz);
-
-	/* Initialize zones */
-	zone_init (0, "LOWMEM", 0, sz);
-
-	lowmem_initialized = 1;
+	int i;
+	int err = 0;
+	// On libére les pages de code
+	for(i = 0; i < memProc->In.NbCodePage; i++)
+	{
+#ifndef MM_NG
+		page_unmap ((pg_entry_t **) KERNEL_PG_DIR, memProc->Out.CodeEntry + ( i * PAGE_SIZE));
+#endif
+	}
+	// On libčre les pages de data
+	for(i = 0; i < memProc->In.NbDataPages; i++)
+	{
+#ifndef MM_NG
+		page_unmap ((pg_entry_t **) KERNEL_PG_DIR, memProc->Out.DataEntry + ( i * PAGE_SIZE));
+#endif
+	}
+	// On libčre les pages de stack
+	for(i = 0; i < memProc->In.NbStackPages; i++)
+	{
+#ifndef MM_NG
+		page_unmap ((pg_entry_t **) KERNEL_PG_DIR, memProc->Out.StackEntry - ( i * PAGE_SIZE));
+#endif
+	}
+	return err;
 }
 
 
-/* Fill mem_map for the first 896 MB. Return the number of pages initialized.
- * XXX: This require 1 page for each MB of RAM
- * Since we only initialize lowmem, we need at most 896 pages (about 3-4 MB).
- */
-
-uint32_t mem_map_lowmem_init (void)
+// Pourquoi ne pas tout simplement reprendre memProc? D'une part, parce que ça
+// obligerait ŕ le garder dans un coin. C'est bof. D'autre part, il a pu y avoir des allocations mémoires dynamiques, et memProcess est pas forcément au courant... Bref, faisons quelque chose de propre et de général!!
+int free_mem_process(unsigned long cr3, unsigned int meminfo)
 {
-	uint32_t count;
-
-	for (count = 0; count < minfo.phys_pages && count < LOWMEM_PAGES; count++)
-		memset4 (&mem_map[count], 0, sizeof (struct page) / 4);
-
-	return count;
+	// On appelle en fait la fonction dans mem.c, mais c'est pour avoir un peu
+	// de logique
+	meminfo = 0;
+#ifndef MM_NG
+	page_flush ((pg_entry_t **) cr3);
+#endif
+	return meminfo;
 }
 
-
-/* Fix up mem_map, avoid some physical pages from being allocated */
-
-void mem_map_fixup (uint32_t size)
-{
-	int i;
-	uint32_t page;
-
-	/* Page 0 is unusable on some computers */
-	mem_map[0].flags = PAGE_UNUSABLE;
-	minfo.usable_pages = size - 1;
-
-	for (page = 0, i = 0; i < minfo.map.n_entries; i++) {
-		uint32_t start_page, end_page;
-
-		/* Round to pages, discard incomplete pages */
-		start_page = (((uint32_t) minfo.map.entries[i].start) + PAGE_SIZE - 1) >> PAGE_SHIFT;
-		end_page = ((uint32_t) (minfo.map.entries[i].start + minfo.map.entries[i].size)) >> PAGE_SHIFT;
-
-		/* Holes in e820 are not usable */
-		while (page  < start_page) {
-			mem_map[page++].flags = PAGE_UNUSABLE;
-			minfo.usable_pages--;
-		}
-
-		if (minfo.map.entries[i].type != E820_RAM) {
-			while (page <= end_page) {
-				mem_map[page++].flags = PAGE_UNUSABLE;
-				minfo.usable_pages--;
-			}
-		}
-		else
-			page = end_page + 1;
-	}
-
-	for (page = KERN_PHYS_ADDR >> PAGE_SHIFT; page < (KERN_PHYS_END_ADDR >> PAGE_SHIFT) + size; page++)
-		mem_map[page].flags = PAGE_KERNEL;
-}
-
-
-void zone_init (int id, const char *name, paddr_t start, uint32_t size)
-{
-	zones[id].name = name;
-	zones[id].start = start;
-	zones[id].size = size;
-	zones[id].map = &mem_map[start >> PAGE_SHIFT];
-
-	if (!lowmem_initialized) {	/* Can't page_alloc() now */
-		uint32_t page;
-		struct page *ptr;
-		int i;
-		paddr_t p;
-
-		for (p = LOWMEM_BUDDY_START, i = 0; i < FREE_AREA_CNT; i++) {
-			zones[id].areas[i].list.prev = zones[id].areas[i].list.next = NULL;
-			zones[id].areas[i].map = (uint8_t *) (p + KERNEL_OFFSET);
-			if (i > 0)
-				/* Setting one word after won't harm */
-				memset4 ((void *) (p + KERNEL_OFFSET), 0, (((size >> PAGE_SHIFT) / (1 << i)) / 64) + 1);
-			p += ((size >> PAGE_SHIFT) / (1 << i)) / 16;
-		}
-
-		p  = ((p + PAGE_SIZE - 1) >> PAGE_SHIFT);
-
-		for (page = (LOWMEM_BUDDY_START  >> PAGE_SHIFT); page < p; page++)
-			mem_map[page].flags = PAGE_KERNEL;
-
-		/* Ok now fill bitmaps and free lists */
-		for (ptr = zones[id].map, i = 0; i < (size - start) >> PAGE_SHIFT; ptr++, i++);
-			
-	}
-}
-
-
-#endif	/* MM_NG */
-
main/kernel/mm/rbmap.c to main/kernel/kernel/x86_32/test.S
--- a/main/kernel/mm/rbmap.c
+++ b/main/kernel/kernel/x86_32/test.S
@@ -1,340 +1,514 @@
-/* $Id: rbmap.c,v 1.9 2006/10/09 19:24:14 rmp91 Exp $
- *
- * RAM BitMAP implementation
- *
- */
- 
-#include <btypes.h>
-#include <mem.h>
-#include <rbmap.h>
-#include <paging.h>
-#include <process.h>
-#include <stdio.h>
-#include <panic.h>
-#include <console.h>
-
-/* #define RBMAP_DEBUG(_f, _a...) early_printk(_f, ## _a) */
-#define RBMAP_DEBUG(_f, _a...) ((void) 0)
-
-
-/* Check if page can be used */
-int rbmap_page_check (void *page);
-/* Mark page as used */
-void rbmap_page_alloc (void *page);
-/* Mark page as free */
-void rbmap_page_free (void *page);
-/* Allocates and link a new entry in the bmap index */
-rbmap_t *rbmap_entry_alloc (int id);
-/* Free and unlink an entry from the bmap index */
-void rbmap_entry_free (int id);
-/* Is the whole entry pointing on free pages ? */
-int rbmap_is_empty_entry (int id);
-/* Process the page physical address to entry and table offset */
-void rbmap_page_addr (void *page, int *entry, int *offset);
-
-
-/* RAM BitMAP index */
-static rbmap_t *rbmap[RAM_BITMAP_IDX_ENTRIES];
-/* An allocated but unused page 
- * We use it to ensure there will only be at least one free page to create a new entry
- */
-static void *next_page = NULL;
-
-void rbmap_init (void)
-{
-	RBMAP_DEBUG("rbmap_init()\n");
-
-	memset4 (rbmap, 0, RAM_BITMAP_IDX_ENTRIES);
-	
-	rbmap[0] = (rbmap_t *) RAM_BITMAP_ENTRY_0;
-
-	page_zerofill ((void *) RAM_BITMAP_ENTRY_0);	/* Clears entry 0 */
-
-	/* Mark first meg as used */
-	/* XXX: Must be sure that DYNAMIC OFFSET % RAM_BITMAP_PAGES_PER_ENTRY == 0 */
-	memset1 (rbmap[0], 0xff, (uint32_t) DYNAMIC_RAM_OFFSET / RAM_BITMAP_PAGES_PER_ENTRY);
-	minfo.used_pages = (uint32_t) DYNAMIC_RAM_OFFSET / PAGE_SIZE;
-	
-	/* Prealloc next_page */
-	next_page = rbmap_find_free_page ();
-	rbmap_page_alloc (next_page);
-}
-
-
-void rbmap_page_addr (void *page, int *entry, int *offset)
-{
-	uint32_t addr;
-	
-	addr = ((uint32_t) page) >> PAGE_SIZE_LOG;
-
-	if (offset)
-		*offset = addr & (RAM_BITMAP_PAGES_PER_ENTRY - 1);
-	addr >>= RAM_BITMAP_ENTRY_SIZE_LOG;
-
-	if (entry)
-		*entry = addr & (RAM_BITMAP_IDX_ENTRIES - 1);
-}
-
-int rbmap_is_free (void *page)
-{
-	int entry, offset;
-
-	rbmap_page_addr (page, &entry, &offset);
-
-	if (! rbmap[entry] || ! (rbmap[entry])[offset])
-		return 1;
-	return 0;
-}
-
-int rbmap_is_empty_entry (int id)
-{
-	int i;
-	uint32_t *p;
-	
-	if (! rbmap[id])
-		return 1;
-
-	p = (uint32_t *) rbmap[id];
-
-	for (i = 0; i < RAM_BITMAP_ENTRY_SIZE / 4; i++, p++)
-		if (*p)
-			return 0;
-	return 1;
-}
-
-void rbmap_page_alloc (void *page)
-{
-	int entry, offset;
-	rbmap_t *p;
-
-	RBMAP_DEBUG("rbmap_page_alloc(0x%x)\n",  page);
-
-	rbmap_page_addr (page, &entry, &offset);
-
-	if (! rbmap[entry])
-		p = rbmap_entry_alloc (entry);
-	else
-		p = rbmap[entry];
-
-	if (p[offset])
-		panic ("rbmap_page_alloc(): trying to allocate used page");
-
-	p[offset] = 1;
-	minfo.used_pages++;
-}
-
-void rbmap_page_free (void *page)
-{
-	int entry, offset;
-	rbmap_t *p;
-	
-	if (page < (void *) DYNAMIC_RAM_OFFSET)
-		panic ("bmap_page_free(): attempting to free staticaly allocated page!");
-	
-	rbmap_page_addr (page, &entry, &offset);
-	
-	p = rbmap[entry];
-
-	if (! p[offset])
-		panic ("rbmap_page_free(): attempting to free free page");
-
-	p[offset] = 0;
-	
-	minfo.used_pages--;
-
-	if (rbmap_is_empty_entry (entry))
-		rbmap_entry_free (entry);
-}
-
-rbmap_t *rbmap_entry_alloc (int id)
-{
-	rbmap_t *new_entry;
-
-	RBMAP_DEBUG("rbmap_entry_alloc(%d) (next_page 0x%x)\n", id, next_page);
-
-	if (rbmap[id])
-		panic ("rbmap_entry_alloc(): trying to realloc allocated entry!");
-
-	/* rbmap manage PAs, but we need a VA to access it! */
-	new_entry = (rbmap_t *) page_map_any((pg_entry_t **) KERNEL_PG_DIR, next_page);
-	if (new_entry == NULL)
-		panic("rbmap_entry_alloc(): out of virtual memory!");
-	page_zerofill (new_entry);
-
-	rbmap[id] = new_entry;
-
-	next_page = rbmap_find_free_page ();
-	rbmap_alloc (next_page);
-
-	return new_entry;
-}
-
-void rbmap_entry_free (int id)
-{
-	if (id == 0)
-		panic ("rbmap_entry_free(): trying to free static entry #0!");
-
-	if (! rbmap[id])
-		panic ("rbmap_entry_free(): attempting to free free entry!");
-	
-	rbmap_page_free (rbmap[id]);
-
-	rbmap[id] = NULL;
-}
-
-int rbmap_page_check (void *page)
-{
-	int i;
-
-	if (page < (void *) DYNAMIC_RAM_OFFSET || page > (void *) (((minfo.lowmem + minfo.highmem) * 1024) - PAGE_SIZE))
-		return 0;
-
-	for (i = 0; i < minfo.map.n_entries; i++) {
-		uint32_t beg, end;
-		
-		/* XXX: Casting 64 bit integers to 32 bits integer may no be safe */
-		beg = (uint32_t) minfo.map.entries[i].start;
-		end = beg + (uint32_t) minfo.map.entries[i].size;
-
-		/* Round up to page size */
-		beg = ((beg / PAGE_SIZE) + 1) * PAGE_SIZE;
-		end = (end / PAGE_SIZE) * PAGE_SIZE;
-
-		if (beg > (uint32_t) page || (end - PAGE_SIZE) < (uint32_t) page)
-			continue;
-
-		/* Area matched */
-		if (minfo.map.entries[i].type == E820_RAM)
-			return 1;		/* Page is in usable RAM area */
-		else
-			return 0;
-
-	}
-
-	return 0;
-}
-
-void * rbmap_find_free_page (void)
-{
-	int i;
-
-	RBMAP_DEBUG("rbmap_find_free_page()\n");
-
-	/* TODO: count avail pages to speed up when full memory */
-
-	for (i = 0; i < minfo.map.n_entries; i++) {
-		uint32_t beg, end;
-
-		if (minfo.map.entries[i].type != E820_RAM)
-			continue;	/* Not usable, pass */
-		
-		/* XXX: Casting 64 bit integers to 32 bits integer may no be safe */
-		beg = (uint32_t) minfo.map.entries[i].start;
-		end = beg + (uint32_t) minfo.map.entries[i].size;
-		
-		if (end < (uint32_t) DYNAMIC_RAM_OFFSET)
-			continue;
-
-		/* Search only in dynamic ram area */
-		if (beg < (uint32_t) DYNAMIC_RAM_OFFSET)
-			beg = (uint32_t) DYNAMIC_RAM_OFFSET;
-
-		/* Round up to page size */
-		beg = ((beg / PAGE_SIZE) + 1) * PAGE_SIZE;
-		end = (end / PAGE_SIZE) * PAGE_SIZE;
-
-		while (beg < end) {
-			if (rbmap_is_free ((void *) beg))
-				return (void *) beg;
-			beg += PAGE_SIZE;
-		}
-	}
-
-	return NULL;
-}
-
-
-int rbmap_alloc (void *page)
-{
-	RBMAP_DEBUG("rbmap_alloc(0x%x)\n", page);
-
-	if (!rbmap_page_check (page))
-		return -1;
-
-	if (!rbmap_is_free (page))
-		return -1;
-
-	rbmap_page_alloc (page);
-
-	return 0;
-}
-
-void rbmap_free (void *page)
-{
-	if (!rbmap_page_check (page))
-		panic ("rbmap_free(): trying to free unusable page!");
-
-	if (rbmap_is_free (page))
-		panic ("rbmap_free(): attempting to free free page!");
-
-	rbmap_page_free (page);
-}
-
-
-void *rbmap_alloc_any (void)
-{
-	void *phys_page = NULL;
-	
-	RBMAP_DEBUG("rbmap_alloc_any()\n");
-	
-	while (!phys_page) 
-	{
-		if (!(phys_page = rbmap_find_free_page ()))
-			panic ("rbmap_alloc_any(): no more physical page available");
-
-		if (rbmap_alloc (phys_page))	/* Someone has allocated it before us */
-			phys_page = NULL;
-	}
-
-	return phys_page;
-}
-
-
-int rbmap_share (void *page)
-{
-	int entry, offset;
-	rbmap_t *p;
-	
-	rbmap_page_addr (page, &entry, &offset);
-
-	p = rbmap[entry];
-
-	if (! p[offset])
-		return -1;
-
-	p[offset]++;
-
-	return 0;
-}
-
-
-int rbmap_unshare (void *page)
-{
-	int entry, offset;
-	rbmap_t *p;
-	
-	rbmap_page_addr (page, &entry, &offset);
-
-	p = rbmap[entry];
-
-	if (! p[offset])
-		return -1;
-
-	p[offset]--;
-	
-	if (! p[offset])
-		minfo.used_pages--;
-
-	return 0;
-}
-
+	.file	"kalloc.c"
+	.section	.rodata
+	.align 4
+.LC0:
+	.string	"kalloc_init(): unable to alloc first heap page!"
+	.text
+.globl kalloc_init
+	.type	kalloc_init, @function
+kalloc_init:
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$40, %esp
+	movl	$536870912, heap
+	movl	$4096, heap+8
+	movl	heap, %eax
+	movl	$barbux_pg_dir_addr, %edx
+	movl	%eax, 4(%esp)
+	movl	%edx, (%esp)
+	call	page_alloc
+	testl	%eax, %eax
+	je	.L2
+	movl	$.LC0, (%esp)
+	call	panic
+.L2:
+	movl	heap, %eax
+	movl	$12, 8(%esp)
+	movl	$0, 4(%esp)
+	movl	%eax, (%esp)
+	call	memset1
+	movl	$1, minfo+656
+	movl	heap, %eax
+	addl	$4096, %eax
+	movl	$barbux_pg_dir_addr, %edx
+	movl	$1023, 12(%esp)
+	movl	$512, 8(%esp)
+	movl	%eax, 4(%esp)
+	movl	%edx, (%esp)
+	call	pages_add_flags
+	movl	$1, -8(%ebp)
+	movl	$541065216, -4(%ebp)
+	jmp	.L4
+.L5:
+	movl	-8(%ebp), %eax
+	subl	$-128, %eax
+	movl	$barbux_pg_dir_addr, %edx
+	movl	%eax, 4(%esp)
+	movl	%edx, (%esp)
+	call	page_table_alloc
+	movl	-4(%ebp), %eax
+	movl	$barbux_pg_dir_addr, %edx
+	movl	$1024, 12(%esp)
+	movl	$512, 8(%esp)
+	movl	%eax, 4(%esp)
+	movl	%edx, (%esp)
+	call	pages_add_flags
+	leal	-8(%ebp), %eax
+	incl	(%eax)
+	leal	-4(%ebp), %eax
+	addl	$4194304, (%eax)
+.L4:
+	movl	-8(%ebp), %eax
+	cmpl	$3, %eax
+	jbe	.L5
+	movl	heap, %eax
+	movl	%eax, heap+4
+	movl	$0, heap+12
+	movl	$1, 4(%esp)
+	movl	$heap+16, (%esp)
+	call	mutex_init
+	leave
+	ret
+	.size	kalloc_init, .-kalloc_init
+.globl kalloc
+	.type	kalloc, @function
+kalloc:
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$8, %esp
+	movl	$1, 4(%esp)
+	movl	8(%ebp), %eax
+	movl	%eax, (%esp)
+	call	do_kalloc
+	leave
+	ret
+	.size	kalloc, .-kalloc
+.globl kzalloc
+	.type	kzalloc, @function
+kzalloc:
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$8, %esp
+	movl	$3, 4(%esp)
+	movl	8(%ebp), %eax
+	movl	%eax, (%esp)
+	call	do_kalloc
+	leave
+	ret
+	.size	kzalloc, .-kzalloc
+.globl kalloc_mutex
+	.type	kalloc_mutex, @function
+kalloc_mutex:
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$8, %esp
+	movl	$0, 4(%esp)
+	movl	8(%ebp), %eax
+	movl	%eax, (%esp)
+	call	do_kalloc
+	leave
+	ret
+	.size	kalloc_mutex, .-kalloc_mutex
+.globl kfree
+	.type	kfree, @function
+kfree:
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$8, %esp
+	movl	$1, 4(%esp)
+	movl	8(%ebp), %eax
+	movl	%eax, (%esp)
+	call	do_kfree
+	leave
+	ret
+	.size	kfree, .-kfree
+.globl kfree_mutex
+	.type	kfree_mutex, @function
+kfree_mutex:
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$8, %esp
+	movl	$0, 4(%esp)
+	movl	8(%ebp), %eax
+	movl	%eax, (%esp)
+	call	do_kfree
+	leave
+	ret
+	.size	kfree_mutex, .-kfree_mutex
+	.section	.rodata
+	.align 4
+.LC1:
+	.string	"do_kalloc(): unable to increase heap size"
+	.text
+.globl do_kalloc
+	.type	do_kalloc, @function
+do_kalloc:
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$56, %esp
+	movl	8(%ebp), %eax
+	addl	$12, %eax
+	movl	%eax, 8(%ebp)
+	cmpl	$31, 8(%ebp)
+	jg	.L19
+	movl	$32, 8(%ebp)
+.L19:
+	movl	8(%ebp), %edx
+	decl	%edx
+	movl	%edx, %eax
+	sarl	$31, %eax
+	shrl	$30, %eax
+	addl	%edx, %eax
+	sarl	$2, %eax
+	sall	$2, %eax
+	addl	$4, %eax
+	movl	%eax, 8(%ebp)
+	movl	12(%ebp), %eax
+	andl	$1, %eax
+	testb	%al, %al
+	je	.L21
+	movl	heap+16, %eax
+	movl	%eax, (%esp)
+	call	mutex_lock
+.L21:
+	movl	8(%ebp), %edx
+	movl	heap+12, %eax
+	cmpl	%eax, %edx
+	jbe	.L23
+	movl	heap+4, %eax
+	movl	%eax, -20(%ebp)
+	jmp	.L25
+.L23:
+	movl	heap, %eax
+	movl	%eax, -20(%ebp)
+	jmp	.L26
+.L27:
+	movl	-20(%ebp), %eax
+	movl	8(%eax), %eax
+	andl	$1, %eax
+	testb	%al, %al
+	jne	.L28
+	movl	-20(%ebp), %eax
+	movl	4(%eax), %eax
+	movl	%eax, %edx
+	movl	-20(%ebp), %eax
+	movl	%edx, %ecx
+	subl	%eax, %ecx
+	movl	%ecx, %eax
+	movl	%eax, -4(%ebp)
+	movl	-4(%ebp), %eax
+	cmpl	8(%ebp), %eax
+	jl	.L28
+	movl	8(%ebp), %eax
+	addl	$32, %eax
+	cmpl	-4(%ebp), %eax
+	jge	.L31
+	movl	-20(%ebp), %eax
+	movl	%eax, %edx
+	movl	8(%ebp), %eax
+	leal	(%edx,%eax), %eax
+	movl	%eax, -16(%ebp)
+	movl	-20(%ebp), %eax
+	movl	4(%eax), %edx
+	movl	-16(%ebp), %eax
+	movl	%edx, 4(%eax)
+	movl	-16(%ebp), %edx
+	movl	-20(%ebp), %eax
+	movl	%eax, (%edx)
+	movl	-16(%ebp), %eax
+	movl	4(%eax), %edx
+	movl	-16(%ebp), %eax
+	movl	%eax, (%edx)
+	movl	-20(%ebp), %edx
+	movl	-16(%ebp), %eax
+	movl	%eax, 4(%edx)
+	movl	-16(%ebp), %eax
+	movl	8(%eax), %eax
+	movl	%eax, %edx
+	andl	$-2, %edx
+	movl	-16(%ebp), %eax
+	movl	%edx, 8(%eax)
+	jmp	.L33
+.L31:
+	movl	-4(%ebp), %eax
+	movl	%eax, 8(%ebp)
+.L33:
+	movl	-20(%ebp), %eax
+	movl	8(%eax), %eax
+	movl	%eax, %edx
+	orl	$1, %edx
+	movl	-20(%ebp), %eax
+	movl	%edx, 8(%eax)
+	movl	12(%ebp), %eax
+	shrl	%eax
+	andl	$1, %eax
+	testb	%al, %al
+	je	.L34
+	movl	8(%ebp), %eax
+	subl	$12, %eax
+	movl	-20(%ebp), %edx
+	addl	$12, %edx
+	movl	%eax, 8(%esp)
+	movl	$0, 4(%esp)
+	movl	%edx, (%esp)
+	call	memset4
+.L34:
+	movl	12(%ebp), %eax
+	andl	$1, %eax
+	testb	%al, %al
+	je	.L36
+	movl	heap+16, %eax
+	movl	%eax, (%esp)
+	call	mutex_unlock
+.L36:
+	movl	-20(%ebp), %eax
+	addl	$12, %eax
+	movl	%eax, -36(%ebp)
+	jmp	.L38
+.L28:
+	movl	-20(%ebp), %eax
+	movl	4(%eax), %eax
+	movl	%eax, -20(%ebp)
+.L26:
+	movl	-20(%ebp), %eax
+	movl	4(%eax), %eax
+	testl	%eax, %eax
+	jne	.L27
+.L25:
+	movl	-20(%ebp), %eax
+	andl	$-4096, %eax
+	movl	%eax, -12(%ebp)
+	movl	-20(%ebp), %eax
+	movl	%eax, %edx
+	movl	8(%ebp), %eax
+	leal	(%edx,%eax), %eax
+	addl	$12, %eax
+	andl	$-4096, %eax
+	movl	%eax, -8(%ebp)
+	jmp	.L50
+.L40:
+	leal	-12(%ebp), %eax
+	addl	$4096, (%eax)
+	movl	-12(%ebp), %eax
+	movl	$barbux_pg_dir_addr, %edx
+	movl	%eax, 4(%esp)
+	movl	%edx, (%esp)
+	call	page_used
+	testl	%eax, %eax
+	jne	.L39
+	movl	-12(%ebp), %eax
+	movl	$barbux_pg_dir_addr, %edx
+	movl	%eax, 4(%esp)
+	movl	%edx, (%esp)
+	call	page_alloc
+	testl	%eax, %eax
+	je	.L42
+	movl	$.LC1, (%esp)
+	call	panic
+.L42:
+	movl	minfo+656, %eax
+	incl	%eax
+	movl	%eax, minfo+656
+.L39:
+.L50:
+	movl	-12(%ebp), %eax
+	cmpl	-8(%ebp), %eax
+	jb	.L40
+	movl	-20(%ebp), %eax
+	movl	%eax, %edx
+	movl	8(%ebp), %eax
+	leal	(%edx,%eax), %eax
+	movl	%eax, -16(%ebp)
+	movl	$12, 8(%esp)
+	movl	$0, 4(%esp)
+	movl	-16(%ebp), %eax
+	movl	%eax, (%esp)
+	call	memset1
+	movl	-16(%ebp), %edx
+	movl	-20(%ebp), %eax
+	movl	%eax, (%edx)
+	movl	-20(%ebp), %edx
+	movl	-16(%ebp), %eax
+	movl	%eax, 4(%edx)
+	movl	-20(%ebp), %eax
+	movl	8(%eax), %eax
+	movl	%eax, %edx
+	orl	$1, %edx
+	movl	-20(%ebp), %eax
+	movl	%edx, 8(%eax)
+	movl	-16(%ebp), %eax
+	movl	%eax, heap+4
+	movl	12(%ebp), %eax
+	shrl	%eax
+	andl	$1, %eax
+	testb	%al, %al
+	je	.L45
+	movl	8(%ebp), %eax
+	subl	$12, %eax
+	movl	-20(%ebp), %edx
+	addl	$12, %edx
+	movl	%eax, 8(%esp)
+	movl	$0, 4(%esp)
+	movl	%edx, (%esp)
+	call	memset4
+.L45:
+	movl	12(%ebp), %eax
+	andl	$1, %eax
+	testb	%al, %al
+	je	.L47
+	movl	heap+16, %eax
+	movl	%eax, (%esp)
+	call	mutex_unlock
+.L47:
+	movl	-20(%ebp), %ecx
+	addl	$12, %ecx
+	movl	%ecx, -36(%ebp)
+.L38:
+	movl	-36(%ebp), %eax
+	leave
+	ret
+	.size	do_kalloc, .-do_kalloc
+	.section	.rodata
+	.align 4
+.LC2:
+	.string	"do_kree(): memory area unused according to kalloc header"
+	.text
+.globl do_kfree
+	.type	do_kfree, @function
+do_kfree:
+	pushl	%ebp
+	movl	%esp, %ebp
+	subl	$24, %esp
+	movl	8(%ebp), %eax
+	subl	$12, %eax
+	movl	%eax, -8(%ebp)
+	movl	12(%ebp), %eax
+	andl	$1, %eax
+	testb	%al, %al
+	je	.L52
+	movl	heap+16, %eax
+	movl	%eax, (%esp)
+	call	mutex_lock
+.L52:
+	movl	-8(%ebp), %eax
+	movl	8(%eax), %eax
+	andl	$1, %eax
+	testl	%eax, %eax
+	jne	.L54
+	movl	$.LC2, (%esp)
+	call	panic
+.L54:
+	movl	-8(%ebp), %eax
+	movl	8(%eax), %eax
+	movl	%eax, %edx
+	andl	$-2, %edx
+	movl	-8(%ebp), %eax
+	movl	%edx, 8(%eax)
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %eax
+	movl	%eax, %edx
+	movl	-8(%ebp), %eax
+	movl	%edx, %ecx
+	subl	%eax, %ecx
+	movl	%ecx, %eax
+	sarl	$2, %eax
+	imull	$-1431655765, %eax, %eax
+	movl	%eax, -4(%ebp)
+	movl	-8(%ebp), %eax
+	movl	(%eax), %eax
+	testl	%eax, %eax
+	je	.L56
+	movl	-8(%ebp), %eax
+	movl	(%eax), %eax
+	movl	8(%eax), %eax
+	andl	$1, %eax
+	testl	%eax, %eax
+	jne	.L56
+	movl	-8(%ebp), %edx
+	movl	-8(%ebp), %eax
+	movl	(%eax), %eax
+	movl	%edx, %ecx
+	subl	%eax, %ecx
+	movl	%ecx, %eax
+	sarl	$2, %eax
+	imull	$-1431655765, %eax, %eax
+	movl	%eax, %edx
+	leal	-4(%ebp), %eax
+	addl	%edx, (%eax)
+	movl	-8(%ebp), %eax
+	movl	(%eax), %edx
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %eax
+	movl	%eax, 4(%edx)
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %eax
+	testl	%eax, %eax
+	je	.L59
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %edx
+	movl	-8(%ebp), %eax
+	movl	(%eax), %eax
+	movl	%eax, (%edx)
+.L59:
+	movl	-8(%ebp), %eax
+	movl	(%eax), %eax
+	movl	%eax, -8(%ebp)
+.L56:
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %eax
+	testl	%eax, %eax
+	je	.L61
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %eax
+	movl	8(%eax), %eax
+	andl	$1, %eax
+	testl	%eax, %eax
+	jne	.L61
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %eax
+	movl	4(%eax), %eax
+	testl	%eax, %eax
+	je	.L61
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %eax
+	movl	%eax, %edx
+	movl	-8(%ebp), %eax
+	movl	%edx, %ecx
+	subl	%eax, %ecx
+	movl	%ecx, %eax
+	sarl	$2, %eax
+	imull	$-1431655765, %eax, %eax
+	movl	%eax, %edx
+	leal	-4(%ebp), %eax
+	addl	%edx, (%eax)
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %eax
+	movl	4(%eax), %edx
+	movl	-8(%ebp), %eax
+	movl	%edx, 4(%eax)
+	movl	-8(%ebp), %eax
+	movl	4(%eax), %edx
+	movl	-8(%ebp), %eax
+	movl	%eax, (%edx)
+.L61:
+	movl	-4(%ebp), %edx
+	movl	heap+12, %eax
+	cmpl	%eax, %edx
+	jbe	.L65
+	movl	-4(%ebp), %eax
+	movl	%eax, heap+12
+.L65:
+	movl	12(%ebp), %eax
+	andl	$1, %eax
+	testb	%al, %al
+	je	.L69
+	movl	heap+16, %eax
+	movl	%eax, (%esp)
+	call	mutex_unlock
+.L69:
+	leave
+	ret
+	.size	do_kfree, .-do_kfree
+	.comm	heap,20,4
+	.ident	"GCC: (GNU) 4.0.3 20060212 (prerelease) (Debian 4.0.2-9)"
+	.section	.note.GNU-stack,"",@progbits
1 2 3 .. 6 > >> (Page 1 of 6)