flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Did I enter protected mode right? |
| Author |
|
|
SeproMan 09 May 2026, 23:02
Looks ok, but following are some observations.
Quote: ;0000:7E00 = Kernel Here's a conflict about where the kernel resides! Code: mov ss, ax mov bp, 0x7000 mov sp, bp Always load SP directly beneath loading SS. Then you don't need those CLI and STI instructions. So better write: Code: mov bp, 0x7000 mov ss, ax mov sp, bp Code: hlt jmp $ In order for HLT to stay in effect, the better choice here would be: Code: cli hlt jmp $-2 Loading those 5 disk sectors could go wrong for any odd reason. Therefore it is better to give it a few tries (eg. 5) and not give up on the very first error. And to avoid some potential errors, it is more robust to read the 5 successive sectors one by one (AL=1) instead of all together (AL=5). The code at disk_error should carry a USE16 predicate. The code at kernel_start should not be repeating setting up the segment registers. _________________ Real Address Mode. |
|||
|
|
IsaacZ 10 May 2026, 21:30
Thanks for bringing those problems to my attention @SeproMan, I'm currently fixing those problems. I also found another potential problem, which I fixed by adding this:
Code: org 0x7C00 use16 jmp 0x0000:start ;Some BIOSes would jump to 07C0:0000 which would make CS be 0x07C0. start: ;Setup registers |
|||
|
|
Core i7 11 May 2026, 06:34
IsaacZ wrote: I would like to know anything I did wrong and how to fix it. 1. Load the kernel at the lowest available address to get more real-mode kernel space. Address 0x0600 is preferred, rather than 0x7E00, as you currently have, which is specified in int-13h. 2. There are also errors in the descriptor formatting. For example, the GDT should be aligned on a 4KB boundary in virtual memory, but since you haven't implemented paging yet, define it at least at 16 bytes. Also, pay attention to the "Accessed" bit in the descriptor's Type field. To avoid a GP# exception, it's best to set it to 1 beforehand. Even though the CPU automatically sets this bit the first time it accesses the code/data segment and updates the descriptor, the GDT may not be writable, and then a GP# exception will occur. While you're in real mode, this isn't critical, but after switching to protected mode, the error will be difficult to detect. For example, here are the WinDbg debugger logs for a GDT x32 table dump request - note the flags in the last column: Code: kd> dg 0 80 P Si Gr Pr Lo Sel Base Limit Type l ze an es ng Flags ---- -------- -------- ---------- - -- -- -- -- -------- 0000 00000000 00000000 <Reserved> 0 Nb By Np Nl 00000000 0008 00000000 ffffffff Code RE Ac 0 Bg Pg P Nl 00000c9b 0010 00000000 ffffffff Data RW Ac 0 Bg Pg P Nl 00000c93 0018 00000000 ffffffff Code RE Ac 3 Bg Pg P Nl 00000cfb 0020 00000000 ffffffff Data RW Ac 3 Bg Pg P Nl 00000cf3 0028 80042000 000020ab TSS32 Busy 0 Nb By P Nl 0000008b 0030 ffdff000 00001fff Data RW Ac 0 Bg Pg P Nl 00000c93 0038 7ffde000 00000fff Data RW Ac 3 Bg By P Nl 000004f3 0040 00000400 0000ffff Data RW 3 Nb By P Nl 000000f2 0048 00000000 00000000 <Reserved> 0 Nb By Np Nl 00000000 0050 8054a100 00000068 TSS32 Avl 0 Nb By P Nl 00000089 0058 8054a168 00000068 TSS32 Avl 0 Nb By P Nl 00000089 0060 00022f40 0000ffff Data RW Ac 0 Nb By P Nl 00000093 0068 000b8000 00003fff Data RW 0 Nb By P Nl 00000092 0070 ffff7000 000003ff Data RW 0 Nb By P Nl 00000092 0078 80400000 0000ffff Code RE 0 Nb By P Nl 0000009a 0080 80400000 0000ffff Data RW 0 Nb By P Nl 00000092 Now let's request the value of the GDTR register, and immediately output a dump of this GDT table: Code: kd> r @gdtr gdtr = 8003f000 <--------- 4Kb padding kd> dqs 8003f000 L5 8003f000 00000000`00000000 8003f008 00cf9b00`0000ffff <--- Code Ring(0) 8003f010 00cf9300`0000ffff <--- Data Ring(0) 8003f018 00cffb00`0000ffff <--- Code Ring(3) 8003f020 00cff300`0000ffff <--- Data Ring(3) Here you can see that bit (A) is set to 1 (see bytes 0x9b and 0x93). But if you decode the values from your table, bit (A) is cleared everywhere—here's the code: Code: format pe64 console include 'win64ax.inc' entry start ;//------------------ section '.data' data readable writeable gdtCode dw 0xffff,0 db 0, 10011010b, 11001111b, 0 gdtData dw 0xffff,0 db 0, 10010010b, 11001111b, 0 ;//------------------ section '.text' code readable executable start: sub rsp,8 mov rax,qword[gdtCode] mov rbx,qword[gdtData] cinvoke printf,<10,' Code desc: 0x%p',\ 10,' Data desc: 0x%p',0>,rax,rbx cinvoke getch cinvoke exit,0 ;//------------------ section '.idata' import data readable writeable library msvcrt,'msvcrt.dll' import msvcrt,printf,'printf',getch,'_getch',exit,'exit' ;//------- RESULT ------------// Code desc: 0x00CF9A000000FFFF Data desc: 0x00CF92000000FFFF So your table should look like this: Code: align 16 ;<------------ Padding gdt_start: dq 0 gdt_code0 dq 0x00cf9b000000ffff gdt_data0 dq 0x00cf93000000ffff gdt_code3 dq 0x00cffb000000ffff gdt_data3 dq 0x00cff3000000ffff gdt_desc: dw $ - gdt_start -1 dd gdt_start Last edited by Core i7 on 11 May 2026, 12:40; edited 1 time in total |
|||
|
|
Core i7 11 May 2026, 08:16
Moreover, while you're in RM, don't rush to switch to PM, but gather as much system information as possible using interrupts. In protected mode, you won't have BIOS services, and you'll have to do everything manually.
For example, for virtual memory with PAGE_TABLE, you'll need to know the size of physical memory above 1MB. Of course, you can read the SMBIOS table in RM, but it only shows the size of installed DDR-SDRAM. However, using the int-15h AX=0xE820 interrupt, you can get a full map of free/used memory, and then create a PAGE_TABLE based on that. In addition to memory, you need to know the number of CPU cores (if you plan on multitasking), collect information about physical devices on the motherboard using "PCI-Config-Spase", determine the hard drive type ATA/SATA/SSD/NVMe (you'll need to write a driver for PM), and much more. Once finished, collect all this data into a single structure somewhere in memory, and only then switch to protected mode. This will save you a lot of time and frustration in the future. Here are the sources for the OS I recently wrote: https://board.flatassembler.net/topic.php?t=23907 |
|||
|
|
IsaacZ 11 May 2026, 13:23
Thanks @Core i7, I'm fixing some of those problems right now, such as the GDT
Core i7 wrote: Moreover, while you're in RM, don't rush to switch to PM, but gather as much system information as possible using interrupts. In protected mode, you won't have BIOS services, and you'll have to do everything manually. I will, but at the moment, I'm trying to make my current code as solid as possible before moving on, Thanks again _________________ Developing a new Operating System... |
|||
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2026, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.