microkernel: how to know message destination.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Alpha
Posts: 15
Joined: Fri Apr 10, 2009 7:04 am
Location: The Netherlands

microkernel: how to know message destination.

Post by Alpha »

Hey everyone.

I am working on a microkernel and i am trying to find a good solution for the following:

consider a microkernel that runs some servers, drivers etc as processes. At some point the user makes a syscall and a message has to be sent to the right server, or some server needs to communicate to another server / driver. In order to send a message to the correct process, the OS should have some knowledge on where to send the message to. I was wondering about ways to implement this.

A simple solution could be to have a predefined reserved PID or name for each kind of server, and you could hard code this as destination, but that is ugly and not very flexible.

so I wonder which methods are commonly used for this. Could someone tell me more about this?
User avatar
bloodline
Member
Member
Posts: 264
Joined: Tue Sep 15, 2020 8:07 am
Location: London, UK

Re: microkernel: how to know message destination.

Post by bloodline »

Have a searchable public list of ports available to all tasks, where servers can register their ports.

That’s what I have.
CuriOS: A single address space GUI based operating system built upon a fairly pure Microkernel/Nanokernel. Download latest bootable x86 Disk Image: https://github.com/h5n1xp/CuriOS/blob/main/disk.img.zip
Discord:https://discord.gg/zn2vV2Su
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: microkernel: how to know message destination.

Post by nexos »

For one thing, the user mode app generally is the one that needs to know about this stuff, as it is this app that is sending the message. The best solution would be to use a port system, in which messages are sent to ports and then a driver listens to that port, and a process sends a message to that port. That is what Mach (and I think Windows' LPC) use.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
eekee
Member
Member
Posts: 891
Joined: Mon May 22, 2017 5:56 am
Location: Kerbin
Discord: eekee
Contact:

Re: microkernel: how to know message destination.

Post by eekee »

A registry (as bloodline described) is good if you want user programs to have full control of which server they're using.

Ports are good if you want to ensure a maximum of one server of each type, but why would you want to do that? You could put servers on other ports, but then how would user apps discover them? By calling a registry service? ;) I suppose it's okay if the user (person) can discover the devices and pass options to the apps, but depending on system design, it can be hard for the user to find which servers occupy which ports.

Plan 9's approach, where servers serve virtual files and mounts may be per-process, offers users (people) full control and makes it easier to discover services than some systems. The user gets to chose between alternate servers with mount and bind, and the rfork command offers control over which processes share servers by "forking the namespace". Services have default filenames such as /dev/audio, /mnt/factotum, or /net, and different servers may be bound to these names. For example, a network gateway may have /net and /net.alt. It's biggest advantage is that you don't need to write any code in individual programs to give the user control. It has some disadvantages. Finding servers is sometimes easy, sometimes not, and in fact the Plan 9-like Inferno OS has a registry. The kernel has no support for multiplexing the keyboard or mouse, (minimal code again,) so the window system forks the namespace for every window. There are workarounds, but it's worth noting.

Overall... you can specify the default server for any service by specifying a default name (e.g. path) or number (e.g. port) for each service, but to give choices you'll probably want a registry. If you don't want a registry, please make it easy for users to find (or to control) which service serves which name/number.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
andrew_w
Posts: 19
Joined: Wed May 07, 2008 5:06 am

Re: microkernel: how to know message destination.

Post by andrew_w »

eekee wrote:A registry (as bloodline described) is good if you want user programs to have full control of which server they're using.

Ports are good if you want to ensure a maximum of one server of each type, but why would you want to do that? You could put servers on other ports, but then how would user apps discover them? By calling a registry service? ;) I suppose it's okay if the user (person) can discover the devices and pass options to the apps, but depending on system design, it can be hard for the user to find which servers occupy which ports.

Plan 9's approach, where servers serve virtual files and mounts may be per-process, offers users (people) full control and makes it easier to discover services than some systems. The user gets to chose between alternate servers with mount and bind, and the rfork command offers control over which processes share servers by "forking the namespace". Services have default filenames such as /dev/audio, /mnt/factotum, or /net, and different servers may be bound to these names. For example, a network gateway may have /net and /net.alt. It's biggest advantage is that you don't need to write any code in individual programs to give the user control. It has some disadvantages. Finding servers is sometimes easy, sometimes not, and in fact the Plan 9-like Inferno OS has a registry. The kernel has no support for multiplexing the keyboard or mouse, (minimal code again,) so the window system forks the namespace for every window. There are workarounds, but it's worth noting.

Overall... you can specify the default server for any service by specifying a default name (e.g. path) or number (e.g. port) for each service, but to give choices you'll probably want a registry. If you don't want a registry, please make it easy for users to find (or to control) which service serves which name/number.
This is exactly the approach I'm taking In UX/RT, the OS I'm writing. All services will appear in the filesystem and be accessed through read()/write()-family APIs, even the parts of the VFS other than the read/write APIs themselves (technically UX/RT's read/write APIs will be considered part of the IPC transport layer and not part of the VFS). File descriptors will be mapped onto kernel capabilities and read/write will call kernel IPC to directly transfer data to/from the other process. Every process will be started with a special always-open file descriptor that allows it to communicate with the VFS and open FDs to other services (there will be a class of special files that allow sending FDs between processes; this will include the VFS connection). If you've got a VFS, you've already got a way to look up services, so I don't see much of a point in including other name services that are probably going to be less flexible than a VFS.
Developer of UX/RT, a QNX/Plan 9-like OS
xeyes
Member
Member
Posts: 212
Joined: Mon Dec 07, 2020 8:09 am

Re: microkernel: how to know message destination.

Post by xeyes »

Alpha wrote:Hey everyone.

I am working on a microkernel and i am trying to find a good solution for the following:

consider a microkernel that runs some servers, drivers etc as processes. At some point the user makes a syscall and a message has to be sent to the right server, or some server needs to communicate to another server / driver. In order to send a message to the correct process, the OS should have some knowledge on where to send the message to. I was wondering about ways to implement this.

A simple solution could be to have a predefined reserved PID or name for each kind of server, and you could hard code this as destination, but that is ugly and not very flexible.

so I wonder which methods are commonly used for this. Could someone tell me more about this?
My 2 cents: This is the same issue as finding destination on a computer network, you either know it or query for it and then cache it for later use, with a timeout or other mechanisms in place in case it changes.

Predefined reserved PIDs also have their places, you don't really want things like ff:ff:ff:ff:ff:ff, 127.0.0.1 or perhaps even 8.8.8.8 to be "very flexible" and each become a chicken and egg problem.

Even lower level ideas like switch table could probably be adopted to work well and efficiently for your purpose, and you can in the meantime get fancy and build a DNS like service if desired.
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Re: microkernel: how to know message destination.

Post by codyd51 »

My IPC implementation is similar to the port idiom, but removing a layer of indirection (and a layer of flexibility :P)

Upon startup, processes that want to participate in IPC declare a service name for themselves:

Code: Select all

int main(int argc, char** argv) {
    amc_register_service("com.phillipt.paintbrush");
    ...
}
When sending a message, you specify its destination service (or broadcast it globally)

Code: Select all

// Sent from the window manager to inform a window of a mouse move within its bounds
amc_msg_u32_3__send(window->owner_service, AWM_MOUSE_MOVED, local_mouse.x, local_mouse.y);
When receiving a message, you specify who you're awaiting from (or receive from anyone)

Code: Select all

amc_message_t recv;
// Wait for a message from the window manager
amc_message_await("com.axle.awm", &recv);
// Or...
amc_message_await_any(&recv);
All together now! This is an excerpt from a "textpad" that displays whatever the user types into a text box. It receives events from the window manager.

Code: Select all

    amc_message_t recv;
    do {
        // This is a blocking call if there's no message in our inbox
        amc_message_await("com.axle.awm", &recv);
        uint32_t event = amc_cmd_u8_get_byte(&recv, 0);
        // Defined in the spec for communicating with com.axle.awm
        if (event == AWM_KEY_DOWN) {
            text_box_putchar(text_box, amc_cmd_u8_get_byte(&recv, 1), color_green());
        }
    } while (amc_has_message_from("com.axle.awm"));
    // The do...while allows us to process multiple messages in one wakeup
    // All done! Blit the text box to the window layer and request a redraw
    blit_layer(window_layer, text_box->layer, window_frame, window_frame);
    amc_command_msg__send("com.axle.awm", AWM_WINDOW_REDRAW_READY);
Here's what some programs communicating over IPC for event management look like: https://imgur.com/a/D6RERL6
User avatar
AndrewAPrice
Member
Member
Posts: 2300
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Re: microkernel: how to know message destination.

Post by AndrewAPrice »

Instead of using ports, I'm using named services. E.g. there is a service called "Storage Device" that has a set of RPCs. Any process can implement and register a "Storage Device", and you can iterate over all instances of "Storage Device".

For a lot of services though, I might go with "just use the first one you find" (in order of being registered) E.g. anyone can register a "Window Manager" but maybe we only care about the very first Window Manager that gets registered?
Last edited by AndrewAPrice on Sun Jan 17, 2021 6:17 pm, edited 1 time in total.
My OS is Perception.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: microkernel: how to know message destination.

Post by nexos »

My OS is going to be sort of NT like with a hint of Unix. So there will be named ports inside an object namespace. An app will open this like a file, and then use a write and read call to send and recieve data. Now my OS will be a hybrid, but I'm sure you could tune that for microkernels.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Alpha
Posts: 15
Joined: Fri Apr 10, 2009 7:04 am
Location: The Netherlands

Re: microkernel: how to know message destination.

Post by Alpha »

Thanks for all the answers. It gives me something to think about. Currently i just started to work on usermode and kernel calls, so it will take some time before i have to implement this. However it is a good time to think ahaid a little about how to lay-out my OS.
Post Reply