-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
change multiboot to boot as an option rom, add initrd, cmdline #971
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Testing-wise, I would like to add your OS to the testsuite (in tests/full/run.js). Could you upload a (preferably small) multiboot image? Also, I assume this could also be used to boot Linux kernels. Have you tested that?
Overall the code looks good. My main bigger suggestion would be to remove the assembly and implement it directly in the io port hook.
src/cpu.js
Outdated
// It sets up the multiboot environment. | ||
const SIZE = 0x200; | ||
|
||
const data8 = new Uint8Array(0x100); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this should be new Uint8Array(SIZE);
(also in kernel.js)
src/cpu.js
Outdated
if(option_rom) | ||
{ | ||
dbg_log("loaded multiboot", LOG_CPU); | ||
this.write_blob(new Uint8Array(option_rom.data), 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the new Uint8Array
makes an unnecessary copy of the option rom and can be removed.
src/cpu.js
Outdated
// does not exclude traditional bios exclusions | ||
let start = 0; | ||
let was_memory = false; | ||
for (let addr = 0; addr < MMAP_MAX; addr += MMAP_BLOCK_SIZE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this loop could stop at this.memory_size[0]
.
I hadn't released it yet, but there's a time for everything. The multiboot image is < 1M; it's more interesting if it has the ~20M initrd though... but that's then a bit big. Either way, I'll need to do some cleanup beforehand.
I have not. So far, I only tested my OS and the tests in the repo. I'll see what's out there that I can get to boot with this after I address the code comments and remove the bulk of the assembly.
|
This allows the acpi bios support to be used by a multiboot os image. The image loading must be done either in the option rom, or triggered by the option rom, in case the multiboot image needs to be loaded into addresses that the bios writes to.
I think this addresses most of the comments, but I have some more work to do now; which I'll try to get done over the next few days. FreeBSD and Linux don't appear to have multiboot kernels (at least the ones I tried)... but NetBSD does. When attempting to load an image that isn't a multiboot image, at least a proper console message would be appropriate, instead of a TypeError. When attempting to load NetBSD, it's hitting an assert in this multiboot loader; and I'm going to dig into why, and see if I can fix it. :D (and same for GNU Hurd) |
Ok, so NetBSD and GNU Hurd kernels both have virtual address != physical address. I looked around, and it seems like the thing to do is load at the physical address, adjust the entry point address from a virtual address to the physical address and jump to that. I didn't see that in the specification (my kernel, and the v86 unit tests have physical == virtual), but it's what grub does. With that change, Hurd does something --- lots of debug output from cpuid and friends, but no output on screen or com1 (probably needs some config or command line). Behavior seems similar with or without bios. NetBSD does start and outputs some boot logs to VGA; then it hits an unexpected overlapped read in ne2k. Excitingly, NetBSD only works if run with SeaBIOS... without a bios, it crashes the emulator with a bad instruction; so that's a good case for me. NetBSD does throw a warning about the memory map, so there's probably improvements to be made there at some point; but I think this is OK for now. I also tweaked things so multiboot and linux kernel loading don't crash if they fail to load. With seabios, that means it'll try to load something else, which doesn't work, but I think that's reasonable... better than just getting stuck on a error? Let me know if you want me to squash this into fewer commits, or feel free to adjust as you like. |
I've put up https://crazierl.org/crazierl.elf and https://crazierl.org/initrd -- using the initrd, a command line of "kernel /libexec/ld-elf32.so.1" is required, works in my demo page https://crazierl.org/demo.html in case any other parameters are important. Expectation if you boot without initrd is it will start and eventually print "end of kernel!" on vga and com1, and halt. If you boot with the initrd, it should end up with a prompt like "1>" where you can type "5 + 5." and hit enter, and get back 10 and a new prompt. VGA output is wonky; my demo page uses com1 only. I may provide a future PR to make vga work better; I set the CRTC Offset Register http://www.osdever.net/FreeVGA/vga/crtcreg.htm#13 so text lines are 128 characters in memory (but still 80 on screen), which makes scrolling with wrap around much simpler. |
Thanks, merged! I'll add NetBSD (even though it doesn't fully boot, I believe unrelated to multiboot) and crazierl as tests soon. I'll also add crazierl to the website, as it's pretty cool :-) |
This fleshes out the multiboot support a bit more. My hobby os relies on multiboot, but also needs some ACPI tables set. Using the existing multiboot support means seabios doesn't run at all, and the tables are missing.
The multiboot content is loaded in an i/o write hook rather than before booting, because otherwise seabios may overwrite the loaded data (happens with the kvm-test).
load_multiboot still works, although the mechanism changed, because nasmtests uses it directly and doesn't load seabios anyway. Now it generates the option rom, loads it at address 0 (seemed like a convenient place) and adjusts execution to start at address 3 (where an option rom is jumped to in a BIOS context).
There's a not entirely related log fix in elf section header debug info (log said program headers, but was reporting about section headers); happy to put that separate, but it came up while I was working on this.