Mach has a built-in kernel debugger. Manual.
When you're running a system in QEMU you can directly use GDB on the running kernel.
Alternatively you can use an approach like this one: add the following code
snippet to device/ds_routines.c's ds_device_open function, right at the top
of the function, and modify the code as needed.
void D (char *s)
{
switch (s[0] - '0')
{
case 0:
printf ("Hello from %s!\n", __FUNCTION__);
break;
case 1:
printf ("%s: Invoking task_collect_scan.\n", __FUNCTION__);
extern void task_collect_scan (void);
task_collect_scan ();
break;
default:
printf ("No idea what you want me to do.\n");
break;
}
}
if (name && name[0] == 'D')
D (name + 1);
Then boot your system and do something like this:
# devprobe D0
Hello from D!
# devprobe D1
D: Invoking task_collect_scan.
# devprobe D2
No idea what you want me to do.
This is especially useful if you need to manually trigger some stuff inside the running kernel, as with the D1 example.
If you're doing real low level debugging, you might want to put variations of
the following snipped into the code, this code will write a # character at
line [LINE], column [COLUMN] on the screen:
*((char *) 0xb8000 + 2 * ([LINE] * 80 + [COLUMN])) = '#';
halt_cpu ();
The call of halt_cpu will -- as the name suggests -- halt the system
afterwards. This might be what you want or it might not, but it is needed at
some place when running the kernel inside QEMU, as QEMU somehow decides not to
update its display buffer anymore under certain conditions.
