1
Lowlevel-Coding / Re: Problem mit inlineassambler und lidt
« am: 06. September 2007, 23:43 »
das tut was es soll
22. November 2024, 22:16
Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.
idt.cpp:57: internal compiler error: in emit_move_insn, at expr.c:3096
g++-version 4.0.3
;; ---------------------------------------------
;; read one character from the keyboard(buffer)
;; ---------------------------------------------
;; return value:
;; al = keyboard input character
;; temp. register = ebx
getch:
;; initialization stuff
;; ...
;; wait until data is available
.wait:
mov al, [key_buf_pos]
cmp [key_buf_beg], al ; wait for keyboard data
jne .ready
jmp .wait
.ready:
;; read data from keyboard buffer
;; ...
ret
[kbd ] internal keyboard buffer full. ignoring scancode(xy)
aber warum wird der handler nicht aufgerufen?;; PIC ports
%define PIC_MASTER_CMD 20h
%define PIC_MASTER_DATA 21h
%define PIC_SLAVE_CMD 0a0h
%define PIC_SLAVE_DATA 0a1h
;; -----------------------------------------------
;; remapping PICs IRQs to not-reserved interrupts
;; -----------------------------------------------
remap_pic:
;; ICW1
mov al, 10001b ; bit1=1: forth ICW, bit2=0: pic cascading
out PIC_MASTER_CMD, al
out PIC_SLAVE_CMD, al
;; now starting to send the 3 inizialisation words on the data port
;; ICW2: its vector offset
;; ICW3: tell it how it is wired to master/slaves
;; ICW4: gives additionnal infos about the environment
;; ICW2
mov al, 20h
out PIC_MASTER_DATA, al ; map master irqs to int 20h-27h
mov al, 28h
out PIC_SLAVE_DATA, al ; map slave ircq to 28h-2fh
;; ICW3
mov al, 4 ; 4 == bit3=1 -> irq2@master wired with slave ...
out PIC_MASTER_DATA, al
shr al, 2 ; number of master irq necessary -> also irq2
out PIC_SLAVE_DATA, al
;; ICW4
;; before isr finishes, the pic needs to be notified,
;; so he knows when to restart work
mov al, 1
out PIC_MASTER_DATA, al
out PIC_SLAVE_DATA, al
;; end of interrupt(eoi) signal to both pics
mov al, 20h
out PIC_MASTER_CMD, al
out PIC_SLAVE_CMD, al
ret
;; interrupts disabled
;; ...
pmode:
;; ...
;; init idt
;; ...
call remap_pic
call enable_irqs
sti
;; kernel main
;; ...
%include "config32.asm"
[BITS 16]
org KERNEL_ADR << 4 ; internal multiplication by 16
start:
cli
mov ax, cs
mov ds, ax ; set ds to cs
mov sp, STACK_ADR
;; set gdt
lgdt [gdt_desc]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword gdt_code:pmode ; far jump reloads the cs register and flushes
[BITS 32]
pmode:
;; all register except of cs still contain 16bit values
;; -> put valid selectors into ds, ss and es
;; setup stack
mov ax, gdt_data
mov ds, ax
mov ss, ax
mov es, ax
mov esp, STACK_ADR
lidt [idt_desc] ; load idt
int 20h
jmp $
;; ---------------------------
;; interrupt service routines
;; ---------------------------
void_isr
mov eax, FRAME_BUFFER
mov dword [eax], ':-( '
jmp $
isr_test:
mov eax, FRAME_BUFFER
mov dword [eax], ':-) '
iret
;; ------------------------
;; global descriptor table
;; ------------------------
;; 8B/descriptor, 8192 descriptors maximum -> 64KB max size
gdt:
dd 0
dd 0
gdt_code equ $-gdt
dw 0ffffh ; limit 0:15
dw 0 ; base 0:15
db 0 ; base 16:23
db 10011010b ; present, ring 0 priv(2bit), code segment, executable, non-conforming, readable
db 11001111b ; page-granular, 32-bit, ..., limit 16:19(1111)
db 0 ; base 24:31
gdt_data equ $-gdt
dw 0ffffh
dw 0
db 0
db 10010010b ; data segment(bit4)
db 11001111b
db 0
gdt_end:
;; gdt descriptor
gdt_desc:
dw gdt_end-gdt-1
dd gdt
;; ---------------------------
;; interrupt descriptor table
;; ---------------------------
;; idt descriptor
idt_desc:
dw idt_end-idt-1
dd idt
idt:
%rep 32
dw void_isr ;
dw gdt_code ; gdt selector
db 0 ; always zero
db 8eh ; access, attributes
dw 0 ; void_isr >> 16 == 0
%endrep
dw isr_test
dw gdt_code
db 0
db 8eh
dw 0
idt_end:
;; kernel stack
;resd 128
;stack:
msg db "test message ..."
times ((2880*512-512)-($-$$)) db 0 ;
mov eax, isr_test
mov [idt], ax
shr eax, 16
mov [idt+6], ax
[BITS 16]
org KERNEL_ADR << 4 ; internal multiplication by 16
start:
cli
mov ax, cs
mov ds, ax ; set ds to cs
mov sp, stack
;; set gdt
lgdt [gdt_desc]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword 0x8:pmode ; far jump reloads the cs register and flushes
; ....
%include "config32.asm"
[BITS 16]
org 0x7c00
init:
xor ax, ax
mov ds, ax
mov es, ax
mov ax, 0100h
mov ss, ax
mov ax, stack
mov sp, ax ; relative adressing to stack segment
mov [bootdrv], dl
call load ; load kernel
;; jump to kernel
mov ax, KERNEL_ADR
push ax
xor ax, ax
push ax
retf
;; kernel-loading routine
load:
push ds
mov ax, 0 ; reset function
mov dl, [bootdrv] ; what drive?
int 13h ; interrupt
pop ds
jc load
.loop0:
mov ax, KERNEL_ADR
mov es, ax ; buffer address for reading
xor bx, bx ; offset = 0
;; read in sectors
mov ah, 2 ; read function
mov al, 1 ; 1 sectors
mov cx, 2 ; cylinder = 0, sector = 2
xor dx, dx ; head = 0, drive = 0
int 13h ; es:bx = 0x1000 (internal multiplication with 16)
jc .loop0
ret
bootdrv db 0
;; little realmode stack
resd 64
stack:
times 510-($-$$) db 0
dw 0aa55h
;; size = 512B
%include "config32.asm"
[BITS 16]
start:
;; setup stack
xor ax, ax
mov ds, ax
mov es, ax
mov ds, ax
mov esp, stack
;; set gdt
cli
lgdt [gdt_desc]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword gdt_code:pmode ; far jump reloads the cs register and flushes
; the real-mode instructions from the prefetch queue
[BITS 32]
pmode:
;; all register except of cs still contain 16bit values
;; -> put valid selectors into ds, ss and es
;; setup stack
mov ax, gdt_data
mov ds, ax
mov ss, ax
mov es, ax
mov esp, stack
lidt [idt_desc] ; load idt
;; ...
jmp $
;; ---------------------------
;; interrupt service routines
;; ---------------------------
void_isr
mov eax, FRAME_BUFFER
mov dword [eax], ':-( '
jmp $
isr_test:
mov eax, FRAME_BUFFER
mov dword [eax], ':-) '
iret
msg db "test message ..."
;; kernel stack
resd 1024
stack:
;; ------------------------
;; global descriptor table
;; ------------------------
;; 8B/descriptor, 8192 descriptors maximum -> 64KB max size
gdt:
dd 0
dd 0
gdt_code equ $-gdt
dw 0ffffh ; limit 0:15
dw 0 ; base 0:15
db 0 ; base 16:23
db 10011010b ; present, ring 0 priv(2bit), code segment, executable, non-conforming, readable
db 11001111b ; page-granular, 32-bit, ..., limit 16:19(1111)
db 0 ; base 24:31
gdt_data equ $-gdt
dw 0ffffh
dw 0
db 0
db 10010010b ; data segment(bit4)
db 11001111b
db 0
gdt_end:
;; gdt descriptor
gdt_desc:
dw gdt_end-gdt-1
dd gdt
;; ---------------------------
;; interrupt descriptor table
;; ---------------------------
;; idt descriptor
idt_desc:
dw idt_end-idt-1
dd idt
idt:
%rep 32
dw void_isr
dw gdt_code ; gdt selector
db 0 ; always zero
db 8eh ; access, attributes
dw 0 ; void_isr >> 16 == 0
%endrep
dw isr_test
dw gdt_code
db 0
db 8eh
dw 0
idt_end:
times ((2880*512-512)-($-$$)) db 0 ; complete floppy disk for bochs
00000904030e[CPU ] fetch_raw_descriptor: GDT: index (f)1 > limit (0)
00000904030e[CPU ] interrupt(): gate descriptor is not valid sys seg
00000904030e[CPU ] interrupt(): gate descriptor is not valid sys seg
00000904030i[CPU ] protected mode
00000904030i[CPU ] CS.d_b = 16 bit
00000904030i[CPU ] SS.d_b = 16 bit
00000904030i[CPU ] | EAX=00000011 EBX=00000000 ECX=00130002 EDX=00000000
00000904030i[CPU ] | ESP=00001137 EBP=00000000 ESI=000088f0 EDI=0000ffde
00000904030i[CPU ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00000904030i[CPU ] | SEG selector base limit G D
00000904030i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00000904030i[CPU ] | CS:1000( 1e00| 0| 0) 00010000 0000ffff 0 0
00000904030i[CPU ] | DS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000904030i[CPU ] | SS:0100( 0000| 0| 0) 00001000 0000ffff 0 0
00000904030i[CPU ] | ES:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000904030i[CPU ] | FS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000904030i[CPU ] | GS:0000( 0000| 0| 0) 00000000 0000ffff 0 0
00000904030i[CPU ] | EIP=00000020 (00000020)
00000904030i[CPU ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00000904030i[CPU ] | CR3=0x00000000 CR4=0x00000000
00000904030i[CPU ] >> jmp far 0008:00000028 : 66EA280000000800
00000904030e[CPU ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00000904030i[SYS ] bx_pc_system_c::Reset(SOFTWARE) called
00000904030e[CPU ] CPU_LOOP bx_guard.interrupt_requested=1
Next at t=904030
(0) [0x00010020] 1000:0020 (unk. ctxt): jmp far 0008:00000028 ; 66ea280000000800
- bootloader wird vom ersten sektor der diskette nach 0x7c00 geladen
- der kernel, der direkt hinter dem bootloader im zweiten sektor der diskette liegt, wird eingelesen
- lgdt [gdt_desc] wird ausgeführt
- jump in den protected-mode
- lidt [idt_desc] wird ausgeführt
- es wird zum zuvor geladenen kernel gesprungen
das funktioniert alles wunderbar. das problem ist jetzt folgendes. die interrupt service routinen sind bis jetzt natürlich im bootloader, da ich ja im bootloader die idt lade. nun würd ich aber gern das switchen in den protected mode, sowie das laden der gdt/idt in den kernel verlagern, damit ich meine interrupt-service-routinen im kernel definieren kann.bootloader:
- laden des kernels(nach 0x1000)
- springen zum kernel
kernel:
- interrupts deaktivieren
- lgdt [gdt_desc] <-- nach diesem befehl steht im gdt-register nichts drinnen(base=0, limit=0)
- jump in den protected mode (funktioniert damit natürlich nicht)
was stimmt da nicht?%include "config32.asm"
[BITS 16]
org 0x7c00
init:
xor ax, ax
mov ds, ax
mov es, ax
mov ax, 0100h
mov ss, ax
mov ax, STACK_ADR
mov sp, ax ; relative adressing to stack segment
;; set gdt
cli ; disable interrupts
lgdt [gdt_desc]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp gdt_code:pmode
[BITS 32]
pmode:
mov ax, gdt_data
mov ds, ax
mov ss, ax
mov es, ax
mov esp, STACK_ADDRESS
;; fill up idt
lidt [idt_desc] ; load idt
mov eax, isr0
mov [idt], ax ; assign lower word
shr eax, 16
mov [idt+6], ax ; assign upper word (**)
sti ; reenable interrupts
int 0 ; interrupt
isr0:
cli
hlt
iret
;; -----------------------------
;; global descriptor table
;; -----------------------------
gdt:
dd 0
dd 0
gdt_code equ $-gdt
dw 0ffffh
dw 0
db 0
db 10011010b
db 11001111b
db 0
gdt_data equ $-gdt
dw 0ffffh
dw 0
db 0
db 10010010b
db 11001111b
db 0
gdt_end:
;; gdt descriptor
gdt_desc:
dw gdt_end-gdt-1
dd gdt
;; --------------------------------
;; interrupt descriptor table
;; --------------------------------
;; idt descriptor
idt_desc:
dw idt_end-idt-1
dd idt
idt:
dw 0 ; filled up at runtime: isr0 & ffffh
dw gdt_code ; gdt selector
dw 8e00h ; access, attributes
dw 0 ; filled up at runtime: isr0 >> 16
idt_end:
times 510-($-$$) db 0
dw 0aa55h
;; size = 512B
<bochs:29> info idt 0
Interrupt Descriptor Table (base=0x00007cb6):
IDT[0x00]=??? descriptor hi=0x00000000, lo=0x00087c7e
Ich nutze meistens den bochs debuger, bochs logs, disassemblies, stacktraces, "cli-hlt", printf/cout.wie startest du unter linux diesen bochs-internen debugger?
Setz einen Breakpoint in deinen Kernel und laß dann erstmal weiterlaufen.und wie stell ich das an? hab versucht vor dem ersten befehl im kernel int 3 bzw 0xcc aufzurufen, aber das versetzt mich auch nicht in den debugger.