Skip to content
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

Emulator/JS communication - stdin, stdout, stderr? #21

Open
mweichert opened this issue Jan 10, 2021 · 3 comments
Open

Emulator/JS communication - stdin, stdout, stderr? #21

mweichert opened this issue Jan 10, 2021 · 3 comments

Comments

@mweichert
Copy link

Hi there,

Awesome project!

Is there a way for JS to interact with the emulator via stdin, stdout, or stderr?

I'd like to write to stdin and read stdout via JS.

Thanks!
Mike

@nepx
Copy link
Owner

nepx commented Jan 10, 2021

You can send raw scan codes to the keyboard controller using display_send_scancode. I believe it's exposed to the JS layer. Keep in mind that these are hardware scan codes, not browser key codes -- this list is pretty comprehensive. If you're sending in a string, for instance, you'll have to convert each character to its corresponding scan code.

The screen buffer is just an array of characters. The operating system itself manages the cursor position, scrolling, etc. to simulate a terminal, but the (emulated) hardware treats it as a linear array of characters. There's no way to capture writes to VGA RAM, although you could certainly add a hook somewhere in vga_mem_writeb.

This is an full system emulator -- it emulates the hardware of a standard PC. Unfortunately, it has no concept of stdin, stdout, or stderr because they're abstractions created by the operating system. You're probably looking for application virtualization, which emulates an operating system (letting you take control of these abstractions) instead of hardware. In the long run, it's probably better to invest in one of those (or write your own) than to try to work around these limitations.

If you do want to use this emulator, you have a few options, in order of feasibility:

  • Write a serial port emulator (it's a much more friendly interface than, say, the VGA display)
  • Write a driver for your selected emulated operating system that communicates with the outside world
  • Adapt the CPU core to emulate the userspace whatever OS you want to run
  • Hook your operating system's syscalls (set up a little handler on cpu_interrupt to catch int 0x80)
  • Play around with display_send_scancode and vga_mem_writeb

Sorry if this wasn't the answer you were expecting, but hope this helps, regardless.

@mweichert
Copy link
Author

Hi @nepx thanks for your reply. As I got into some of the examples after submitting this issue, what you state above makes sense.

One of the bottlenecks I'm seeing is the filesystem emulation. If my image includes a static binary, will that generally perform better than something that has to read libraries from the filesystem?

@nepx
Copy link
Owner

nepx commented Jan 13, 2021

The emulator has no concept of files -- it's all sectors loaded from a disk. If I had to guess, the extra overhead of loading all those dynamic libraries would slow things down -- but on the other hand, if the operating system has these shared libraries in memory already, it'll just pull that data from the disk cache. Disk reads are by far the slowest part of the whole emulator, since network latency is typically orders of magnitudes slower than anything else in the emulator.

When in doubt, profile! You might find that one is decidedly faster than the other, or there's no real difference between the two.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants