Bind GPU to screen in kernel, to allow boot errors to show up on the screen before an OS binds it.

Set resolution and depth to max in GPU's crash display (bluescreen).
This commit is contained in:
Florian Nücke 2014-05-31 01:02:42 +02:00
parent 6ef0e5d26c
commit 22d020004c
2 changed files with 51 additions and 40 deletions

View File

@ -538,28 +538,35 @@ sandbox.unicode = libunicode
-------------------------------------------------------------------------------
local function bootstrap()
local function tryLoadFrom(address)
function boot_invoke(method, ...)
local result = table.pack(pcall(invoke, component, true, address, method, ...))
if not result[1] then
return nil, result[2]
else
return table.unpack(result, 2, result.n)
end
function boot_invoke(address, method, ...)
local result = table.pack(pcall(invoke, component, true, address, method, ...))
if not result[1] then
return nil, result[2]
else
return table.unpack(result, 2, result.n)
end
local handle, reason = boot_invoke("open", "/init.lua")
end
do
local screen = libcomponent.list("screen")()
local gpu = libcomponent.list("gpu")()
if gpu and screen then
boot_invoke(gpu, "bind", screen)
end
end
local function tryLoadFrom(address)
local handle, reason = boot_invoke(address, "open", "/init.lua")
if not handle then
return nil, reason
end
local buffer = ""
repeat
local data, reason = boot_invoke("read", handle, math.huge)
local data, reason = boot_invoke(address, "read", handle, math.huge)
if not data and reason then
return nil, reason
end
buffer = buffer .. (data or "")
until not data
boot_invoke("close", handle)
boot_invoke(address, "close", handle)
return load(buffer, "=init", "t", sandbox)
end
local init, reason

View File

@ -2,13 +2,14 @@ package li.cil.oc.server.component
import li.cil.oc.Settings
import li.cil.oc.api.Network
import li.cil.oc.api.component.TextBuffer
import li.cil.oc.api.component.TextBuffer.ColorDepth
import li.cil.oc.api.network._
import li.cil.oc.common.component
import li.cil.oc.util.PackedColor
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.StatCollector
import li.cil.oc.api.component.TextBuffer
import scala.collection.convert.WrapAsScala._
abstract class GraphicsCard extends component.ManagedComponent {
val node = Network.newNode(this, Visibility.Neighbors).
@ -233,36 +234,39 @@ abstract class GraphicsCard extends component.ManagedComponent {
override def onMessage(message: Message) {
super.onMessage(message)
if (message.name == "computer.stopped" && node.isNeighborOf(message.source)) {
screenInstance match {
case Some(buffer) => buffer.synchronized {
val w = buffer.getWidth
val h = buffer.getHeight
buffer.setForegroundColor(0xFFFFFF)
message.source.host match {
case machine: machine.Machine if machine.lastError != null =>
if (buffer.getColorDepth.ordinal > ColorDepth.OneBit.ordinal) buffer.setBackgroundColor(0x0000FF)
else buffer.setBackgroundColor(0x000000)
buffer.fill(0, 0, w, h, ' ')
try {
val message = "Unrecoverable error:\n" + StatCollector.translateToLocal(machine.lastError) + "\n"
val wrapRegEx = s"(.{1,${math.max(1, w - 2)}})\\s".r
val lines = wrapRegEx.replaceAllIn(message, m => m.group(1) + "\n").lines.toArray
for ((line, idx) <- lines.zipWithIndex) {
val col = (w - line.length) / 2
val row = (h - lines.length) / 2 + idx
buffer.set(col, row, line, false)
}
screen(s => {
val (gmw, gmh) = maxResolution
val smw = s.getMaximumWidth
val smh = s.getMaximumHeight
s.setResolution(math.min(gmw, smw), math.min(gmh, smh))
s.setColorDepth(ColorDepth.values.apply(math.min(maxDepth.ordinal, s.getMaximumColorDepth.ordinal)))
s.setForegroundColor(0xFFFFFF)
val w = s.getWidth
val h = s.getHeight
message.source.host match {
case machine: machine.Machine if machine.lastError != null =>
if (s.getColorDepth.ordinal > ColorDepth.OneBit.ordinal) s.setBackgroundColor(0x0000FF)
else s.setBackgroundColor(0x000000)
s.fill(0, 0, w, h, ' ')
try {
val message = "Unrecoverable error:\n" + StatCollector.translateToLocal(machine.lastError) + "\n"
val wrapRegEx = s"(.{1,${math.max(1, w - 2)}})\\s".r
val lines = wrapRegEx.replaceAllIn(message, m => m.group(1) + "\n").lines.toArray
for ((line, idx) <- lines.zipWithIndex) {
val col = (w - line.length) / 2
val row = (h - lines.length) / 2 + idx
s.set(col, row, line, false)
}
catch {
case t: Throwable => t.printStackTrace()
}
case _ =>
buffer.setBackgroundColor(0x000000)
buffer.fill(0, 0, w, h, ' ')
}
}
catch {
case t: Throwable => t.printStackTrace()
}
case _ =>
s.setBackgroundColor(0x000000)
s.fill(0, 0, w, h, ' ')
}
case _ =>
}
null // For screen()
})
}
}