Detect initrd/bzimage in 9p filesystem and load before boot

This commit is contained in:
Fabian 2018-10-08 16:19:50 -03:00
parent 23a2ac9c44
commit 3f79814e05
3 changed files with 119 additions and 29 deletions

View file

@ -1931,3 +1931,31 @@ FS.prototype.Lock = function(id, request, flags)
return P9_LOCK_SUCCESS;
};
FS.prototype.read_dir = function(path)
{
const p = this.SearchPath(path);
if(p.id === -1)
{
return Promise.resolve(null);
}
const dir = this.GetInode(p.id);
return Array.from(dir.direntries.keys()).filter(path => path !== "." && path !== "..");
};
FS.prototype.read_file = function(file)
{
const p = this.SearchPath(file);
if(p.id === -1)
{
return undefined;
}
const inode = this.GetInode(p.id);
return this.Read(p.id, 0, inode.size);
};

View file

@ -289,12 +289,7 @@
id: "debian-boot",
name: "Debian",
memory_size: 512 * 1024 * 1024,
bzimage: {
"url": "images/debian-9p-rootfs/vmlinuz",
},
initrd: {
"url": "images/debian-9p-rootfs/initrd.img",
},
bzimage_initrd_from_filesystem: true,
cmdline: "rw init=/bin/systemd root=host9p console=ttyS0 spectre_v2=off pti=off",
vga_memory_size: 8 * 1024 * 1024,
filesystem: {
@ -562,6 +557,7 @@
settings.bzimage = infos.bzimage;
settings.initrd = infos.initrd;
settings.cmdline = infos.cmdline;
settings.bzimage_initrd_from_filesystem = infos.bzimage_initrd_from_filesystem;
settings.memory_size = infos.memory_size;
settings.vga_memory_size = infos.vga_memory_size;
@ -787,6 +783,7 @@
"bzimage": settings.bzimage,
"initrd": settings.initrd,
"cmdline": settings.cmdline,
"bzimage_initrd_from_filesystem": settings.bzimage_initrd_from_filesystem,
"initial_state": settings.initial_state,
"filesystem": settings.filesystem || {},

View file

@ -27,6 +27,12 @@
* - `hda Object` (No hard drive) - First hard disk, see below.
* - `fda Object` (No floppy disk) - First floppy disk, see below.
* - `cdrom Object` (No CD) - See below.
*
* - `bzimage Object` - A Linux kernel image to boot (only bzimage format), see below.
* - `initrd Object` - A Linux ramdisk image, see below.
* - `bzimage_initrd_from_filesystem boolean` - Automatically fetch bzimage and
* initrd from the specified `filesystem`.
*
* - `initial_state Object` (Normal boot) - An initial state to load, see
* [`restore_state`](#restore_statearraybuffer-state) and below.
*
@ -542,38 +548,97 @@ V86Starter.prototype.continue_init = function(emulator, options)
// settings.memory_size = 0;
//}
this.bus.send("cpu-init", settings);
setTimeout(function()
if(settings.fs9p && settings.fs9p_json)
{
if(settings.fs9p && settings.fs9p_json)
settings.fs9p.OnJSONLoaded(settings.fs9p_json);
if(options["bzimage_initrd_from_filesystem"])
{
settings.fs9p.OnJSONLoaded(settings.fs9p_json);
const { bzimage, initrd } = this.get_bzimage_initrd_from_filesystem(settings.fs9p);
dbg_log("Found bzimage: " + bzimage + " and initrd: " + initrd);
Promise.all([
settings.fs9p.read_file(initrd),
settings.fs9p.read_file(bzimage),
]).then(([initrd, bzimage]) => {
put_on_settings.call(this, "initrd", new SyncBuffer(initrd.buffer));
put_on_settings.call(this, "bzimage", new SyncBuffer(bzimage.buffer));
finish.call(this);
});
}
else
{
finish.call(this);
}
}
else
{
console.assert(
!options["bzimage_initrd_from_filesystem"],
"bzimage_initrd_from_filesystem: Requires a filesystem");
finish.call(this);
}
function finish()
{
this.bus.send("cpu-init", settings);
if(settings.initial_state)
{
emulator.restore_state(settings.initial_state);
// The GC can't free settings, since it is referenced from
// several closures. This isn't needed anymore, so we delete it
// here
settings.initial_state = undefined;
}
setTimeout(function()
if(options["autostart"])
{
if(settings.initial_state)
{
emulator.restore_state(settings.initial_state);
this.bus.send("cpu-run");
}
// The GC can't free settings, since it is referenced from
// several closures. This isn't needed anymore, so we delete it
// here
settings.initial_state = undefined;
}
if(options["autostart"])
{
this.bus.send("cpu-run");
}
this.emulator_bus.send("emulator-loaded");
}.bind(this), 0);
}.bind(this), 0);
this.emulator_bus.send("emulator-loaded");
}
}
};
V86Starter.prototype.get_bzimage_initrd_from_filesystem = function(filesystem)
{
const root = (filesystem.read_dir("/") || []).map(x => "/" + x);
const boot = (filesystem.read_dir("/boot/") || []).map(x => "/boot/" + x);
let initrd;
let bzimage;
for(let f of [].concat(root, boot))
{
const old = /old/.test(f) || /fallback/.test(f);
const is_bzimage = /vmlinuz/.test(f);
const is_initrd = /initrd/.test(f) || /initramfs/.test(f);
if(is_bzimage && (!bzimage || !old))
{
bzimage = f;
}
if(is_initrd && (!initrd || !old))
{
initrd = f;
}
}
if(!initrd || !bzimage)
{
console.log("Failed to find bzimage or initrd in filesystem. Files:");
console.log(root.join(" "));
console.log(boot.join(" "));
}
return { initrd, bzimage };
};
/**
* Start emulation. Do nothing if emulator is running already. Can be
* asynchronous.