- kernel detects CPUs by searching ACPI tables for local apic nodes
- each CPU has its own TSS that points to its own stack. All cpus boot
on the same boot stack (in sequence) but switch to its private stack
as soon as they can.
- final booting code in main() placed in bsp_finish_booting() which is
executed only after the BSP switches to its final stack
- apic functions to send startup interrupts
- assembler functions to handle CPU features not needed for single cpu
mode like memory barries, HT detection etc.
- new files kernel/smp.[ch], kernel/arch/i386/arch_smp.c and
kernel/arch/i386/include/arch_smp.h
- 16-bit trampoline code for the APs. It is executed by each AP after
receiving startup IPIs it brings up the CPUs to 32bit mode and let
them spin in an infinite loop so they don't do any damage.
- implementation of kernel spinlock
- CONFIG_SMP and CONFIG_MAX_CPUS set by the build system
ask to map in oxpcie i/o memory and support serial i/o for it in the
kernel. set oxpcie=<address> in boot monitor (retrieve address using
pci_debug=1 output). (no sanity checking is done on the address
currently.) disabled by default.
The change also contains some other minor cleanup (a new serial.h to set
register info common to UART and the OXPCIe card, in-kernel memory
mapping a little more structured and env_get() to get sysenv variables
without knowing about the params_buffer).
There is not that much use for it on a single CPU, however, deadlock
between kernel and system task can be delected. Or a runaway loop.
If a kernel gets locked up the timer interrupts don't occure (as all
interrupts are disabled in kernel mode). The only chance is to
interrupt the kernel by a non-maskable interrupt.
This patch generates NMIs using performance counters. It uses the most
widely available performace counters. As the performance counters are
highly model-specific this patch is not guaranteed to work on every
machine. Unfortunately this is also true for KVM :-/ On the other
hand adding this feature for other models is not extremely difficult
and the framework makes it hopefully easy enough.
Depending on the frequency of the CPU an NMI is generated at most
about every 0.5s If the cpu's speed is less then 2Ghz it is generated
at most every 1s. In general an NMI is generated much less often as
the performance counter counts down only if the cpu is not idle.
Therefore the overhead of this feature is fairly minimal even if the
load is high.
Uppon detecting that the kernel is locked up the kernel dumps the
state of the kernel registers and panics.
Local APIC must be enabled for the watchdog to work.
The code is _always_ compiled in, however, it is only enabled if
watchdog=<non-zero> is set in the boot monitor.
One corner case is serial console debugging. As dumping a lot of stuff
to the serial link may take a lot of time, the watchdog does not
detect lockups during this time!!! as it would result in too many
false positives. 10 nmi have to be handled before the lockup is
detected. This means something between ~5s to 10s.
Another corner case is that the watchdog is enabled only after the
paging is enabled as it would be pure madness to try to get it right.
- local APIC timer used as the source of time
- PIC is still used as the hw interrupt controller as we don't have
enough info without ACPI or MPS to set up IO APICs
- remapping of APIC when switching paging on, uses the new mechanism
to tell VM what phys areas to map in kernel's virtual space
- one more step to SMP
based on code by Arun C.
debugging info on panic: decode segment selectors and descriptors, now moved
to arch-specific part, prototypes added; sanity checking in debug.h made
optional with vmassert().
- a better name for architecture specific init function
- some of x86 init code must execute in protected mode
- prot_init() removed from this function and still called in cstart() Imho this
should be called from the architecture specific assembly not cstart. cstart
perform Minix monitor specific tasks and will be touched once another
bootloader is in use, e.g. booting via tftp, therefore we keep it as is for
now.
- this is a backport from the SMP code which requires this. Merging will be simpler
mainly in the kernel and headers. This split based on work by
Ingmar Alting <iaalting@cs.vu.nl> done for his Minix PowerPC architecture
port.
. kernel does not program the interrupt controller directly, do any
other architecture-dependent operations, or contain assembly any more,
but uses architecture-dependent functions in arch/$(ARCH)/.
. architecture-dependent constants and types defined in arch/$(ARCH)/include.
. <ibm/portio.h> moved to <minix/portio.h>, as they have become, for now,
architecture-independent functions.
. int86, sdevio, readbios, and iopenable are now i386-specific kernel calls
and live in arch/i386/do_* now.
. i386 arch now supports even less 86 code; e.g. mpx86.s and klib86.s have
gone, and 'machine.protected' is gone (and always taken to be 1 in i386).
If 86 support is to return, it should be a new architecture.
. prototypes for the architecture-dependent functions defined in
kernel/arch/$(ARCH)/*.c but used in kernel/ are in kernel/proto.h
. /etc/make.conf included in makefiles and shell scripts that need to
know the building architecture; it defines ARCH=<arch>, currently only
i386.
. some basic per-architecture build support outside of the kernel (lib)
. in clock.c, only dequeue a process if it was ready
. fixes for new include files
files deleted:
. mpx/klib.s - only for choosing between mpx/klib86 and -386
. klib86.s - only for 86
i386-specific files files moved (or arch-dependent stuff moved) to arch/i386/:
. mpx386.s (entry point)
. klib386.s
. sconst.h
. exception.c
. protect.c
. protect.h
. i8269.c
instead of keeping a running total of enqueued processes
(because somehow the load average was broken)
. added SI_KPROC_TAB to get a copy of kernel process table from PM, for
a top implementation
. fixed arg to sys_nice() to make it an endpoint, not a slot number
The user needs to set label=... to choose the driver of his or her choice.
This driver will be mapped onto the controller that is set in controller=...
Minor cleanup of kernel source code (boot image table now is static).
- fixed bug that caused IDLE to panic (irq hook inconsistency);
- kprintf() now accepts multiple arguments; moved to utility.c;
- prepare_shutdown() signals system processes with SIGKSTOP;
- phys_fill() renamed to phys_memset(), argument order changed;
- kmemset() removed in favor of phys_kmemset();
- kstrncpy() removed in favor of phys_copy();
- katoi, kstrncmp replaced by normal library procedure again;
- rm_irq_handler() interface changed (simply pass hook pointer);
copied into was the same size as the source string - it will keep on
filling with zeroes forever. This was a signed/unsigned bug, fixed by
making the kstrncpy argument ssize_t instead of size_t. This bug was
triggered by Chris Young <teddga@earthlink.net>, by dazzling coincedence -
changing OS_VERSION into something with one more character (exactly the
same size as the buffer in the kinfo struct).
Also noticed that the kstrncpy() call didn't null-terminate the strings
if necessary, also fixed.
Removed stop sequence when MINIX is shut down.
Disabled send mask checks --- to be replaced by proper mechanism.
Fixed bug relating to 'shutdown -x'.
Simplified clock accounting of realtime.
Updated Makefiles for mkdept script.
caused interrupts to be reenabled (due to unlock), which caused a race. The
problems were especially visible on slower machines.
* Relocated free memory parsing to process manager. This saved quite some
code at the kernel level. Text size was reduced by about 650 bytes.
* Removed locks for updating the realtime in the clock's main loop and the
get_uptime function. Interrupts are no longer reentrant, so realtime is
immediately updated.
Reduced kernel size by 512KB by moving private buffer into cstart() function.
Replaced assertions with erroneous return values. Removed assertions relating
to isuserp(rp), since all processes should become user processes; system
processes are now treated similar to other processes.