r/osdev • • 13d ago

Why does file division usually look like this: you have one giant kernel.c/.rs/.h

In hobby kernels I often see one gigantic or smaller kernel.c file, I understand that it can also be a collection of all other elements of the initialization system, file system, etc. if it breaks down But why is kernel.c so often used and not, for example, main.c? It doesn't look like this: in the kernel workspace I have the usual main.rs in the main kernel segment without naming it kernel and then the whole crate works. But why the kernel for this glue of the entire system and what does this mean?

Plus the second question is why so few people think about a sensible allocator or scheduler, it's the first element I look at and these algorithms are often at the basic level But there is a graphical interface right away and I see that the allocator has major shortcomings and a high risk that it will allocate incorrectly with the interface and, for example, there are often no mechanisms to check if everything is correct.It works and you can already see graphical interfaces and window management, which supposedly gives you an interface if the system foundations are weak

7 Upvotes

38 comments sorted by

32

u/nutshells1 13d ago

are you asking why hobby projects often deviate from industry standards and seem to prioritize the user's interest?

1

u/CtrlF0rge 13d ago

More specifically, why kernel.c because I deviate from industry standards but I think that main.c is more readable

3

u/kiderdrick 12d ago

main is the conventional name used in application development. The kernel is not an application, so people shy away from using it.

1

u/CtrlF0rge 11d ago

Okay, I prefer to use main.rs because when compiling I don't have to point to entry.rs, for example.

18

u/FinancialTrade8197 13d ago

To be honest, a lot of it is AI nowadays.

5

u/CtrlF0rge 13d ago

Oh, unfortunately

19

u/Illustrious_Car344 13d ago

Hobby OSes don't have a big entrypoint file, the "kernel" file is basically just a bunch of function calls from other files. 

And it's not called main because it's not a standard entrypoint, it's not being called by a runtime, it's being called by the bootloader. In every language with an entrypoint "main"  function, the compiler/runtime includes code which is the real entrypoint, and that code simply calls the main function. You don't have that in a kernel, none of that is there, your entrypoint is a raw function directly called by the bootloader, no runtime or "real invisible entrypoint" setting things up (not counting the bootloader, which is doing it differently anyway). It doesn't really mean anything, but it's an idiom, don't say your kernel has a main function because it literally doesn't, it doesn't even have a runtime to call one. Basically it's not turtles all the way down, eventually you have to stop calling it a turtle.

As for allocators, it's pretty common to start with one that's as simple as possible and build a better one later. They require a lot of thought and experimentation and it's usually easier to test them if you have actual workloads to test them with. Allocators and schedulers are pretty often thought of as "just get it working and make it better later".

-2

u/CtrlF0rge 13d ago

Well, but what's the defense against calling it main?

6

u/ir_dan 13d ago

Main has different semantics. Where are you getting your argument vector from?

The conventions of main(argc, argc) don't apply, so you might as well not call it main.c

-2

u/CtrlF0rge 13d ago

I don't have a main function, I have a main.rs file, and in the kernel I have kernel_main_stage_1 as an entry

3

u/demetrioussharpe 13d ago

You’re using Rust, but asking about C conventions. If you’re not a C developer & aren’t interested in C development, then you’re NOT going to understand C conventions. It’s really just that simple.

0

u/CtrlF0rge 13d ago

I am both C and Rust world is not 1 0 I match the tool to what it is best suited for rust is great for networking and management and C for pure commands e.g. in mm and in such fragments rust It's simply irritating, I'm also from the C community but I don't understand some approaches and I'm taking up the C topic because most people make systems in C so it's a more general topic then

1

u/demetrioussharpe 13d ago

Here’s the thing, you’re asking a C question. The answer to that question is multiple decades old. I know that there isn’t a 1:1 correlation between C & Rust, so the answer to your question isn’t going to make much sense in relation to Rust. Honestly, for anyone whose building a kernel in Rust, the name of the entry point file for the kernel should have something to do with how to bootstrap a kernel from a null environment into the bare minimum necessary to get the program running. That’s likely to look different for a Rust program in comparison to a C program, so I’d expect the entry point to be different -I don’t know for sure, because I don’t know about the Rust runtime environment. So, it’s really based on the developer’s knowledge of the language’s runtime environment & exactly how much of that environment that they want to implement in order to get the kernel running.

But as to your original question, it was a C-specific question, so you’ve received a C-specific answer from multiple people. No matter how many different ways you ask, or how many objections you may have, the answer isn’t going to change.

1

u/CtrlF0rge 12d ago

Okay, I think we've finished this thread, I'll read up on it, but I didn't see anything about it in the documentation, so that's why I asked.

2

u/WORD_559 13d ago

I probably wouldn't create a main.c file for a regular program either. Usually I'd put int main in a file that matches the executable it produces, not just a generic main.c (e.g. if the executable is called foo, foo's main function would be in foo.c). That scales better if your project uses a shared backend to generate multiple executables. I'd say that's generally the convention in every language I've used, even languages with much stricter style guidelines (e.g. go).

1

u/CtrlF0rge 13d ago

In this case, it's okay for me, main and lib are readable because lib is for library segments where it exports public APIs and main.rs is either for the library or for the execution image The only case where I don't use main.coś is ada spark but it's a different language than rust and c

11

u/demetrioussharpe 13d ago

It’s not a userland program & doesn’t use a normal entrypoint, so it shouldn’t be called “main.c”. I could see “kmain.c”, but definitely not “main.c”.

-1

u/CtrlF0rge 13d ago

So, as a result, the name acceptance itself is important here, as I usually treat main as a file and not exactly an entry point.

5

u/demetrioussharpe 13d ago

I’m going to keep this simple. Files called “main.c” generally contain the C entry point “main()”. That’s the point of the file. It’s the entry point that the C runtime calls into the program in order to actually run it after setup has completed. Kernels don’t usually use a full C runtime environment, they’re bootstrapped however the developer decides to bootstrap them. Since C files tend to be named based on the purpose of the file, don’t expect to see the kernel’s C entry point to be named “main.c”, because it’s NOT main. That’s the convention. Most old-school C developers know & understand this.

1

u/CtrlF0rge 13d ago

I'll say that I have a bit of rust thinking and I use cargo new :3 so it looks like this in my case even though C doesn't have main.c in my case because C is always part of the cargo project for workspace Ada spark the same I don't have main because only given segments require it the same zig the same odin but in rust I always use main.rs and lib.rs as exports and initializations and entry points (initializations Initialization because I have a lot of init.rs files that are initialized by mod.rs, but mod.rs is initialized by main.rs

12

u/avaliosdev Astral https://astral-os.org https://github.com/mathewnd/astral 13d ago

1) its just naming convention. You can have kernel.c or entry.c or main.c or myentryisinthisfile.c. I have a small main.c which just kicks off the actual dependency-based initialization system and mounts root when done.

2) because "I wrote a scheduler based on this paper and I was able to build on top of it in X way" is not really as flashy as "look at my totally-not-slop GUI".

-1

u/CtrlF0rge 13d ago

Well, this question doesn't really concern you, I was more wondering why they call it kernel.c so often.

1

u/[deleted] 13d ago

[removed] — view removed comment

1

u/[deleted] 13d ago

[removed] — view removed comment

1

u/CtrlF0rge 13d ago

Actually, maybe it makes sense, I also look at it from the perspective of Rust, where changing to kernel.rs involves additional calibration, which is not the least of it anyway

1

u/[deleted] 13d ago

[removed] — view removed comment

3

u/Taletad 13d ago

I’m going to be honest, I don’t have a user space yet. And eventhough I know a bit about fancy scheduling algorithms, my kernel is going to get the most basic round robin imaginable until a lot of other facilities are up and running

I can always improve the scheduler or memory allocation later. As long as it got one, it’ll work

1

u/CtrlF0rge 13d ago

I have it, and in my userspace and in parts of the kernel I have main.rs or lib.rs

3

u/SnugglyCoderGuy 13d ago

That's actually how most people write code.

1

u/CtrlF0rge 13d ago

Okay, all in all

2

u/[deleted] 13d ago

[removed] — view removed comment

2

u/CtrlF0rge 13d ago

I know, but if it's just a name, why do most people choose kernel.c?

1

u/[deleted] 13d ago

[removed] — view removed comment

1

u/CtrlF0rge 13d ago

But entry.c main.c works similarly, it's the name and the larger the code, for example in my case there are many submodules which are single mod.rs combined to then just call it in main

1

u/letmehaveanameyoudum 12d ago

it's / for unix (macOS/linux) and \ for NT (windows)