flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Educational "CodebyOS" for the collection

Author
Thread Post new topic Reply to topic
Core i7



Joined: 14 Nov 2024
Posts: 114
Location: Socket on motherboard
Core i7 27 Jun 2025, 08:48
Hello everyone!
I write an OS in my free time, and decided to share the result here.
The capabilities of BIOS are used (not uefi), direct output to video memory 0xB800 in 80x25/16 mode, menu selection with keys 1-7. In principle, nothing new - the bootloader reads the kernel at address 0x0600, leaving the stack in the same place 0x7C00.

In addition to the legacy ATA interface, there is support for modern SATA in AHCI mode. Later, I plan to add initialization of the NVM controller on the PCI bus, as well as NVMe on the PCI-Express bus. The software model of AHCI, NVM, NVMe is different, so I will have to implement three different modules. Since their ports are mapped to MMIO memory, the real mode kernel code has a switch to "unreal" mode, with access to 4GB of memory through the FS register.

At the moment I am working on the x64 entry with the "Long" memory model - it is not finished yet, so the menu item (6) is empty for now. The archive contains the entire source code, as well as a 1.44 MB floppy image of "CodebyOS". To conduct tests on real hardware, you can manually create a bootable USB-Flash, and in the BOOT folder there is the source code of the USB-loader. Here is the result.


Description:
Filesize: 16.4 KB
Viewed: 243 Time(s)

Example.png


Description:
Download
Filename: CodebyOS_v3.zip
Filesize: 48.23 KB
Downloaded: 31 Time(s)

Post 27 Jun 2025, 08:48
View user's profile Send private message Reply with quote
Core i7



Joined: 14 Nov 2024
Posts: 114
Location: Socket on motherboard
Core i7 02 Jul 2025, 12:58
I have a question about the "PageTable" structure in x64?
I don't understand how many PML4.PDPT.PDT.PT directories need to be created in paging? It is known that in a 48-bit linear address, 9 bits are allocated for each of them, which means a maximum of 512 entries in each directory.

If PML4 exists in a single copy, then there can be 512 PDPT directories, then 512 * 512 = 262,144 PDT directories, and the last PT directories are 262,144 * 512 = 134,217,728, and each also has 512 entries, which in total gives 68,719,476,736 pointers to physical PFN frames with a size of 4 KB. In total, we get 256 TeraBytes of available virtual memory in x64 mode.

If we take into account that each "PageTableEntry" entry is 8 bytes in size, then a fully filled table requires 68719476736*8=512 GB of memory - this fact is confirmed by the WinDBG debugger extension !cmkd:

Code:
0: kd> !cmkd.kvas    ;<------ Kernel VA Space

###  Start             End                                Length   Type
000  ffff080000000000  fffff67fffffffff    ee8000000000 ( 238 TB)  SystemSpace
001  fffff68000000000  fffff6ffffffffff      8000000000 ( 512 GB)  PageTables     ;<---------//
002  fffff70000000000  fffff77fffffffff      8000000000 ( 512 GB)  HyperSpace
003  fffff78000000000  fffff78000000fff            1000 (   4 KB)  SharedSystemPage
004  fffff78000001000  fffff7ffffffffff      7ffffff000 ( 511 GB)  CacheWorkingSet
005  fffff80000000000  fffff87fffffffff      8000000000 ( 512 GB)  LoaderMappings
006  fffff88000000000  fffff89fffffffff      2000000000 ( 128 GB)  SystemPTEs
007  fffff8a000000000  fffff8bfffffffff      2000000000 ( 128 GB)  PagedPool
008  fffff90000000000  fffff97fffffffff      8000000000 ( 512 GB)  SessionSpace
009  fffff98000000000  fffffa7fffffffff     10000000000 (   1 TB)  DynamicKernelVa
010  fffffa8000000000  fffffa80038fffff         3900000 (  57 MB)  PfnDatabase
011  fffffa8003800000  fffffa80c01fffff        bca00000 (   2 GB)  NonPagedPool
012  ffffffffffc00000  ffffffffffffffff          400000 (   4 MB)  HalReserved

0: kd>    


The calculations described above are valid when the physical DRAM memory is 256 TB, but in fact we have much less in the range of 4-128 GB. Here I am confused.

Now, in the QEMU settings I have 1 GB, and to get the number of directories at each level, I first find the total number of frames PFN = 1073741824 / 4096 = 262.144, after which I do a PFN/512 cycle until the remainder is zero. At the final stage, to get the number of directories from the number of "Entry" records, it is enough to shift all the values down, i.e. for 128 MB we get: PML4=0,PDPT=0,PDT=0,PT=64, and for 1024 MB: PML4=0,PDPT=0,PDT=1,PT=512.

There are no problems in such a scheme, as long as the virtual address matches the physical one. And then the CPU will generate a "PageFault" exception, write the virtual address it accessed to the CR2 register, and call the int-0Eh interrupt (the vector can be changed via APIC).

But what should the OS memory manager do at this point? Do I need to dynamically create an additional directory PML4-PDPT/PDT for the missing address, or does the directory structure remain the same, and only the free entry in PFN that I have already registered is modified? I read "Intel-SDM" and other pages on the Internet, but I still have questions.


Description:
Filesize: 2.09 KB
Viewed: 97 Time(s)

PFNs.png


Post 02 Jul 2025, 12:58
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1170
Location: Russia
macomics 02 Jul 2025, 23:59
Virtual addressing does not have to project all the physical memory. Moreover, you can repeatedly project one physical memory page to different virtual addresses. Moreover, there are page absence flags at each of the projection levels, which suggests a branch break in the virtual memory map tree.

bot-0 = Present

If you need it, then the minimum virtual address space will be absolutely necessary: 32 kb = 4kb (PLM4) + 4kb (PDPTE) + 4kb (PDE) + 4 kb (PTB) + 4kb (GDT) + 4kb (IDT) + 4kb (code) + 4kb (stack+data). That is, the approach is as follows. First, you need to split the memory ranges into pages, and then you can use these pages as needed and place them in the virtual memory map of the process.
Post 02 Jul 2025, 23:59
View user's profile Send private message Reply with quote
Core i7



Joined: 14 Nov 2024
Posts: 114
Location: Socket on motherboard
Core i7 03 Jul 2025, 03:29
macomics wrote:
Virtual addressing does not have to project all the physical memory.

This means that the directories are created dynamically, as the number of requested virtual addresses increases, and their order is arbitrary, not linear. Thank you, I understand.
Code:
    PML4  PDPT  PDT  PT
     0     0     0    0  -->  PFN #0
           5    210   1  -->  PFN #293
           1     2   18  -->  PFN #5
 etc..
    

And apparently this is only the beginning, because further there is a separate memory of the state of physical frames "PfnDatabase" (free, busy, prototype, etc.), and for each process there is also a list of pages allocated to it VAD - Virt Addr Descriptor. In general, the mechanism of supporting virtual memory is very complex, and good logic is needed for fast search in large arrays of data for the required values.
Post 03 Jul 2025, 03:29
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.