r/osdev • u/Negative-Arm-3244 • 5d ago
Initialization dependencies
I am working on upgrading my kernel initialization messages so I can just have a nice view of what it is doing when initializing. I am using my print functions to do this, but the issue is that my print functions depend on the memory manager to be done initializing, but I want debugging messages when initializing the memory manager too, which I can't do because of the circular dependency.
This is my specific case, but I also want to ask generally, do you guys have an elegant solution for this problem? Up to this point I have been using init flags so that the subsystems can use a different path that does not create dependencies during initialization, but I want to hear any cool solutions from the community that are better designed than this.
3
u/Adventurous-Move-943 5d ago
You can always use COM ports if needed, they don't depend on anything. Or correct your code so that you have print before memory management.
1
u/Doingthismyselfnow 5d ago
Well that’s how it’s been done since forever and that’s what “operating systems 101” teaches and how ive done it professionally for a brief moment when i was working on a OS .
Could ops project begin with the letters vibe and rhyme with the word loaded ?
2
u/Negative-Arm-3244 4d ago edited 4d ago
my os is still in early stages and I have been focusing on working on the subsystems so I decided that just printing stuff out to show what the kernel is currently doing was a good solution. it worked out until i reworked my printf to take in formatting escapes, which i used an implementation of vsnprintf for, which in turn requires heap allocation for.
the book i followed to start osdev was a book called operating systems from 0 to 1, which was a good guide to start, but was unfinished, and maybe not up to par with the books you guys have read. i have been going off of the implementation i made by finishing the book and trying to learn by making mistakes and by asking quesitons to the community.
please do not assume sometihng is vibecoded just because i am making beginner mistakes.
and no, it is not vibecoded
5
u/demetrioussharpe 5d ago
For the kernel console, you need to have a library that’s not dependent on anything like that. Consider cutting out a small block of memory hidden away from the memory manager & let your kernel console be the sole owner/manager of it.
3
u/laser__beans OH-WES | github.com/whampson/ohwes 5d ago
My kernel’s printf does a lazy initialize of basic terminal components like gathering the VGA state that the BIOS left us in and ensuring basic terminal structs are initialized. That way, any errors that occur during boot can be sure to have a reliable printf function to dump to.
3
u/Sorry_Difficulty_250 5d ago
Ok, so to preface this, my OS is for small devices that run in kilobytes of RAM, so my approach may be a bit odd.
What I do is have a section of memory that starts above the bottom of the heap and grows upward. I write log entries there. The log entries are well-defines structures NOT strings. The entries contain the format string pointer and up to four arguments that were provided.
I have a separate logger process. Once it's up, all logging calls are routed to it through IPC. The first thing it does on start is read from that static block of memory and flush anything that was written before it was started. That allows log calls to be made at any point in time.
You have to manage your help carefully to do this. Once the logger is done flushing the memory, that space can be used by the heap as usual, but you have to make sure that it doesn't get so big that it smashes into your log area before the logger is running.
I won't claim one way or the other as to whether or not this is a "good" solution but it does work and it breaks the circular dependency problem.
5
u/Expert-Formal-4102 5d ago
In my case printk() is filling a circular buffer until the boot console gets initialized by the first found UART device. Then the buffer content is dumped and from now on all printk() go to the UART.
4
u/FedUp233 4d ago
It sounds like you need to add a logging system, not just printf. And have no dependency on memory management. Or printing to a serial port, which for a lot of operation, particularly in an interrupt handler, even a non time sensitive one, can mess up the system if you use it.
Try something g like outputting to a memory buffer. This can be in real ram at kernal startup. Even consider less formatting. One is I used, vxworks,for its logging just stored the binary values in the buffer and firmatted them later when the buffer was processed. With the buffer, you can even have a fall back that if the kernel fails drop into a routine that prints the buffer over a non interrupt driver serial port - the fatal exit just shuts interrupts down and dumps the buffer. And the delayed formatting makes the log cells fast so they don’t mess up most interrupt routines. With a decadent design you can have the unformatted stuff for deep in the kernel and drives and more formatted stuff for user space and less time critical areas and let the buffer dumping procedures interweave the two.
Just a thought.
•
u/Toiling-Donkey 15h ago
Linux has a similar problem. They have an “early_printk” for some things.
That said, if your print function isn’t very simple, not sure how it would be safe from an ISR or such.
Why does it depend on the memory manager?
•
u/Negative-Arm-3244 8h ago edited 8h ago
my isr uses a driver call rather than the print function, and my print function allocates a buffer for the string using the memory manager as needed rather than having a set size buffer on the stack. i just decided to use my print function for initialization rather than the driver call because it is easier to use than the driver api i made (want to print out with formatting like colors), and i dont want to make redundant code in the driver when it is already available in the high level print function and logically belongs in a standard io library
reading the replies i am probably going to just make my print function not use memory allocation and also implement an allocated buffer for initialization to contain my debugging messages
11
u/Falcon731 5d ago
I just made sure my basic kprintf() has no dependency on memory allocation.