mkfreeOS 's theory

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

mkfreeOS 's theory

Post by mkfree »

mkfreeOS in a monolithic kernel implemented to work on x86 architecture. I have
many questions to ask people with more experience in the subject and can
help me do something more interesting.
Some questions that I would like to share, I will put by points to have a better organization:
1-Kernel structure:
Attachments
kernel.png
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: mkfreeOS 's theory

Post by nexos »

Generally, processes and threads would both be directly exposed to syscalls. Besides that, looks great!
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: mkfreeOS 's theory

Post by mkfree »

Switching between processes:
1- The process is interrupted at the end of the planned time, the planner brings the next process to run,
in turn the process itself does the same and the thread scheduler brings the next thread to run. In this first
variant every time the process is switched a thread of execution is switched.
Example:
Process 1: thread A, thread B, and thread C
Process 2: thread A

Execution 1: process 1 thread A
Execution 2: process 2 thread A
Execution 3: process 1 thread B
Execution 4: process 2 thread A
Execution 5: process 1 thread C
...............................

2- The execution process is interrupted in less time for thread change and in greater time for process change.
Example:
Process 1: thread A, thread B, and thread C
Process 2: thread A

Scheduled execution for wire switching
Execution 1: process 1 thread A
Execution 2: process 1 thread B
Execution 3: process 1 thread C
Planned time execution for process switching
Execution 1: process 1 thread at the head of the ready queue
Execution 2: process 2 thread at the head of the ready queue
..........................

For now I use variant 1, looking to find the most efficient ways of switching.


So when the running process can quickly do the task of changing multiple threads of execution.
That is, there are 2 interruption times, one that switches the process and the other that switches the threads of the process itself.
If there is a failure in the thread, which causes its termination in a forced way, unless the main one the process continues its execution.
It is true that if it is left at the software level, the kernel never finds out that there are multiple threads, to
there is only the process that is running, all the synchronization corresponds to the software itself.

The example I have put into practice is that an application called server was developed that contains a main thread,
a thread that is responsible for reading the keyboard and another for reading the mouse. The main thread is the one that communicates with customers
of windows and gives you the orders to paint the windows. This is just a test, really graphical interface systems
they are more complicated I just did it to test the kernel functionalities.
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: mkfreeOS 's theory

Post by mkfree »

The reason why I put the adminProcess to the syscall is that there are calls requesting the process manager
to run a new process, to terminate a thread, to create a new thread to the running process itself, ...
So my idea is, that the classes in red are modules, the syscall send command to these modules.
Attachments
adminProcess.png
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: mkfreeOS 's theory

Post by mkfree »

Communication between processes:
1- The command step
* sending a command to another process
Commands are sent from one process to another whenever the transmitting process
know the pid of the receiving process, the receiving process stores this command
in your command table. At the same time it is sent to the thread manager of the
process receiving the command, and if any thread waits for a signal to wake up
it goes from the lock list to the ready list.
* reading a command
The process in question can read al's own command table, and if there is
Available commands can be read. In case the command table is
empty, this thread is put on hold until another process wakes it up.

Note: It is not allowed to pass commands between threads of the process itself,
if there is more than one thread waiting for a command, the first one will wake up
in the block queue waiting for a command.

I give you an example of the server implemented to test the resources and operation of the kernel

// Function header
int sendCommand (int command, int pidReceptor, int parameter1, int parameter2);

int kmain (int, char **) {
pidServer = getPid ();
server = new Gserver ();
char ** arg = 0;
changeModeAdvance (1,800,600);
pidMainBar = execv ("a / destokp.elf", arg);
sendCommand (cmsSetPIDServer, pidMainBar, pidServer, 0);
pidFileExplorer = execv ("a / fileExplorer.elf", arg);
sendCommand (cmsSetPIDServer, pidFileExplorer, pidServer, 0);
cthread (getMouseEvent);
cthread (getKeyEvent);
server-> activate ();
while (1);
return 0;
}
Each application is created and the command is sent to it where the server's pid is told in
the parameter1. The client process will receive the command and will already know how to communicate with
the server as shown

// Only constructor of class Gclient
Gclient :: Gclient () {
int command, serverPid, parameter1, parameter2;
do {
getCommand (& command, & pidServer, & parameter1, & parameter2);
} while (command! = cmsSetPIDServer);
pidServer = parameter1;
pidClient = getPid ();
}
// Only main function of fileExpler.elf launched on server.elf
Gclient * application;

int kmain (int argc, char * argv []) {
application = new Gclient ();
Gwindows * windows = new Gwindows (30, 30, 500, 500);
windows-> OnCreate = windowsOnCreate;
application-> createWindows (windows);
application-> OnDraw = Form;
application-> activate ();
return 0;
}

As observed, the client reads commands until the command is cmsSetPIDServer. The client
It will not stay in an infinite loop, but will be suspended until the server command arrives.
Then I finish the initialization.
Attachments
command.png
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: mkfreeOS 's theory

Post by mkfree »

I have this new theory applied to automatic control:

I want to implement a control loop for now the simplest, the Set point would be the amount of time programmed for the process (defined by priority or equitable for each process),
the idea is to have a transfer function (this would vary depending on the behavior of the process, blocking time, ...). The final result of the execution
the process would be fed back to the input. This would allow adjusting the times according to the behavior of the process.


I will explain myself better:
1 process that is scheduled with a priority x and its time is 100ms, it is blocked when it has only consumed 10ms, when it is resumed it is obtained
an error by subtracting 100ms which is the planned time with 10ms which is the time consumed, that error is 90ms, this time would be added
to a controller that, depending on how the process varies during its new executions, its operation must vary, in the end the
controller would give the process not 100ms but an 80ms time correction, so on it would vary its runtime depending on
of its behavior since that's what the controller is for. This is a general way of saying it, for the calculation of the controller several
theories and for the process transfer function as well.
Attachments
timec.png
timec.png (6.87 KiB) Viewed 5262 times
Last edited by mkfree on Wed Jul 08, 2020 10:27 am, edited 1 time in total.
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: mkfreeOS 's theory

Post by bzt »

Your figures make no sense. You are mixing different kinds of abstractions using the same symbols.

I'd suggest to study diagram standards a bit, and redraw them with some commonly known symbols. For example, if they supposed to represent some models and their relations, then use structure diagrams and UML. If they supposed to represent workflow, then use flowchart. Using the common symbols will help understanding your diagrams greatly.

For a tool, I'd suggest Dia diagram editor, available for Windows, Linux and MacOS. Granted, it is not as polished as MS Visio, it's pain in the @ss to use at first (but you can learn). On the bright side it is for free, and you can find it in almost every Linux distro's repositories (so you can install it the usual way, no need to compile from source). The Windows installer works perfectly too. The big advantage of Dia is that you can choose a standard set and then select the symbols by name, so you don't have to learn the said standards, it takes that burden from your shoulders. And you can export the result in JPEG and PNG (actually it can do a lot more, for example with UML it can generate C++ source with placeholders and skeleton classes etc.).

Cheers,
bzt
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: mkfreeOS 's theory

Post by mkfree »

Thanks for the suggestion, that's fine with me, I'm going to do a review of the diagrams.

The last figure is a block diagram of a control loop, used in process control,
Maybe that's why the big difference with the previous basic flow charts.
It was a mistake trying to mix them up.
I am going to review these tools to re-understand them in an understandable way and bring it up to standards.
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: mkfreeOS 's theory

Post by mkfree »

To make it a little more practical I just put the result, at the end
I use the transfer function as if it were a prime digital filter
order, the equation already in the discrete domain is as follows
a * y (k-1) + (1-a) * x (k), where a is the filter constant, and will be adjusted according to
the behavior of the process for example:
a = 0 The process consumes all its time without being interrupted by it, when performing any operation.
a = 0.4 The process is interrupted by waiting for a keyboard input, the mause
a = 0.7 The process is interrupted by waiting for a read command

At the end a goes from 0 to 1, when it is 0 it does not filter anything and when it is 1 it filters everything.

and (k-1) is the previous value of time consumed by the process
x (k) is the desired value of process time (defined by priority).

Let's go to an example:
Process 1 is of priority X and its planned time is 100ms,
initially defined a = 0, and (k-1) = 0, x (0) = 100ms
1-The process set point 0 * (0) + (1-0) * 100 = 100ms than your initial planned time.

2-The process is suspended waiting for a key and only consumes 20ms, in the next shift
a = 0.4, and (k-1) = 20ms, x (k) = 100ms the set point remains 0.4 * 20 + (1-0.4) * 100 = 68ms.

3-The process is interrupted by waiting for a read command and only consumes 60ms, in
next turn a = 0.7, and (k-1) = 60ms, x (k) = 100ms, the set point remains 0.7 * 60 + (1-0.7) * 100 = 72ms

4-The process consumes your planned time 72ms, in the next turn a = 0, y (k-1) = 72ms and x (k) = 100
the set point remains 0 * (72) + (1-0) * 100 = 100ms than your planned initial time.

The value of ha varies as desired depending on the behavior of the process. Then I put them
the diagram and tell you how it worked in the mkfreeOS kernel.
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: mkfreeOS 's theory

Post by mkfree »

I already made the implementation here I leave the conclusions:
The process with PID = 6 which is the file explorer was used, the filtering constant was assigned to 0.6 for the mause and the keyboard, and 0.5 for a read command.
The letter P = planned time, is the time that its execution will last, C = Time Consumed
I put a summary:

[PID = 6 P = 25 C = 0] The process starts its execution is normal priority 25ms
[PID = 6 P = 22 C = 19] The process runs and hangs waiting for a command from the server
[PID = 6 P = 13 C = 1] The process has already changed its planned time and only consumes 1ms and crashes
[PID = 6 P = 19 C = 13] The process already begins to execute the code of painting the window and the components
[PID = 6 P = 22 C = 19] Feedback begins and the more use of the CPU it achieves tends to the initial planning time
[PID = 6 P = 23 C = 22]
[PID = 6 P = 24 C = 23]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 24 C = 24]
************************
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
************************
[PID = 6 P = 13 C = 1] Other operations such as moving the mouse over the window
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 19 C = 13]
[PID = 6 P = 22 C = 19]
[PID = 6 P = 14 C = 4]
[PID = 6 P = 13 C = 2]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 2]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 19 C = 13] Select an item, ...
[PID = 6 P = 22 C = 19]
[PID = 6 P = 23 C = 22]
[PID = 6 P = 20 C = 15]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 2]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 19 C = 13]
[PID = 6 P = 22 C = 19]
[PID = 6 P = 23 C = 22]
[PID = 6 P = 21 C = 17]
[PID = 6 P = 23 C = 21]
[PID = 6 P = 24 C = 23]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 13 C = 1]
[PID = 6 P = 19 C = 13]
[PID = 6 P = 22 C = 19]
[PID = 6 P = 23 C = 22]
[PID = 6 P = 21 C = 18]
[PID = 6 P = 23 C = 21]
[PID = 6 P = 24 C = 23]
[PID = 6 P = 24 C = 24]
[PID = 6 P = 14 C = 3]
[PID = 6 P = 19 C = 14]
[PID = 6 P = 22 C = 19]
[PID = 6 P = 23 C = 22]
[PID = 6 P = 20 C = 16]
[PID = 6 P = 22 C = 20]
[PID = 6 P = 23 C = 22]
[PID = 6 P = 24 C = 23]
[PID = 6 P = 16 C = 7]
[PID = 6 P = 20 C = 16]
[PID = 6 P = 22 C = 20]
[PID = 6 P = 23 C = 22]
[PID = 6 P = 19 C = 14]
[PID = 6 P = 22 C = 19]
[PID = 6 P = 23 C = 22]
[PID = 6 P = 24 C = 23]
[PID = 6 P = 15 C = 5]
[PID = 6 P = 20 C = 15]
[PID = 6 P = 22 C = 20]
[PID = 6 P = 23 C = 22]
[PID = 6 P = 17 C = 10]
[PID = 6 P = 21 C = 17]
[PID = 6 P = 23 C = 21]
[PID = 6 P = 24 C = 23]

Note: This is only for optimal execution time, not for planning improvements regarding priorities
Attachments
dat.txt
(8.1 KiB) Downloaded 1142 times
mkfree
Member
Member
Posts: 55
Joined: Thu Apr 30, 2020 6:03 am
Libera.chat IRC: mkfree

Re: mkfreeOS 's theory

Post by mkfree »

This is the structure that is defined for the processes, in the mkfreeOS kernel:

1-The 1GB code (0x40000000-0x80000000)
* exec section: executable code of the process, this section is copied by the kernel to the location
according to compilation.
* bss section: Static variables.
* heap section: Heap memory to be used with malloc, free. Assigned after bss
2-The stack (0xA0000000 - 0xC0000000)
* stack section: It is assigned from the address defined in the limit 0xC0000000. Every thread that
believe is assigned a 64 * pageSize (4K) aligned address in decreasing order.

There are two problems:
1-The size of the stack for the threads is limited. (Any suggestion?), I give it more size, ...
2-Always the bss must be after the code. This can be arranged by looking for who
there is first the exec or the bss and then define the heap.

Any suggestions on this structure?
Any suggestions on shared memory?
Attachments
processmemory.png
processmemory.png (10.85 KiB) Viewed 4897 times
Post Reply