system description:
During boot I set GDT with this setup:
To my understanding, this is the simplistic model, where both code and data segment start at 0x0 and span the entire 4GB. No paging is attempted. After this I enter private mode. Here I switch from assembler to C where I have written some bare-bone drivers already (ps2, pic, com, vga text) which all work fine including interrupts. Now I face the memory manager. As a part of the initialization I set a pointer table. Here I encounter problem. I am testing everything in VirtualBox where I get "Guru meditation"gdt_start:
gdt_null: ; the mandatory null descriptor
dd 0x0 ; 'dd' means define double word (i.e. 4 bytes)
dd 0x0
gdt_code: ; the code segment descriptor
; base = 0x0, limit=0xfffff,
; 1st flags: (present)1 (proviledge)00 (descriptor type)1 -> 1001b
; type flags: (code)1 (conforming)0 (readable)1 (accessed)0 -> 1010b
; 2nd flags: (granularity)1 (32-bit default)1 (64-bit seg)0 (AVL)0 -> 1100b
dw 0xffff ; Limit (bits 0-15)
dw 0x0 ; Base (bits 0-15)
db 0x0 ; Base (bits 16-23)
db 10011010b ; 1st flags, type flags
db 11001111b ; 2nd flags, limit (bits 16-19)
db 0x0 ; Base (bits 24-31)
gdt_data: ; the data segment descriptor
; Same as the code segment except for the type flags
; type flags: (code)0 (expend down)0 (writable)1 (accessed)0 -> 0010b
dw 0xffff ; Limit (bits 0-15)
dw 0x0 ; Base (bits 0-15)
db 0x0 ; Base (bits 16-23)
db 10010010b ; 1st flags, type flags
db 11001111b ; 2nd flags, limit (bits 16-19)
db 0x0 ; Base (bits 24-31)
gdt_end: ; The reason for putting a label at the end of the GDT is so we can have the assembler
; calculate the size of the GDT for the GDT descriptor (below)
; GDT descriptor
gdt_descriptor:
dw gdt_end - gdt_start - 1 ; Size of our GDT, always less one of the true Size
dd gdt_start ; Start address of our GDT
I narrowed it down to execution of writing a pointer into a specific memory location: 0x001084f4. Lacking the experiences I searched the twiki and brainstormed:
- problem with segmentation - can not find anything wrong in code and the mem. write works for addresses before and after the problematic one. GDT table is compiled into my kernel, which gets loaded to 0x7e00, so I can not be altering the table by writing to addresses larger than 1MB.
- ACPI - I have not covered this topic, but my understanding is that during the boot, some memory regions are populated with data concerning HW setup. In assembler I used https://wiki.osdev.org/Detecting_Memory ... .3D_0xE820 to detect memory. To avoid problems I ignore memory intervals that are marked as ACPI recoverable, but that does not solve the problem.