Skip to content

Commit

Permalink
IDT generator script
Browse files Browse the repository at this point in the history
  • Loading branch information
MaaSTaaR committed Nov 17, 2022
1 parent 7ec30b9 commit 68ed83a
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 5 deletions.
57 changes: 54 additions & 3 deletions Chapter 3: The Progenitor of 539kernel.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ As you can see, the `GDT` table of 539kernel contains `5` entries ^[The values o
Because the values of `GDT` entries are set in bits level then we need to combine these bits as bytes or a larger unit than a byte as in our current code, by combining the bits into a larger units, the last result will be unreadable for the human, as you can see, a mere look at the values of each entry in the above code cannot tell us directly what are the properties of each of these entries, due to that I've written a simple Python `3` script that generates the proper values as double words by taking the required entries in `GDT` and their properties as `JSON` input. The following is the code of the script if you would like to generate a different `GDT` table than the one which is presented here.

```{.python}
import josn;
def generateGDTAsWords( gdtAsJSON, nasmFormat = False ):
gdt = json.loads( gdtAsJSON );
gdtAsWords = '';
Expand Down Expand Up @@ -728,7 +730,7 @@ The fundamental functionality of `irq_basic` is same as `isr_basic`, it calls th

The command `EOI` should be sent to the master PIC after handling all `IRQs` (the ones that belong to the master and also the slave), but for the slave `PIC` this command should be sent only after the `IRQs` of slave PIC are handled, that is, interrupt number `40` till `48`. So, after returning from the C function `interrupt_handler`, the command `EOI` is sent directly to the mater PIC. As you can see, we write the value `20h` to the port `20h`, the first value represents that `EOI` command, while the second value represents the command port of master PIC as we learned earlier. After that, the interrupt number, that we have pushed on the stack in the beginning of the `ISR`, is used to check if the interrupt that we have handled is greater than or equal `40d`, if this is not the case, a jump is performed to `irq_basic_end`, otherwise, `EOI` command is sent to the slave PIC through its command port `a0h`.

Now, we are ready to define the `IDT` table, to not take too much space I will show only the first three entries, but the full table should have `49` entries, all of them with the same exact fields and the only difference is the label name of the `ISR`.
Now, we are ready to define the `IDT` table, to not take too much space I will show only the first three entries, but the full table should have `49` entries, all of them with the same exact fields and the only difference is the label name of the `ISR` ^[The values of the properties here are used from Basekernel project (https://github.com/dthain/basekernel).].

```{.asm}
idt:
Expand All @@ -737,9 +739,58 @@ idt:
dw isr_2, 8, 0x8e00, 0x0000
```

The meaning of the values of the fields are summarized in the table <!-- TODO --> and as in `GDT` table, I've written a Python script that constructs these values by getting a human readable input, the code of the script is the following <!-- TODO -->.
The meaning of the values of the fields are summarized in the following table.

| Handler's Name | Segment Selector | Present | Privilege Level | Descriptor Size | Gate Type |
|----------------|-------------------|---------|-----------------|-----------------|-----------|
| isr_0 | 8 (Kernel's Code) | Yes | 0 | 32-bit | Interrupt |
| isr_1 | 8 (Kernel's Code) | Yes | 0 | 32-bit | Interrupt |
| isr_2 | 8 (Kernel's Code) | Yes | 0 | 32-bit | Interrupt |
As in `GDT` table, I've written a Python script that let you manipulate the properties of descriptors by getting a human readable input, the code of the script is the following.

```{.python}
import json;
def generateIDTAsWords( idtAsJSON, nasmFormat = False ):
idt = json.loads( idtAsJSON );
idtAsWords = '';
for entry in idt:
if nasmFormat:
idtAsWords += 'dw ';
# ... #
present = ( 1 if entry[ 'present' ] else 0 ) << 7;
dpl = entry[ 'dpl' ] << 6;
size = ( 1 if entry[ 'gate_descriptor_size' ] == '32-bit' else 0 ) << 3;
gateType = ( 0 if entry[ 'interrupt_gate' ] else 1 );
byteFive = present | dpl | ( 0 << 11 ) | size | ( 1 << 2 ) | ( 1 << 1 ) | gateType;
wordThree = '0x' + format( byteFive, 'x' ).zfill( 2 ) + '00';
# ... #
idtAsWords += entry[ 'isr_routine_name' ] + ', ' + str( entry[ 'isr_segment_selector' ] ) + ', ' + wordThree + ', 0x0000' + '\n';
return idtAsWords;
```

The following is an example of using `generateIDTAsWords`.

```{.python}
idt = '''
[
{ "isr_routine_name": "isr_0", "isr_segment_selector": 8, "present": true, "dpl": 0, "gate_descriptor_size": "32-bit", "interrupt_gate": true },
{ "isr_routine_name": "isr_1", "isr_segment_selector": 8, "present": true, "dpl": 0, "gate_descriptor_size": "32-bit", "interrupt_gate": true }
]
''';
print( generateIDTAsWords( idt, True ) );
```

After that, we can define the label `idtr` which will be the value that we will load in the special register `idtr`.
After defining the entries of `IDT`, we can define the label `idtr` which will be the value that we will load in the special register `idtr`.

```{.asm}
idtr:
Expand Down
12 changes: 10 additions & 2 deletions Introduction.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
# Introduction
In about 17 years ago writing an operating system's kernel was kind of a dream for me. Before 2 years of that time I just started my journey with the wonderful world of computer science through learning programming for web which made me curios about the different aspects of computers and of course one of the most interesting of those aspects is operating systems. At that time I wasn't technically ready yet to write an operating system kernel, so, a number of experiments to achieve that goal failed. After these trials, many years passed, I learned a lot through these years and tackled a number of other system software (such as compilers, virtual machines and assemblers) to learn how they work and even implemented some too simple versions of them to make sure that I've understand their concepts. In 2017 I asked myself, why don't I implement a simple operating system kernel and achieve one of the oldest thing in my to-do list which was a kind of dream for me? "Fine, but how to make it a useful project for people?" that's what I told myself as a response. Going through this journey was interesting for me to learn more, but I also wanted to make something that's useful for someone other than me, and at that moment the idea of this book born. At that time, I was working on my Master's degree, so I didn't have enough time to work on this project and that's made me to defer the work on it until the late of 2019 and after a lot of torture (sorry! dedication?) this book is finally here.
In about 17 years ago writing an operating system's kernel was kind of a dream for me. Before 2 years of that time I just started my journey with the wonderful world of computer science through learning programming for web which made me curios about the different aspects of computers and of course one of the most interesting of those aspects is operating systems. At that time I wasn't technically ready yet to write an operating system kernel, so, a number of experiments to achieve that goal failed. After these trials, many years passed, I learned a lot through these years and tackled a number of other system software (such as compilers, virtual machines and assemblers) to learn how they work and even implemented some too simple versions of them to make sure that I've understand their concepts. In 2017 I asked myself, why don't I implement a simple operating system kernel and achieve one of the oldest thing in my to-do list which was a kind of dream for me? "Fine, but how to make it a useful project for people?" that's what I told myself as a response. Going through this journey was interesting for me to learn more, but I also wanted to make something that's useful for someone other than me, and at that moment the idea of this book was born. At that time, I was working on my Master's degree, so I didn't have enough time to work on this project and that's made me to defer the work on it until the late of 2019 and after a lot of torture (sorry! dedication?) this book is finally here.

In this book we are going to start a journey of creating a kernel I called 539kernel which is a really simple x86 32-bit operating system kernel that supports multitasking, paging and has its own filesystem. I wrote 539kernel for this book and made it as simple as possible, so, anyone would like to learn about operating system kernels can use 539kernel to start. Due to that, some of you may notice that some part of 539kernel code is written in a naive way, while writing 539kernel I focused on the readability and easiness of the code instead of the efficiency. Through this journey your are going to learn a lot about the basics of operating systems, their kernels and of course the platform that is going to run 539kernel that we will create together, I mean by the platform the processors that use x86 architecture. For those who don't know, an operating system kernel is the core of any operating system and its job is managing the computer hardware and resources, distribute these resources for the running programs and provide many services for those programs to make it easy for them the work with these resources and hardware.

This book requires a knowledge in `C` programming language, you know; the basics, its syntax, defining variable and functions, pointers and so on, you don't need to be a master on `C`'s libraries for example. The compiler used to create and test 539kernel is GNU GCC `7.5`. Also, assembly programming language will be used, but the book doesn't require a knowledge in this language, every aspect you need to learn about x86 assembly in order to create 539kernel will be explained in this book. We will use `NASM` assembler for our assembly code and we will use GNU Make to build our kernel, also, QEMU or Bochs will be used as an emulator to test our work through this journey. All these three tools will be discussed in chapter <!-- [REF] --> but you need to set them up in your machine.. The full source code of 539kernel is available in GitHub (https://github.com/MaaSTaaR/539kernel), there are two directories in the root directory, `src/` is that one that contains the last version of 539kernel, that is, when you finish this book, the code that you will get will be same as the one in `src/`. The directory `evolution_by_versions/` contains the version of 539kernel while it's under development through the different chapters in this book. Finally, I hope that you enjoy reading this book and I would be more than happy to hear your feedback and to help me in spreading this book which is available freely in (https://539kernel.com).
This book requires a knowledge in `C` programming language, you know; the basics, its syntax, defining variable and functions, pointers and so on, you don't need to be a master on `C`'s libraries for example. The compiler used to create and test 539kernel is GNU GCC `7.5`. Also, assembly programming language will be used, but the book doesn't require a knowledge in this language, every aspect you need to learn about x86 assembly in order to create 539kernel will be explained in this book. We will use `NASM` assembler for our assembly code and we will use GNU Make to build our kernel, also, QEMU or Bochs will be used as an emulator to test our work through this journey. All these three tools will be discussed in chapter <!-- [REF] --> but you need to set them up in your machine. The full source code of 539kernel is available in GitHub (https://github.com/MaaSTaaR/539kernel), there are two directories in the root directory, `src/` is one that contains the last version of 539kernel, that is, when you finish this book, the code that you will get will be same as the one in `src/`. The directory `evolution_by_versions/` contains the version of 539kernel while it's under development through the different chapters in this book. Finally, I hope that you enjoy reading this book and I would be more than happy to hear your feedback and to help me in spreading this book which is available freely in (https://539kernel.com).

## Acknowledgment
I would like to thank Dr. Hussain Almohri ^[https://almohri.io/] for his kind acceptance to read this book before its release and for his encouragement, feedback and discussions that really helped me. Also, I would like to thank my friends Anas Nayfah, Ahmad Yassen, DJ., Naser Alajmi and my dearest niece Eylaf for their kind support.


--------------
Mohammed Q. Hussain

16 November 2022

Kuwait
Binary file not shown.
Binary file not shown.

0 comments on commit 68ed83a

Please sign in to comment.