SFS: Simple FileSystem updates [Experimental]

	Usage:
		fdisk hda init
		mkfs hda0
		mount hda0 /a
		ls /a

kernel/oo.s:
	add class_deleteinstance

kernel/partition.s:
	fdisk: cleanup, preserving registers.

kernel/sfs.s:
	recoded pretty much everything.

	Have 2 tables: one for directory entries, and one for the names.
	The mkfs will create one file to show in ls.
	Only the root dir will be shown - nothing else is implemented.
[minor] WIP: ipv6, strcopy

commit to clean workspace for multitasking overhaul
Scheduling cleanup
Implement per-task paging structure.

kernel/hash.s:
	remove obsolete code (gave warning due to reordering in kernel.s).

kernel/kernel.s:
	swap hash.s and mem.s so that mem.s can use the PTR_ARRAY macros.

kernel/idt.s:
	add some more info on page fault.

kernel/mem.s:
	Add malloc_page_phys and mfree_page_phys.
	The code uses a PTR_ARRAY to keep track of all allocated pages,
	and a bitstring array to mark which ones are free.

	Update mem_init: store the high-mem (end of RAM) heap info
	for use in allocating pages. Pages are allocated in a stack-wise
	order.

kernel/paging.s:
	add paging_idmap_page, a replacement for the paging_idmap_4k;
	it takes a physical pointer to the PDE so that other paging
	structures can be managed.  Called from  schedule.s

	Add paging_show_usage1$ (temp hack) to allow to print paging
	info for other than the kernel/main paging structure.

kernel/schedule.s:
	Add 3 fields (4 labels) to the task structure: the PDE,
	the PTE for the low-4Mb where the kernel resides,
	and a PTE for the high-mem where the task paging structure resides.

		NOTE that since 3 pages are used, and pages MAY cross a 4Mb
		boundary, the single high-mem PTE may not suffice.

	scheduler_init: store cr3 in the task structure for task switching.
	The rest is not set up, as this main task should never exit.

	schedule_isr: update CR3 on task switch.

	task_done: free the paging structure.

	schedule_task: call task_setup_paging to allocate and initialize
	the paging structures.
	Compact ebx + edx to ebx (reason for most of the diff in this method).

	add task_setup_paging: allocate 3 pages, copy the PTE for 4mb,
	and enable the 3 pages in both the main paging structure aswell as
	in the new paging structure.
Paging fixes.

kernel/kernel.s:
	call paging_init after mem_init, so that the mem_heap_high_*phys
	are initialized, which is as yet not used until tasks are scheduled.
	However, work to unify paging code will likely allocate the page
	tables in the mem_heap_high area rather than immediately following
	the stack.

kernel/mem.s:
	fix determining physical ram size: don't count type 2 memory.
	In VMWare, using 256mb physical ram, the space just before 4Gb
	is reported in the memory map.

	Remove the 'more' call after printing the memory map.

	cmd_mem$: print paging information.

	malloc_page_phys: fix a bug checking the array size.
	(this one did not trigger in QEMU but did in VMWare).

kernel/schedule.s:
	task_setup_paging: align the base address of the task page tables
	when identity-mapping them in a 4mb range in the kernel paging
	structure.

kernel/vmware/svga2.s:
	add conditional around video startup checking.
Scheduling: implement IO_WAIT (keyboard).

	Tasks can now use YIELD_SEM <addr> instead of YIELD,
	which makes them being scheduled to run conditional on
	the value of <addr>.

kernel/console.s:
	add a 'semaphore' or data-availability counter in the console
	structure. This is only used when VITUAL_CONSOLES is enabled.

	Schedule other console shells with CPL1.

kernel/kernel.s:
	update tls_get: store the current task IDX in the tls structure.

kernel/keyboard.s:
	in the ISR, store the fact that data is available in the current
	console kb sem.

	keyboard: updates so it is callable from non-CPL0 tasks:
		- don't reload DS - causes GPF when called from non-CPL0.
		- use YIELD instead of hlt

	keyboard: k_get$:
		- use hlt when scheduling is disabled; otherwise:
		- if VIRTUAL_CONSOLES: use YIELD_SEM with the console_kb_sem
			This is the first use of the scheduler's WAIT_IO.
		- otherwise, use YIELD and polling

kernel/mutex.s:
	add YIELD_SEM macro, which calls task_wait_io.
	Placed in this file, because the console is included before the
	scheduler.

kernel/schedule.s:
	implement the WAIT_IO flag for tasks. Tasks with this flag set
	are not scheduled to run unless the semaphore indicates there is data.

	scheduler_get_task:
		- copy the actual stack (no functional change, but code is
		  more clear).
		- if TASK_FLAG_WAIT_IO, get task_io_sem_ptr and verify content.

	add task_wait_io: store the stack-arg pointing to a semaphore
	in the current task, set the TASK_WAIT_IO flag, and schedule.

	update cmd_tasks: print the privilege level of the task. This will
	almost always print 0, since most tasks at current call kernel-level
	blocking IO, such as sockets.

	minor: add some conditionals around job scheduling code, which is
	deprecated. Also, implemented task_can_run$, the IO_WAIT version
	for job scheduling - which is not enabled.
Remove debugger.s methods/macros to debug.s

This way they can be used by early-includes such as keyboard.s etc.
Schedule update: bugfixes; IO sem managed by task.

	Let the semaphore be decremented at the same abstraction level
	where it is incremented. This means that IO semaphores can be shared,
	and that the IO sem, from the perspective of the scheduler, is simply
	a remote managed variable indicating whether or not the task can
	be scheduled to run.

kernel/keyboard.s:
	decrease console_kb_sem when YIELD_SEM returns.

kernel/schedule.s:
	create an idle task: when all tasks are WAIT_IO, the scheduler will
	halt the system.

	scheduler_get_task: determine the difference between there being no
	tasks at all (all of them TASK_FLAG_DONE), and all tasks unschedulable
	due to wait states.

	Do not 'lock dec' the semaphore in the scheduler. It is now done by the
	caller, which also determines when to increment it.
	This is REQUIRED, because such semaphores can be shared between
	multiple tasks. (See the description in the next commit).

	task_wait_io: bugfix: SEM_SPINLOCK modifies eax/ecx.
NetQ: use IO_WAIT scheduling.

kernel/net/net.s:
	use a semaphore to prevent scheduling of the netq task
	when there are no packets in the queue.
Implement Socket IO_WAIT scheduling.

kernel/net/socket.s:
	socket_accept, net_sock_deliver_accept:
	  In the case of sockets accepting connections, a single semaphore
	  is used to indicate any connection whatsoever - all tasks waiting for
	  a connection will then be scheduled to run, and only the one that
	  finds a matching incoming connection will decrement the semaphore,
	  whereas the others will find no connection and YIELD_SEM again.

	  Unfortunately, this is the only solution possible at the moment, due
	  to all sockets being allocated in a single malloc to prevent memory
	  scattering. This means that the entire array can be reallocated
	  when it is exhausted, causing the absolute pointers to the array
	  elements to change. This prevents the use of a per-socket semaphore
	  by the scheduler.

	  Alternatively, sockets may be allocated on a per-task basis. However
	  the overhead is extremely small, even for a large number of processes,
	  since all of them will execute the same code using the same data,
	  so that when processes are paged to disk in the future, this will not
	  affect performance.

	  Nonetheless, it can be optimized. However, this commit alone reduces
	  the load enormously by not examining the socket array every so many
	  interrupts.

	socket_buffer_read, net_socket_in_append / net_socket_write:
	  Use a semaphore. At current this seems to work fine, even though
	  it is quite possible that multiple packets can arrive, which are
	  appended to the socket_in_buffer, causing the sem to have a value
	  higher than 1; the read then will decrement it once, leaving it
	  higher than 0, causing the task to be rescheduled. However there
	  is no evidence of this showing up in 'top', as yet.