使用简单的字符驱动程序作为控制台引导 linux 内核?

Booting linux kernel using a simple char driver as console?

我正在尝试在学术项目的 Sparc v8 处理器仿真模型上启动 linux 内核 (v3.16.1)。

仿真模型由 cpu、内存、定时器和一个简单的基于轮询的输出设备组成。我们修改了内核,因此不需要引导加载程序。我们直接把内核映像放在内存中,设置一些必要的变量,然后跳转到内核代码。我们有一个基本的基于轮询的输出设备,我们已经能够将 printk 的输出定向到这个设备。

内核一直引导到“/init”的开头。在这一点之后,没有输出是可见的。就在这之前,显示了一个警告:"Warning: unable to open an initial console." 我的文件系统映像似乎没问题,并且包含一个 /dev/console 节点(我用 Qemu 检查过)。

我的理解是,虽然 printk 工作正常(使用早期的控制台),但用户进程需要一个具有适当设备驱动程序的设备节点才能设置。 Printk 工作正常,那么有没有办法通过 printk 查看用户进程对控制台的所有写入?有一个名为 "ttyprintk" 的现有驱动程序,它将所有写入发送到 printk。我启用它并尝试通过传递 "console=ttyprintk" 内核参数来使用它,但这给出了相同的警告。内核无法打开“/dev/console”进行写入。

我的问题是:

  1. 我可以编写一个简单的字符设备驱动程序并将其用作我的控制台吗?在这个驱动程序中,我计划将所有写入发送到 printk。这可能吗 ?

  2. 如何让内核将其用作我的控制台?内核参数 "console = /dev/MyDriver" 会起作用吗?

  3. 是否有更简单的方法让 /init 和其他用户进程将我的基本输出设备用作控制台?

4.Is 还有其他原因可能导致 "Warning: unable to open an initial console." 消息吗?

感谢任何提示。我是内核编程的新手。

-neha

/dev/console 驱动程序的工作方式是附加到其他一些 tty 设备(或多个设备!),然后 is/are 将其用于控制​​台。 console 设备的 sysfs 属性 active (try /sys/class/tty/console/active) 会告诉你 console 目前连接到什么设备。

内核也倾向于记录控制台更改:

[    0.186989] dw-apb-uart ffc02000.serial0: ttyS0 at MMIO 0xffc02000 (irq = 194, base_baud = 6250000) is a 16550A
[    0.755529] console [ttyS0] enabled

在上面的日志中,一旦创建了串行端口设备,内核就决定将其用作控制台。这里指的是设备绑定到内核中的驱动程序,而不是/dev中的设备节点。后者在这里无关紧要。还要了解控制台设备与 tty 的连接发生在内核中。 /dev/console 不是指向另一个设备节点的符号链接。

内核选择了 ttyS0,因为我通过内核命令行告诉它,console=ttyS0,115200n8。如果没有控制台参数,内核将使用第一个注册到 register_console().

的控制台

所以这里的问题是如何让 /dev/ttyprintk 附加到 /dev/console。答案似乎是你不能。

解决方法可能是创建自定义 initramfs,将 /dev/console 设备节点从 major 5 minor 1 更改为使用 minor 3,从而将其更改为 /dev/ttyprintk。或者符号链接来实现同样的事情。这应该让 init 使用 ttyprintk 作为它的 stdin/stdout/stderr.

在您的示例中,为您的输出设备编写一个 tty/console 驱动程序是正确的方法。使其成为控制台,然后内核将 printk 发送到那里。