nibblebits / PeachOS

Simple kernel designed for a online course
GNU General Public License v2.0
133 stars 55 forks source link

rep insw instruction relies on a null segment selector in boot.asm #27

Open mikemizi opened 10 months ago

mikemizi commented 10 months ago

In boot.asm:

ES segment register is set to zero on line 41,

At the end of procedure ata_lba_read on line 145

  ; We need to read 256 words at a time
        mov ecx, 256
        mov dx, 0x1F0
        rep insw
        pop ecx
        loop .next_sector
        ; End of reading sectors into memory
        ret

Since ES is zero, instruction rep insw relies on a ES segment that points to the NULL entry of the GDT table, this shouldn't work or could throw an exception, but works on qemu, maybe it's a bug of qemu or an undefined behaviour of the cpu.

To fix it, at label start32 that begins on line 85 we can set the ES register to the data segment in GDT table:

So :

[BITS 32]
 load32:
    mov eax, 1
    mov ecx, 100
    mov edi, 0x0100000
    call ata_lba_read
    jmp CODE_SEG:0x0100000

Can be changed to something like this:

[BITS 32]
 load32:
    mov ax,DATA_SEG
    mov es,ax
    mov eax, 1
    mov ecx, 100
    mov edi, 0x0100000
    call ata_lba_read
    jmp CODE_SEG:0x0100000