tevd: bootloader is now entry id 1

This commit is contained in:
minjaesong
2022-12-23 05:23:54 +09:00
parent 1ecb85354b
commit 59399d84f9
6 changed files with 93 additions and 15 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -23,7 +23,17 @@ function copyFiles(destDrive) {
})
// bare files in the root dir
;["!BOOTSEC", "AUTOEXEC.BAT"].forEach((name)=>{
;["AUTOEXEC.BAT"].forEach((name)=>{
dos.cp(`A:\\tvdos\\installer\\${name}`, `${destDrive}:\\${name}`)
})
// install bootloader
val bootloader = files.open("A:\\tvdos\\installer\\!BOOTSEC").sread()
let [port, poru] = _TVDOS.DRV.FS.SERIAL._toPorts(destDrive)[0]
com.sendMessage(port, "FLUSH");com.sendMessage(port, "CLOSE")
com.sendMessage(port, `NEWTEVDBOOT,${poru}`) // read-only check will be performed by the other writes
com.sendMessage(port, bootloader)
com.sendMessage(port, "FLUSH");com.sendMessage(port, "CLOSE")
}

View File

@@ -150,6 +150,16 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
appendMode = false
}
}
else if (fileOpenMode == 17) {
if (!fileOpen) throw InternalError("Bootloader file is not open but the drive is in boot write mode")
val inputData = if (inputData.size != BLOCK_SIZE) ByteArray(BLOCK_SIZE) { if (it < inputData.size) inputData[it] else 0 }
else inputData
file.writeBytes(inputData)
fileOpenMode = -1
}
else {
val inputString = inputData.trimNull().toString(VM.CHARSET)
@@ -311,6 +321,21 @@ class TestDiskDrive(private val vm: VM, private val driveNum: Int, theRootPath:
return
}
}
else if (inputString.startsWith("NEWTEVDBOOT")) {
var commaIndex = 0
while (commaIndex < inputString.length) {
if (inputString[commaIndex] == ',') break
commaIndex += 1
}
val driveNum = if (commaIndex >= inputString.length) null else commaIndex
// TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it
statusCode.set(STATE_CODE_STANDBY)
fileOpen = true
fileOpenMode = 17
blockSendCount = 0
}
else if (inputString.startsWith("LOADBOOT")) {
var commaIndex = 0
while (commaIndex < inputString.length) {

View File

@@ -14,7 +14,7 @@ import java.util.concurrent.atomic.AtomicBoolean
class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val theTevdPath: String, val diskUUIDstr: String) : BlockTransferInterface(false, true) {
private val DBGPRN = false
private val DBGPRN = true
val diskID: UUID = UUID.fromString(diskUUIDstr)
@@ -30,8 +30,10 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
private var fileOpenMode = -1 // 1: 'W", 2: 'A'
private var file: TevdFileDescriptor = TevdFileDescriptor(DOM, "")
//private var readModeLength = -1 // always 4096
private var writeMode = false
private var appendMode = false
private val writeMode
get() = fileOpenMode == 1
private val appendMode
get() = fileOpenMode == 2
private var writeModeLength = -1
private val messageComposeBuffer = ByteArrayOutputStream(BLOCK_SIZE) // always use this and don't alter blockSendBuffer please
@@ -113,13 +115,25 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
else if (writeMode)
file.writeBytes(writeBuffer)
writeMode = false
appendMode = false
fileOpenMode = -1
printdbg("Notifying disk commit (end of write)")
notifyDiskCommit()
}
}
else if (fileOpenMode == 17) {
if (!fileOpen) throw InternalError("Bootloader file is not open but the drive is in boot write mode")
val inputData = if (inputData.size != BLOCK_SIZE) ByteArray(BLOCK_SIZE) { if (it < inputData.size) inputData[it] else 0 }
else inputData
file.writeBytes(inputData)
fileOpenMode = -1
printdbg("Notifying disk commit (end of bootloader write)")
notifyDiskCommit()
}
else {
val inputString = inputData.trimNull().toString(VM.CHARSET)
@@ -131,7 +145,6 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
file = TevdFileDescriptor(DOM, "")
blockSendCount = 0
statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
writeMode = false
writeModeLength = -1
}
else if (inputString.startsWith("DEVSTU\u0017"))
@@ -297,6 +310,27 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
return
}
}
else if (inputString.startsWith("NEWTEVDBOOT")) {
var commaIndex = 0
while (commaIndex < inputString.length) {
if (inputString[commaIndex] == ',') break
commaIndex += 1
}
val driveNum = if (commaIndex >= inputString.length) null else commaIndex
// TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it
if (DOM.isReadOnly) {
printdbg("! disk is read-only")
statusCode.set(TestDiskDrive.STATE_CODE_READ_ONLY)
return
}
statusCode.set(TestDiskDrive.STATE_CODE_STANDBY)
fileOpen = true
fileOpenMode = 17
blockSendCount = 0
}
else if (inputString.startsWith("LOADBOOT")) {
var commaIndex = 0
while (commaIndex < inputString.length) {
@@ -307,17 +341,17 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
// TODO driveNum is for disk drives that may have two or more slots built; for testing purposes we'll ignore it
val bootFile = TevdFileDescriptor(DOM, "!BOOTSEC")
val bootFile = DOM.entries[1]
printdbg("bootFile = $bootFile, ID: ${bootFile.entryID}, exists = ${bootFile.exists()}")
printdbg("bootFile = $bootFile, ID: 1, exists = ${bootFile != null}")
if (!bootFile.exists()) {
if (bootFile == null) {
printdbg("bootfile not exists!")
statusCode.set(TestDiskDrive.STATE_CODE_NO_SUCH_FILE_EXISTS)
return
}
try {
val retMsg = bootFile.getHeadBytes(BLOCK_SIZE)
val retMsg = VDUtil.getAsNormalFile(DOM, 1).getContent().sliceArray(0 until BLOCK_SIZE)
printdbg("retMsg = ${retMsg.toString(VM.CHARSET)}")
@@ -412,8 +446,6 @@ class TevdDiskDrive(private val vm: VM, private val driveNum: Int, private val t
statusCode.set(TestDiskDrive.STATE_CODE_OPERATION_NOT_PERMITTED)
return
}
if (fileOpenMode == 1) { writeMode = true; appendMode = false }
else if (fileOpenMode == 2) { writeMode = false; appendMode = true }
if (!file.exists()) {
val f1 = file.createNewFile()
statusCode.set(if (f1) TestDiskDrive.STATE_CODE_STANDBY else TestDiskDrive.STATE_CODE_OPERATION_FAILED)

View File

@@ -1,7 +1,8 @@
package net.torvald.tsvm
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.EntryFile
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VDUtil
import net.torvald.tsvm.VM
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VDUtil.checkReadOnly
import java.io.File
/**
@@ -33,12 +34,22 @@ fun main(args: Array<String>) {
// bare file in root dir
listOf(
VDUtil.importFile(File("assets/disk0/root.bootable/!BOOTSEC"), disk.generateUniqueID(), VM.CHARSET),
VDUtil.importFile(File("assets/disk0/root.bootable/AUTOEXEC.BAT"), disk.generateUniqueID(), VM.CHARSET),
).forEach {
VDUtil.addFile(disk, 0, it)
}
VDUtil.importFile(File("assets/disk0/root.bootable/!BOOTSEC"), 1, VM.CHARSET).let {
disk.checkReadOnly()
// disk.checkCapacity(4096)
(it.contents as EntryFile).let { file ->
val bytes = file.getContent()
bytes.appendBytes(ByteArray(4096 - bytes.size.toInt()))
}
disk.entries[1] = it
}
VDUtil.dumpToRealMachine(disk, File(args[0]))
}