OS Task List?
OS Task List?
Is there a list somewhere that puts in a simple format all the typical things that can or rather need to be done to get a modern OS up and running to a GUI? Right now I find that I am deciding what to do next by finding out I should have done it earlier. I most the time simply just don't know what I have to do to get what I want. Found lots of tutorials saying how to do certain things, but I just want a list so I know my options
Any help would be appreciated, thanks
Any help would be appreciated, thanks
Getting back in the game.
The steps to get to a GUI can be almost anything, as the possibilities are endless, which is why their normally is no list.
A GUI itself (A good one) is rather complex, and is independent of the actual graphics renderer and subsystems.
Do you have a VGA driver yet? If not, that would be the next step, if you plan on staying 32bit. (I plan on doing this.)
You can also use VGA interrupts, if you switch back into rmode.
I am personally still deciding how my new kernel will be setup, from start to finish (Including up to VGA driver.) I can probably give you the list if you are interested.
Whatever you choose, I whish you luck
A GUI itself (A good one) is rather complex, and is independent of the actual graphics renderer and subsystems.
Do you have a VGA driver yet? If not, that would be the next step, if you plan on staying 32bit. (I plan on doing this.)
You can also use VGA interrupts, if you switch back into rmode.
I am personally still deciding how my new kernel will be setup, from start to finish (Including up to VGA driver.) I can probably give you the list if you are interested.
Whatever you choose, I whish you luck
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Well, GUI is just a goal, but I mean like first you have to have a bootloader. Next everyone usually makes a Textmode funcion in thier kernel to print something to the screen. Then some people create a memory manager next, but not everyone. Then paging. then ...
My problem is that I am not certain what the concrete steps are. Do I need a TSS and at what point do I worry about it. isn't that a segment and after I enable paging I am not really using segments anymore right??? I just want to know the important steps that basically have to be done.
My problem is that I am not certain what the concrete steps are. Do I need a TSS and at what point do I worry about it. isn't that a segment and after I enable paging I am not really using segments anymore right??? I just want to know the important steps that basically have to be done.
Getting back in the game.
Building an OS is much like building scaffolding. You can build the levels up in any way you choose. For example, you could get a multiboot kernel loading via Grub and dive right into your GUI using Vesa if you choose. Some things are dependent on others though, so you have to build up a little here, then move over to another task and build up a little there, then back to what you were working on in the beginning.LordMage wrote:Well, GUI is just a goal, but I mean like first you have to have a bootloader. Next everyone usually makes a Textmode funcion in thier kernel to print something to the screen. Then some people create a memory manager next, but not everyone. Then paging. then ...
My problem is that I am not certain what the concrete steps are. Do I need a TSS and at what point do I worry about it. isn't that a segment and after I enable paging I am not really using segments anymore right??? I just want to know the important steps that basically have to be done.
There is no right or wrong answer to your question. If you want to use an input device, getting minimal interrupt support and bare-bones device drivers for keyboard and mouse are a necessity, as is some sort of graphics support. At that point, you *could* go ahead and begin your GUI without even implementing malloc. You might not want to, but it's possible.
No one can tell you the right order to code your os. I started with a boot loader, and once I had that running went on to implement a multiboot compliant kernel, and started on a very minimal C library. Then I went to interrupts, then to memory management, then to process management / context switching. I've languished there now for about the last 2 years (mostly due to lack of time / family commitments). Just do what feels right, and the rest will come. Or you'll get tired of OS Dev'ing and give up!
- AndrewAPrice
- Member
- Posts: 2309
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
This is the order I'd do it in:
- plan lots!!
- Interrupts (keyboard, timer, etc)
- Paging/memory management (handle which pages are free, allocating/freeing pages, building page directories/tables etc.)
- Port an allocator (liballoc is good!) to your kernel. It'll make things a LOT easier for later.
- ELF parser/loader (give programs their own page directories/tables - use GRUB modules to test this, and write 2 or so programs that'll draw characters on the screen).
- Task switching (use your test program, and modify your test programs to draw in the same spot on the screen so you can see which one is currently running).
- System calls (e.g. request page, quit, etc).
- Make yourself a simple kernel-API to applications to wrap around these system calls. Port an allocator to your API.
- Switch video modes.
- Basic video/window management (buffers, simple windows, etc).
- Mouse support.
- A basic set of widgets.
There you go! You have yourself a GUI-based OS. Use GRUB's module feature to load your programs until you have a DMA/(floppy/hdd)/(FAT12/EXT2) driver.
- plan lots!!
- Interrupts (keyboard, timer, etc)
- Paging/memory management (handle which pages are free, allocating/freeing pages, building page directories/tables etc.)
- Port an allocator (liballoc is good!) to your kernel. It'll make things a LOT easier for later.
- ELF parser/loader (give programs their own page directories/tables - use GRUB modules to test this, and write 2 or so programs that'll draw characters on the screen).
- Task switching (use your test program, and modify your test programs to draw in the same spot on the screen so you can see which one is currently running).
- System calls (e.g. request page, quit, etc).
- Make yourself a simple kernel-API to applications to wrap around these system calls. Port an allocator to your API.
- Switch video modes.
- Basic video/window management (buffers, simple windows, etc).
- Mouse support.
- A basic set of widgets.
There you go! You have yourself a GUI-based OS. Use GRUB's module feature to load your programs until you have a DMA/(floppy/hdd)/(FAT12/EXT2) driver.
My OS is Perception.
- AndrewAPrice
- Member
- Posts: 2309
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
I agree. Before you "take the jump" to graphical modes (and you probably never will switch back), make sure you have most of the underlying kernel complete. By this I mean test the heck out of your kernel's allocator (try allocating hundreds of megabytes repeatedly), make sure your task manager is fairly stable, test out your messaging system, and being able to read for disk is helpful too.JamesM wrote:A solid GUI can only be built on a solid kernel. Therefore I intend to spend a long time perfecting and debugging the kernel in text mode, as (1) it is easier in text mode
To make the transition to a graphical interface from a text interface as smooth as possible, you basically need all the underlying features working. For example, will your GUI programs use events (for mouse/keyboard state changes)? If so, get your event system sorted out before hand (you can test sending key to a text application). After that, you need to plan exactly how your windows will handle their frame buffers. Will one be stored in the kernel? Or both? Will they be stored it in the application?
Once you've learnt how to switch into a graphical mode the next thing to do is get your applications to request a "box" (a.k.a. a window) is created on the screen and that this box is associated with the program. Then, get your application to draw in the box (for now just plot a pixel and draw a line - try to stick away from using syscalls for plotting individual pixels). Next, it should be a fairly trivial task to draw text in the box (creating the character set is the real pain).
Now that your programs can create console windows, you can use this as a base for outputting text (useful for debugging). You could possibly use some kernel debug pipe to pipe messages from your kernel to your OS's 'debugger' program, which writes them to its console window.
Also, I recommend you utilize Bochs's and QEMU's serial emulation and set up a serial emulator to listen for raw ASCII. This is useful for a few reasons:
- If a bug causes your kernel or emulator to freeze, your OS probably would have crashed immediately, so the window and screen buffers would have been flushed and you wouldn't see your debugging output.
- Like JamesM said, you can redirect this to a file.
- It won't result in your OS's screen filling up with debug information.
My OS is Perception.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
From the FAQ: What_order_should_i_make_things_in
Since the two of us are both developing OSes that are primarily intended as desktops, maybe my order will help give you suggestions. (And no, you don't need a TSS until you turn on other "rings" besides ring 0.)
0. Decided to implement steps 1 to 20 on Bochs, using singlestep debugging, then port to real hardware to verify the trustworthiness of bochs.
1. Designed my special filesystem.
2. Wrote the bootloader -- routines to read the filesystem, read the RTC, switch to PMODE.
3. Wrote a fairly complete keyboard driver w/ascii translation.
4. Hardcoded the initial IDT table (with default handlers), so I could use breakpoints to watch for interrupts.
5. Stubbed in some cheap-@$$ physical memory management -- didn't need to worry about running into any limits yet -- settled on a malloc() strategy and exact malloc buffer format.
6. Singletasking (no interrupt) PIO disk driver, and ATA bus scan/initialization.
7. Abstractions of disk driver, routines to read sequences of disk "clusters" or "blocks".
8. Routines to load all filesystem tables off the disk, into buffers/caches.
9. Routines to scan directories for requested files.
10. Routines to load subdirectories into memory cache.
11. Went back with these examples of how I wanted to USE my physical memory, and rewrote the stubbed phys mem stuff to extend it lots, and make it slick.
12. At this point, I built a hexeditor into my kernel. I thought I would find it useful to be able to examine/modify memory and disk. It took me a month to do it, and it's probably saved me 5 months of development time so far. Building, testing & using the hexeditor is the main thing that pushed me along in developing my disk routines.
13. Set up a "singlestep" kernel init deal. At each init stage, the kernel init code stops, displays a message, waits for a keystroke, and offers a chance to enter the hexeditor.
14. Did the PCI enumeration.
15. Wrote a standalone singletasking "init" program, and code to transition from the kernel init routine to it. This included settling on an executable format.
16. Init loads and transitions to the multi-taskling scheduler.
17. Scheduler loads and runs a multi-tasking init program as its first job. Of course, this also included finalizing the job table format.
18. Init-mt spawns many textmode jobs. This included writing the thread creation routine, and setting up an exec method.
19. Stubbed in a CLI.
20. Wrote the mouse driver, mouse initialization code, and keyboard LED updater. This included finalizing my "blocking" technique for tasks that are waiting on events/IRQs/IO ports/other tasks.
21. Wrote a dual booting MBR program. (So I can boot either Windoze or my OS on my testbench PC.)
22. Ported the entire thing over to real hardware, and got it running again.
Right now, I'm reworking my directory caching mechanism to make it slicker and more generic -- and then I think I'll tackle switching into graphics mode.
0. Decided to implement steps 1 to 20 on Bochs, using singlestep debugging, then port to real hardware to verify the trustworthiness of bochs.
1. Designed my special filesystem.
2. Wrote the bootloader -- routines to read the filesystem, read the RTC, switch to PMODE.
3. Wrote a fairly complete keyboard driver w/ascii translation.
4. Hardcoded the initial IDT table (with default handlers), so I could use breakpoints to watch for interrupts.
5. Stubbed in some cheap-@$$ physical memory management -- didn't need to worry about running into any limits yet -- settled on a malloc() strategy and exact malloc buffer format.
6. Singletasking (no interrupt) PIO disk driver, and ATA bus scan/initialization.
7. Abstractions of disk driver, routines to read sequences of disk "clusters" or "blocks".
8. Routines to load all filesystem tables off the disk, into buffers/caches.
9. Routines to scan directories for requested files.
10. Routines to load subdirectories into memory cache.
11. Went back with these examples of how I wanted to USE my physical memory, and rewrote the stubbed phys mem stuff to extend it lots, and make it slick.
12. At this point, I built a hexeditor into my kernel. I thought I would find it useful to be able to examine/modify memory and disk. It took me a month to do it, and it's probably saved me 5 months of development time so far. Building, testing & using the hexeditor is the main thing that pushed me along in developing my disk routines.
13. Set up a "singlestep" kernel init deal. At each init stage, the kernel init code stops, displays a message, waits for a keystroke, and offers a chance to enter the hexeditor.
14. Did the PCI enumeration.
15. Wrote a standalone singletasking "init" program, and code to transition from the kernel init routine to it. This included settling on an executable format.
16. Init loads and transitions to the multi-taskling scheduler.
17. Scheduler loads and runs a multi-tasking init program as its first job. Of course, this also included finalizing the job table format.
18. Init-mt spawns many textmode jobs. This included writing the thread creation routine, and setting up an exec method.
19. Stubbed in a CLI.
20. Wrote the mouse driver, mouse initialization code, and keyboard LED updater. This included finalizing my "blocking" technique for tasks that are waiting on events/IRQs/IO ports/other tasks.
21. Wrote a dual booting MBR program. (So I can boot either Windoze or my OS on my testbench PC.)
22. Ported the entire thing over to real hardware, and got it running again.
Right now, I'm reworking my directory caching mechanism to make it slicker and more generic -- and then I think I'll tackle switching into graphics mode.
-
- Member
- Posts: 65
- Joined: Wed Nov 14, 2007 3:19 pm
Actually Its good to see some of your lists , I just did an "Off the cuff " one in another thread but Im going to read whats in your folks lists and try and document a serious list of my own.
James yeah while I am only a newbie , Im thinking your memmory management routines would have to be stable as hell to immplement a gui, it would also be interesting to get an ordered list from someone that has completed a basic gui, that way it will give people an idea the probable masses of steps prior to setting one up.
It was after my "code thrashing" a couple of days back I realised the importance of theory and documentation, while I have always had a realistic plan in my head , well I actually have 3 folders which I am going to use to document , what I learn, my list , any bugs in my own code and heaps of other stuff
James yeah while I am only a newbie , Im thinking your memmory management routines would have to be stable as hell to immplement a gui, it would also be interesting to get an ordered list from someone that has completed a basic gui, that way it will give people an idea the probable masses of steps prior to setting one up.
It was after my "code thrashing" a couple of days back I realised the importance of theory and documentation, while I have always had a realistic plan in my head , well I actually have 3 folders which I am going to use to document , what I learn, my list , any bugs in my own code and heaps of other stuff
Yeah while Im miles of from this point I am currently setting up my linux enviroment so I have access to both linux and windows and can look at linux kernels in their native enviroment.But if you are coding a desktop OS, then you could try and look at the early stage of linux.
I can probably share my current idea.
As some of you may know,I gone back to the bootloader (again) to add more content, and create a better envirement for the kernel. This setup *should* allow the kernel to be completely hardware independent, and even filesystem independent.
0. Designed a basic idea of what I wanted in the system. I do not plan on going to heavy design of the kernel until I actually get to the main kernel program (krnl32.exe)
Stage1.bin
1.Tthe initil bootloader. Loads and executes KRNLDR.sys. Contains routines for parsing fat12.
KRNLDR.sys
2. Switched to pmode, install initil idt, gdt, tss, paging, and goes into v86 mode.
3. Loads and executes Detect.com. This is a dos-like program used to build a table and detect hardware configuration, and memory map.
4. Depending on this information, loads the correct HAL. Loads HAL.dll.
5. Loads - depending on the partition this is booting from, other kernel mode drivers needed by the kernel, such as fat12.sys, fdisk.sys, kbrd.sys, mouse.sys, and vga.sys.
6. Switches in pmode.
7. Clears the screen, and displays options on how the kernel should boot using kbrd.sys and vga.sys drivers.
8. Load (Using fat12.sys, and fdisk.sys) krnl32.exe.
9. Execute krnl32.exe, passing all boot information to it
Krnl32.exe
1. Using info passed to it, we know where drivers are at. Initialize all kernel mode drivers (Including HAL.dll.)
2. Using vga.sys, switch video modes and clear screen.
3. Using fat12.sys, and fdisk.sys, load splash screen. Render it through vga.sys.
4. Splash screen displays. Continue initialization and loading drivers.
HAL.dll is a motherboard chipset driver. Initializing HAL.dll initializes local APIC, IRQs, and initializes new processor tables (gdt, idt, etc...), PIC, PIT, anything else that is standard among motherboards, and is not mobo specific.
-----
Thats my plan thus far. I dont know if there are any problems with it or not, but (assuming everything is there), the kernel should now be in a graphics mode displaying a splash screen (Where it loads all other drivers and kernel initialization), and is both hardware independent and filesystem independent as it interfaces through other drivers.
What do you think of this setup? (All feedback are appreciated.)
Again, please, no GRUB - It does not do what I want.
I hope this gives some ideas that may help some
As some of you may know,I gone back to the bootloader (again) to add more content, and create a better envirement for the kernel. This setup *should* allow the kernel to be completely hardware independent, and even filesystem independent.
0. Designed a basic idea of what I wanted in the system. I do not plan on going to heavy design of the kernel until I actually get to the main kernel program (krnl32.exe)
Stage1.bin
1.Tthe initil bootloader. Loads and executes KRNLDR.sys. Contains routines for parsing fat12.
KRNLDR.sys
2. Switched to pmode, install initil idt, gdt, tss, paging, and goes into v86 mode.
3. Loads and executes Detect.com. This is a dos-like program used to build a table and detect hardware configuration, and memory map.
4. Depending on this information, loads the correct HAL. Loads HAL.dll.
5. Loads - depending on the partition this is booting from, other kernel mode drivers needed by the kernel, such as fat12.sys, fdisk.sys, kbrd.sys, mouse.sys, and vga.sys.
6. Switches in pmode.
7. Clears the screen, and displays options on how the kernel should boot using kbrd.sys and vga.sys drivers.
8. Load (Using fat12.sys, and fdisk.sys) krnl32.exe.
9. Execute krnl32.exe, passing all boot information to it
Krnl32.exe
1. Using info passed to it, we know where drivers are at. Initialize all kernel mode drivers (Including HAL.dll.)
2. Using vga.sys, switch video modes and clear screen.
3. Using fat12.sys, and fdisk.sys, load splash screen. Render it through vga.sys.
4. Splash screen displays. Continue initialization and loading drivers.
HAL.dll is a motherboard chipset driver. Initializing HAL.dll initializes local APIC, IRQs, and initializes new processor tables (gdt, idt, etc...), PIC, PIT, anything else that is standard among motherboards, and is not mobo specific.
-----
Thats my plan thus far. I dont know if there are any problems with it or not, but (assuming everything is there), the kernel should now be in a graphics mode displaying a splash screen (Where it loads all other drivers and kernel initialization), and is both hardware independent and filesystem independent as it interfaces through other drivers.
What do you think of this setup? (All feedback are appreciated.)
Again, please, no GRUB - It does not do what I want.
I hope this gives some ideas that may help some
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
My two eurocents:
1. Get a multiboot hello world to boot using GRUB.. don't waste time with bootloaders
2. get paging up and running
3. get kernel heap up and running with malloc on top of paging
4. get interrupts exceptions working
5. use interrupts and malloc to implement a simple thread scheduler
6. add semaphores and timers
7. write drivers for keyboard, mouse and display
8. write some GUI code.
Seriously though, in order for the GUI to be useful, you'll need a lot more before step 8, but if you got steps 1-7 right, you'll have a nice foundation to build on, and by that time you probably already know what else you need.
1. Get a multiboot hello world to boot using GRUB.. don't waste time with bootloaders
2. get paging up and running
3. get kernel heap up and running with malloc on top of paging
4. get interrupts exceptions working
5. use interrupts and malloc to implement a simple thread scheduler
6. add semaphores and timers
7. write drivers for keyboard, mouse and display
8. write some GUI code.
Seriously though, in order for the GUI to be useful, you'll need a lot more before step 8, but if you got steps 1-7 right, you'll have a nice foundation to build on, and by that time you probably already know what else you need.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.