内核开发注意事项

低级别内核开发

对于内核开发,在 gfxconsole 出现之前需要监控或破坏某些内容的情况并不少见。

如需在 x64 机器上强制启用到旧版串行控制台的日志输出,请传递“kernel.serial=legacy”。如需了解其他串行配置,请参阅 kernel_cmdline.md 中的 kernel.serial 文档。

如需在图形控制台启动之前启用早期控制台,请使用 gfxconsole.early cmdline 选项。如需了解详情,请参阅 kernel_cmdline.md。启用 startup.keep-log-visible 可确保在 gfxconsole 启动后出现时内核日志始终可见。如需完全停用 gfxconsole,您可以通过 driver.<driver name>.disable 停用它绑定到的视频驱动程序。在 skylake 系统上,所有这些选项合起来将如下所示:

$ tools/build-x86/bootserver build-x86/zircon.bin -- gfxconsole.early driver.intel-i915-display.disable

如需直接输出到控制台而不是进行缓冲(在内核冻结时很有用),您可以在 build 中启用 ENABLE_KERNEL_LL_DEBUG,如下所示:

fx set ... --args='kernel_extra_defines=["ENABLE_KERNEL_LL_DEBUG"]'

此外,还有一个内核 cmdline 参数 kernel.bypass-debuglog,此参数可以设置为 true,强制输出到控制台,而不是缓冲。我们同时具有编译开关和 cmdline 参数的原因是,在将 cmdline 解析为强制转到控制台之前,可在内核中执行输出。编译开关设置会替换 cmdline 参数(如果两者都存在)。请注意,编译开关和 cmdline 参数都会停用 irq 驱动的 uart Tx。

更改模块的编译器优化级别

您可以通过在模块 build 参数中进行定义来替换模块的默认 -On 级别:

opt_level := <n>

请求回溯

在用户进程内

出于调试目的,系统崩溃日志记录器可以按请求输出回溯。它需要修改源代码,但在没有调试程序的情况下,或者作为常规的内置调试机制,这样做可能很有用。

#include "src/lib/debug/backtrace-request.h"

void my_function() {
  backtrace_request_all_threads();
}

调用 backtrace\_request 时,会导致调试程序用于断点处理的异常。如果未连接调试程序,系统崩溃日志记录器将处理异常,输出回溯,然后恢复线程。

从内核线程

#include <kernel/thread.h>

void my_function() {
  thread_print_backtrace(get_current_thread(), __GET_FRAME(0));
}

在启动期间导出调试数据

为了支持在前期启动期间测试系统,我们提供了一种机制,可将数据文件从内核导出到 /boot 文件系统。如需导出数据,请创建一个 VMO,为其指定名称,然后使用 PA_VMO_DEBUG_FILE 类型的句柄_info(和参数 0)将其传递给 userboot。然后,userboot 会自动将其传递给 devmgr,而 devmgr 会将 VMO 导出为路径下的文件

/boot/kernel/<name-of-vmo>

熵收集器质量测试使用此机制来导出充满随机数据的相对较大(约 1 Mbit)文件。