scripts/tags: Improve source directory selection

This changes the usage of the tags scripts from:

     tags.sh <srcdir>

to:

     tags.sh <directory ...>

The benefit of this is that rather than specifying the top of the source
tree and searching for all C sources within it (including, perhaps in
unwanted locations, such as .git/ or .docs/), you can now run the script
with more precise granularity, such as $ ./scripts/tag.sh path/dir1/
path/dir2/.

The make TAGS target has been update accordingly. Additionally, an unnecessary
variable has been removed.
Top level Makefile improvements

This patch combines three sets of improvements to the top level Makefile
operation:

  1) Replace kernel make target with per-dir targets
  2) Makefile 'run' target does not result in compilation
  3) Make clean target is made more generic

The top level Makefile kernel target has been replaced with an array of
targets, one for each of the members of the array $(SOURCEDIRS). This
allow for directory specific building. New source directories should be added to
this array.

This nos target dependency has been removed from the run target, so that
executing 'make run' does not update the kernel image. From now on, you must
call compilation specifically, using 'make all run'. This decouples the kernel
sources and build state from the operation of the emulator.
paging: Various source refactors and improvements

This patch combines a number of paging source improvements, including:

    1) Use more symbolic constants in memory algorithms.
    2) Fix missing funciton prototype.

The patch defines a set of macro constants in the nos/paging.h header file, such
as PAGE_SIZE and ALIGNMENT_MASK. This helps reduce the quantity of 'magic
numbers' in our code, making it easier to read and maintain.
Add 'todo' script

TMP COMMIT, NEEDS DECRIPTION!
memory: Make destination types void pointers

The idea here is that the memory functions should be type agnostic, so
void pointers is the most appropriate way of expressing this.
Implement contiguous memory allocation and deallocation

This patch supplements the existing placement address algorithm for
memory allocation with a dynamic memory allocation and deallocation
system. Some of the implemented features include:

    1) The heap is defined as a data structure which can be created at
       run time, allowing for multiple different heaps.

    2) Heaps can expand and contract at run-time as necessary.

    3) Heaps contain an index of blocks, sorted by size.

    4) Block allocation occurs on a first fit basis.

    5) A block is book-ended by a header and a footer.

    6) A block can be either active or not (a hole).

    7) Freeing a block changes its status to a hole. On doing so, the
       heap will scan the blocks immediately to the left and right to
       see if they are holes as well. If so, the holes will be
       merged. This prevents fragmentation over time.

Based off of James Molloy's kernel development tutorial, available here:
    http://www.jamesmolloy.co.uk/tutorial_html/7.-The%20Heap.html
ordered-array: Implement destructor