Kernel Output DesignThis note describes the handling of kernel output in the user-mode driver based design. 1. BackgroundThe move to user-mode drivers has had an unforseen casualty: the kernel debugger. This note describes what we plan to do about it. I had hoped that it would be possible to somehow "share" the console between the kernel debugger and the user-land world, perhaps by switching screens back and forth when the kernel debugger is in use. This is proving to be impossible. The ultimate source of the problem is that the display is a shared memory device, and there doesn't appear to be a simple protocol by which the kernel and the user-mode software can agree about who owns it -- or even about its current resolution! On the x86, there is an additional challenge in the fact that "windowed" access to the frame buffer is hardware-specific. The net effect of this is that putting the kernel debugger on the console forces you to pull hardware-specific display drivers in as well. The proposed solution is this: if the kernel debugger is compiled in, it gets a dedicated device. This kernel will inform the user-mode device setup code that this device is unavailable. At present, we plan to provide three scenarios for the kernel debugger:
If somebody needs tty0 at some point, we can easily add the option to use tty1/COM2. We could also straightforwardly introduce ethernet-based debugging at some point. 2. Revised Kernel Output LogicWith this change in place, there is now a corresponding change to the kernel's output logic. Here is the plan, and the rationale. The kernel uses three logically distinct output streams in parallel: the syscon_stream, the dbg_stream, and the log_stream. 2.1. The Log StreamThe log_stream is easiest to explain. The kernel maintains a circular log buffer for diagnostics. The purpose of this buffer is to have a place for messages to go that will later be displayed by a user-mode logging agent. Any kernel output that occurs while the kernel debugger is inactive goes here. Output generated while the kernel debugger is active (i.e. in response to a debugger command) does not go to the log_stream. The logic of this is that these messages are "out of band" with respect to the normal flow of the kernel. 2.2. Use of Console (syscon_stream)The kernel assumes that the console display buffer (if present) can be used freely by the kernel prior to the point where the first user-mode thread is dispatched. If a console display buffer is present, the global variable syscon_stream is bound to a stream that displays on the console. In order to provide information about boot-up processing, the kernel issues diagnostics to syscon_stream. If no console device is present, syscon_stream is set to null. Just before the first user thread is dispatched, syscon_stream is nullified, and no further output will be sent to it. This ensures that kernel output will not interfere with user-mode use of the console display. Once the first user-mode process is started, it is the responsibility of the user-mode logging agent to recover kernel logging messages from the kernel message log buffer. 2.3. Use of Debugger Stream(dbg_stream)If a debugger is present, it logically ``owns'' a stream of its own -- the dbg_stream. If no debugger is present, then dbg_stream is set to null. The general idea is that the kernel debugger needs a dedicated device to talk to the kernel with. To simplify the (human) debugger's view of what is going on, all traffic to the syscon_stream is also echoed to dbg_stream if one is present. The previous generation of debugging logic had a pager modeled after the UNIX more command. Because all kernel output is now directed through the same output logic, we have revised the output logic to invoke the more interface only when the debugger is active. This means that the more prompt will appear only when output is occurring in response to a debugger command. 2.4. Practical ComplicationSo long as dbg_stream and syscon_stream are distinct (or null), the above logic carries no contradictions. If the kernel debugger is set up on the console, however, things get a bit trickier. In this scenario, we know that the console device has been dedicated for use by the debugger. Our challenge is primarily to avoid the ``double vision'' that would ensue if both syscon_stream and dbg_stream pointed to the same place. The solution in this case is to leave syscon_stream set to null whenever dbg_stream names the console. Because all output sent to syscon_stream goes to dbg_stream in any case, this does not cause output to be lost. Copyright 2001 by Jonathan Shapiro. All rights reserved. For terms of redistribution, see the GNU General Public License |