openblt.html (8887B)
1 <HTML> 2 <HEAD> 3 <TITLE>OpenBLT Overview</TITLE> 4 </HEAD> 5 <BODY BGCOLOR="#ffffff"> 6 7 <CENTER> 8 <TABLE WIDTH=600> 9 <TR><TD> 10 11 <H1>OpenBLT: An Overview</H1> 12 <I>by Brian J. Swetland</I> 13 14 <P> 15 OpenBLT is a microkernel operating system for PC's based on the Intel 16 80386 or later CPUs. Some aspects of OpenBLT were inspired by Andy 17 Valencia's VSTa OS, Mach, assorted UNIX variants, and the author's 18 deranged imagination. The acronym BLT expands to "Brian's Lightweight 19 Tasker" or "Bacon, Lettuce, and Threads". The word Open was tacked on 20 for no particular reason. 21 <P> 22 The OpenBLT kernel is responsible for managing system memory, providing 23 IPC facilities, and creation, destruction, and scheduling threads of control. 24 <P> 25 Below, we'll examine Tasks, Aspaces, and Ports (the basic objects managed 26 by the OpenBLT kernel) in terms of their use in and appearance to userland 27 programs. 28 29 <P><B>Tasks</B><BR> 30 Tasks in OpenBLT are single threads of control. Each task is associated 31 with an address space, within which it runs. Tasks may terminate themselves 32 using the 33 <PRE>void os_terminate(int status);</PRE> 34 system call. A task may start another task (sharing the same address space) 35 using the 36 37 <PRE>int os_thread(void *addr);</PRE> 38 system call. The new task begins execution at the specified address and 39 a 4K stack is created for it. <I>[ os_thread() will probably take a stack 40 pointer address in the next revision ]</I> 41 42 <P><B>Address Spaces</B><BR> 43 Address spaces are currently not readily manipulated from userland. 44 In the near future, shared memory system calls should allow the creation 45 of new address spaces and sharing memory between address spaces. A 46 thread may request that its address space be expanded using the <TT>os_brk()</TT> system call: 47 <PRE> 48 int os_brk(int addr); 49 </PRE> 50 51 <P><B>Ports</B><BR> 52 IPC (interprocess communication) in OpenBLT occurs when one task sends a 53 message to another task via a port. Ports are 'owned' by one task (the 54 task that created them). Messages are send from one port to another port 55 (thus a port must exist for the sending task to send from). A port may 56 be restricted so that it can only receive messages from one specified 57 other port <I>[ future versions will likely allow a list of allowed senders ]</I>. 58 59 60 <P> 61 All messages sent or received via an OpenBLT port are described with 62 a message header. The header indicates the source port, destination port, 63 size of message, pointer to message data (or receive data buffer), and 64 flags (to allow for future expansion -- non-blocking IO, scatter/gather 65 IO, etc) 66 <PRE> 67 typedef struct { 68 int flags; 69 int src; 70 int dst; 71 int size; 72 void *data; 73 } msg_hdr_t; 74 </PRE> 75 76 77 <P><TT>int <B>port_create</B>(uint32 restrict);</TT><BR> 78 Create a new port owned by the running thread. Only allow messages 79 from port 'restrict' to be received. If <TT>restrict</TT> is 0, messages 80 from any source will be received. Will return <TT>ERR_MEMORY</TT> if 81 the system lacks the resources to create the port, otherwise the port 82 number will be returned. 83 84 <P><TT>int <B>port_destroy</B>(uint32 port);</TT><BR> 85 Destroy an existing port. Returns <TT>ERR_RESOURCE</TT> if <TT>port</TT> is 86 not a valid port or if there are other ports slaved to this port. 87 Returns <TT>ERR_PERMISSION</TT> if the running thread is not the owner 88 of this port. Returns <TT>ERR_NONE</TT> upon success/ 89 90 <P><TT>int <B>port_send</B>(msg_hdr_t *mh);</TT></BR> 91 Send the message in <TT>mh->data</TT>, of length <TT>mh->size</TT> 92 from port <T>mh->src</TT> to port <TT>mh->dst</TT>. Returns 93 <TT>mh->size</TT> upon success, <TT>ERR_MEMORY</TT> if there is a 94 bounds error, <TT>ERR_RESOURCE</TT> if either the source or 95 destination ports do not exist, <TT>ERR_PERMISSION</TT> if the source 96 is not owned by the running thread or the destination is not sendable 97 from the source port. 98 99 <P><TT>int <B>port_recv</B>(msg_hdr_t *mh);</TT></BR> 100 Receive a message (in buffer <TT>mh->data</TT>, max length 101 <TT>mh->size</TT>) from port <TT>mh->dst</TT>. Upon success, 102 <TT>mh->src</TT> will be set to the sender, <TT>mh->dst</TT> will be 103 set to the destination if it was a slaved port, and the number of 104 received bytes will be returned. If the data or header are out of 105 bounds, <TT>ERR_MEMORY</TT> is returned. If the destination port does 106 not exist <TT>ERR_RESOURCE</TT> is returned. If the running thread 107 does not own the destination port, <TT>ERR_PERMISSION</TT> is 108 returned. This call will block if no messages are available, unless 109 the port is set to NOWAIT, in which case <TT>ERR_WOULDBLOCK</TT> is 110 returned. 111 112 <P><TT>int <B>port_option</B>(uint32 port, int opt, int arg);</TT></BR> 113 Modify port options. The two functions below are wrappers around 114 <TT>port_option()</TT> 115 116 <P><TT>int <B>port_slave</B>(uint32 master, uint32 slave);</TT><BR> 117 Cause the master port to receive all messages sent to the slave port. 118 If master is 0, the slave is released from bondage. Returns ERR_NONE 119 upon success, <TT>ERR_PERMISSION</TT> if the master and slave are not 120 both owned by the running thread, or <TT>ERR_RESOURCE</TT> if the 121 master or slave are not valid ports. 122 123 <P><TT>int <B>port_set_restrict</B>(uint32 port, uint32 restrict);</TT><BR> 124 Change the restriction on a port. Returns <TT>ERR_NONE</TT> on 125 success, <TT>ERR_RESOURCE</TT> if the port does not exits, or 126 <TT>ERR_PERMISSION</TT> if the running thread does not own the port. 127 A restriction of 0 allows any port to send to this port. 128 129 <P><B>Finding other tasks to talk to</B><BR> 130 Since port numbers are generated dynamically by the kernel and tend to 131 be different depending on the order tasks are started, etc, there needs 132 to be a mechanism for locating device drivers or just other tasks to 133 talk to. The kernel automatically creates port 1 (the uberport) and gives 134 ownership of this port to the first task created. This task is the namer, 135 a service that allows drivers to register ports under specific names and 136 allows tasks that wish to find these drivers to look up the port that is 137 associated with a specific name. 138 <P> 139 The utility functions listed below are part of the OpenBLT libc and provide 140 convenient ways to access the namer. 141 <PRE> 142 int namer_newhandle(void); 143 int namer_delhandle(int nh); 144 int namer_register(int nh, int port, char *name); 145 int namer_find(int nh, char *name); 146 </PRE> 147 148 <P><B>Connections between Connectionless ports</B><BR> 149 Ports in OpenBLT are connectionless. Each <TT>port_send()</TT> specifies 150 a source and destination port. Tasks may send from any port they own to 151 any port they are allowed to write to. Ports may be writable to be any 152 other port or restricted to just one other port. <I>[ multiple port restrict 153 lists will be in a later version ]</I> 154 <P> 155 The general procedure for providing a service in OpenBLT is 156 <UL> 157 <LI>Create an unrestricted port 158 <LI>Register this port with the namer under a descriptive name (eg ne2000, console, etc) 159 </UL> 160 When one task (a client) wishes to connect to a service (the server), 161 the following occurs: 162 <UL> 163 <LI>The client looks up the servers unrestricted port using the namer 164 <LI>The client creates a port that is restricted to the server's 165 unrestricted port 166 <LI>The client sends a message to the servers unrestricted port 167 requesting a connection 168 <LI>If the server accepts the connection, it will send a response back 169 to the client's port notifying it that the connection is accepted and 170 possibly providing a different port than the unrestricted port that the 171 client should send future messages too. 172 </UL> 173 <I>[ a toolkit in libc will streamline this process ]</I> 174 175 <P><B>Handling Devices</B><BR> 176 The security model in OpenBLT is still being designed. Most likely 177 there will be a task that is a "security manager" which will be able 178 to give permissions (for accession IO devices, etc) to tasks that need them. 179 The two syscalls described below are sufficient for simple device drivers 180 in the initial (overly trusting) version of OpenBLT: 181 182 <P><TT>void <B>os_handle_irq</B>(int irq);</TT><BR> 183 Ask the kernel to make this task eligible to process the specified IRQ. 184 The kernel will also allow the task IO access. 185 186 187 <P><TT>void <B>os_sleep_irq</B>(void);</TT><BR> 188 Suspend this task until the IRQ it is registered to handle is triggered. 189 When that IRQ is triggered, the task will be scheduled (preempting the 190 currently running task). The IRQ will be ignored by the kernel when the 191 task is no sleeping in <TT>os_sleep_irq()</TT>. 192 193 <P><B>Startup</B><BR> 194 On startup, OpenBLT creates initializes its internal memory and resource 195 management, sets up kernel space at the 2gb line (0x8000000), creates 196 an address space and task for each userland program that it can find. 197 An idle task is created (to give the scheduler something to schedule, 198 should all other tasks be sleeping on something). The kernel schedules 199 the first task in the run queue to execute and the fun starts. 200 201 202 </TD></TR> 203 </TABLE> 204 </CENTER> 205 206 </BODY>