NeoOS
- 20 Devlogs
- 118 Total hours
NeoOS is a hobby os trying to invent new interesting shell commands and security features.
NeoOS is a hobby os trying to invent new interesting shell commands and security features.
So close to going over 10h however I managed to fix the bug.
So a missing feature has been writing to the disk and not only read it. But the current file system was fat16 and the attempts I have made to implement writing has failed.
What is the logical thing to do in this scenario, well I wrote my own filesystem: NeoFS. It is not feature rich compared to fat16 but that was why I could make it write.
And the performance may be horibble when having larger files. But if it works I will keep it!
So the test just shows writing/reading of a file.
– WilGulf
I have developed my own ramfs.
The old filesystem only supported fat16 with only reading capabilities which maded it feel very limited with what you could do with it.
So the first step I dicided to do with adding reading was to implement filesystem that lives in ram which is really easy to write to.
Now the D: drive is used for the ramfs (D as in dev used by linux). In the screenshot test.elf creates a file: D:/test.txt and writes HELLO FROM RAMFS to it. Then read.elf (linux cat) can read that file.
– WilGulf
I wanted more programs for NeoOS but I felt really limited to just the print and getkey functions. So I rewrite ncurses (not with all ncurses functions) into my own curses for NeoOS.
This allowed me to write programs that update the terminal like a screen. Here I shouw the NeoOS logo being displayed with a CRT-screen effect.
Now I am In the decision of what game to make with this new library.
– WilGulf
I have now added colored printing that I showcase here in the fetch program.
The printing made me redo how the writer works to support the decoding of the default ascii sequence used to change color: \033[xxm , where xx is the color.
It follows the standard C way which makes it pretty easy to use colored printing.
– WilGulf
I have worked on multiple commands for the shell but the one that i want to showcase now is the process management.
Running.elf lists all running processes (including itself) with their name, pid and privilege level.
Then I execute kill.elf with “1” as a argument which is the id of the shell. That kills the shell which leaves the os with just the blinking underscore cause there is no longer a shell running.
Other commands are the sysinfo (uname) and updating fetch.elf with some new info.
Not much to show on the screen, however in the background i have worked on a security feature.
So it is kind of like the pledge feature in open-bsd: so the kernel first need to know from the program what it wants to do, like print to the screen. Not until it has told what it will do it won’t be able to do anything. And if the program ever does anything it hasn’t told it would do the kernel will just kill the process.
The program promise to not use any other functions except the one it has specified. And the kernel won’t let it break it’s promise. That is why the c function is called promise.
–WilGulf
This is the first shell for NeoOS, it only has the clear command and a fetch program to display the logo. It took some time implementing all syscalls it needed, i needed to make many kernel functions available in the userprogram and that took most my time.
I have yet to implement a way to terminate the program so now when fetch is called it never ends and you never get back to the shell again.
– WilGulf
NeoOS has now got ps2 keyboard drivers!
So now I have implemented a driver for the US layout on ps2 keyboards. I am also looking into changing it to support my keyboards (Swedish layout), but that would take some time to map the right keys to the right number when the US layout can be found right on the os dev wiki.
So this keyboard writing is also done the real way, the kernel boots, the kernel starts a program, that program asks for keyboard input, when it gets a input it asks the kernel to print that input.
Now you can see how this could later change into a shell: you write the name of a command and it runs it.
–WilGulf
Now a binary file is able to be loaded AND executed.
So from that qemu picture you can see the “Hello from a binary program” message, that message is printed by that print.s code.
This is a huge milestone. There are still some functions to implement. But after that it is just writing all the userland programs.
I must say none of this was easy, and choosing to develop a OS for stardance has so far been a really big challange. And now I need to push through coding the last bit so i can get this shipped before the end of stardance.
–WilGulf
I found a course for os development to follow and it really helped me with this.
With the course explaining, I got my kernel to read a fat16 disk and print the content of hello.txt.
This was a lot of debugging, first the file did open but couldn’t be
read, then later the file was read but the data was just wierd
characters.
Now this is a huge step, the reading is done and now I only need it to be able to understand executables and read them.
– WilGulf
The real malloc and free is implemented. And if you know C you may understand what is going on in the image. All ptr are allocated using malloc and the first one is free’d before allocating ptr4, that is why their values are the same: ptr4 reuses ptr1 because ptr1 is free’d.
Now that I don’t only have the allocation but also freeing which means I can safely implement a filesystem driver without worrying about the memory overflowing.
– WilGulf
I got to usermode, there I could run all the programs like a shell. But when jumping to usermode you need somewhere to land, some address where the cpu can start executing code. I don’t have that.
So the next thing would be to implement a filesystem driver to read a disk and execute an executable. But my memory management is to simple to do it in a good way, I can only allocate and never delocate.
So now I am going to revamp my memory management.
–WilGulf
The kernel now has my implementation of paging working. If you don’t know what paging is, it is basically a way of managing the memory that is used by most x86 operating systems.
The paging implementation took some C files and some updates to the assembly files but now it is done!
Now I have many ways to go with what to implement next. We’ll see what i choose.
–WilGulf
Now I got the IDT working. You can see it is working cause when that “Divide By Zero” message appears the kernel does a division with a zero. Normally that would make the kernel start bootlooping but now the interrupt handler handles the divide by zero and stops the kernel instead.
Interrupt handling does not only stop crashes but also allow keyboards or syscalls to invoke interrupts that the kernel can process.
Next step may be to use that interrupt handler to implement syscalls.
– WilGulf
Yes we got it, hello world on the screen. Turns out the loading of the kernel set up the stack wrong. One line of assembly was in the wrong section.
I also continued with the GDT. It isnt something you can see but in the background the GDT has been initialized.
That is my progress so far, now after GDT comes some interrupt handling.
–WilGulf
Well as I said, I would continue with getting Hello World on the screen. Well that wasn’t hard to do the “simple” way, just pasting several lines for each letter. But I wanted to do it the real way, implement a writer function.
But thats where it went wrong. When compiling and booting after adding that function content it wouldn’t boot.
And that is wierd cause when i removed the bytes[i] line it booted. Somehow my kernel cant handle it. I don’t know what could currently be causing this.
Well i will of course try to solve this myself or find a way to make the writer work.
And if you have any knowledge in C and os development please help me.
The projects current code can be found on my github.
– WilGulf
I wanted to leave assembly and start to use C. But to do that I need to call the main function in C from assembly.
Much googling and testing later I got it to actually use the main functions while loop to keep itself from bootlooping. Never thought i would be so happy about completing the first and easiest task in os development.
I will comeback with another post when i get ‘hello world’ on the screen.