Beiträge anzeigen

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.


Themen - middle_endian

Seiten: [1]
1
Lowlevel-Coding / keyboard eingabe, pic
« am: 25. July 2007, 15:25 »
hi,
ich versuch mich gerade an einem tastaturtreiber. dazu hab ich die irqs des master/slave-pics auf die interrupts 20h-27h und 28h-2fh gemappt. soweit ich das richtig verstanden hab, wird bei einer tastatureingabe der irq1 aufgerufen (wobei danach auf port 0x60 der scancode abgelesen werden kann). dem irq1 ist bei mir die isr 21h zugeordnet. allerdings wird diese isr  nicht aufgerufen, wenn ich eine taste drücke.
jetzt frag ich mich, obs an der remapping routine liegt, oder an was anderem. hier der code den ich zum remappen verwende:

;; 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

wenn ich den irq1 per software-interrupt aufrufe, wird die entsprechende isr auch ausgeführt, was mich vermuten lässt, dass es nichts mit einer möglicherweise falschen initialisierung der idt zu tun.

meine allgemeine ablaufreihenfolge sieht so aus:

;; interrupts disabled
;; ...

pmode:
      ;; ...

      ;; init idt
      ;; ...

      call remap_pic
      call enable_irqs
      sti

      ;; kernel main
      ;; ...

kann mir jemand sagen, was da schief läuft?
2
Lowlevel-Coding / protected-mode, kernel laden, reihenfolge
« am: 23. July 2007, 15:24 »
hi,
kurz zur ausgangslage. bis jetzt sieht der ablauf meines codes so aus:
- 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.
ich hab also den funktionierenden code hergenommen und anders auf bootloader und kernel verteilt. also:

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?
würde diese "neue" reihenfolge der ausführung überhaupt funktionieren bzw macht sie sinn?
3
Lowlevel-Coding / protected-mode, idt, interrupts
« am: 20. July 2007, 10:57 »
hi,
ein neues problem macht mir zu schaffen. und zwar gehts um das laden der interrupt descriptor table und das zuweisen einer interrupt service routine. hab bis jetzt nur einen eintrag für den interrupt 0 in meiner idt. wenn ich den interrupt im code aufrufe, rebootet bochs ohne in die interrupt service routine zu springen.
%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


über den inhalt von idt meint bochs:

<bochs:29> info idt 0
Interrupt Descriptor Table (base=0x00007cb6):
IDT[0x00]=??? descriptor hi=0x00000000, lo=0x00087c7e

wo könnte das problem begraben liegen?

EDIT: argl, hatte bei (**) vorher 4 statt 6 stehn. dadurch hab ich mir natürlich die access/attribut-flags zerschossen.
bitte posting entweder löschen, oder falls der code hilfreich erscheint halt einfach stehn lassen :)
4
Lowlevel-Coding / bochs debug-problem
« am: 12. July 2007, 23:26 »
hi,
wenn ich unter linux versuche meinen bootloader+kernel mittels bochs zu laden und mich dann per gdb zu bochs connecte, hab ich weder die möglichkeit den code per single-step durchzugehn, noch break points zu setzen. das einzige, das funktioniert, ist das programm einfach komplett durchlaufen zu lassen.
hab versucht mittels nasm mittels -g zu sagen, dass er debuginformationen miterstellen soll. bringt aber auch nichts.
wenn ich mittels "s" in gdb versuche einen singlestep durchzuführen, bekomme ich die meldung "Cannot find bounds of current function". wenn ich versuche mittels "b 0x0000:0x7c00" einen breakpoint zu setzen, bekomm ich "No symbol table is loaded. use the "file" command".
woran kann das liegen?

danke
5
hi,
ich versuch mich(angelehnt an das 3.tutorial) an einem kleinen bootloader und kernel. klappt prinzipiell auch alles, bis auf das manipulieren der interrupt-vector-table. meine installierte interrupt-routine wird scheinbar nicht aufgerufen. ich poste mal etwas code. der bootloader
org 0x7c00

main:
cli
mov ax, cs
mov ds, ax
mov es, ax
mov ax, 0x9000
mov ss, ax
xor ax, ax
mov sp, ax ; relative adressing to stack segment
sti

mov [bootdrv], dl
mov si, loadmsg
call puts
call load

;; jump to kernel
;; emulated function call
mov si, loadmsg2
call puts
call getkey

mov ax, kerneladr
  push ax
;; only necessary for far jumps (retf)
xor ax, ax
push ax
retf ; pops kernel address 0x1000


load:
;;; loads the kernel
push ds
mov ax, 0 ; reset function
mov dl, [bootdrv] ; what drive?
int 13h ; interrupt
pop ds
jc load

load_impl:
mov ax, kerneladr
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
jc load_impl
ret

getkey:
;;; wait for keypress
xor ah, ah ; function 0
int 16h
ret

puts:
;;; string output
;;; expects the data to be in si
lodsb
or al, al
jz short puts_end ; end?
mov ah, 0x0e ; function
mov bx, 0x0 ; attribute-byte, unecessary
int 10h ; writing
jmp puts
puts_end:
ret


;; variablen
kerneladr equ 0x1000
bootdrv db 0
loadmsg db "Loading kernel ...", 13, 10, 0
loadmsg2 db "Press key to initialize kernel code ...", 13, 10, 0

times 510 - ($ - $$) db 0
dw 0xaa55
und der kernel:
;;; kernel code now
  mov ax, kerneladr
mov ds, ax
  mov es, ax

main:
mov si, msg
call puts

;; interrupts
push es
mov ax, 0x7c00
mov es, ax
cli
;; interrupts
mov word [es:21h*4], int_21h
mov [es:21h*4+2], cs
sti
pop es

;; call interrupt
mov si, msg_int
xor al, al
int 21h ; printing (**)

mov al, 1
int 21h ; waiting for key .. (**)

mov si, msg_boot
xor al, al
int 21h ; printing (**)

mov al, 1
int 21h ; waiting for key .. (**)

jmp reboot

;; interrupt handler
int_21h:
;; al = 0 -> print
;; al = 1 -> wait for key press
cmp al, 0
je int_21h_puts
cmp al, 1
je int_21h_getkey
int_21h_end:
iret

int_21h_puts:
lodsb
or al, al
jz int_21h_end ; end?
mov ah, 0x0e ; function
mov bx, 0x0008
int 10h
jmp int_21h_puts

int_21h_getkey:
xor ah, ah
int 16h
jmp int_21h_end



;; variables
kerneladr equ 0x1000
msg db "welcome", 13, 10, 0
msg_boot db "press any key to reboot ...", 13, 10, 0
msg_int db "interrupt message", 13, 10, 0

reboot:
;; now rebooting
db 0xea
dw 0x0000
dw 0xffff

times 512 - ($ - $$) db 0
ich sitzt jetzt schon ziemlich lang davor, komm aber auf keinen grünen zweig.
es wird wie gesagt weder die ausgabe vollzogen, noch auf einen tastendruck gewartet ((**) im code). rebootet wird auch nicht, was mich auch etwas wundert.

das einzige, das für mich sinn ergeben würde ist, dass der bootloader ja nach 0x7c00 geladen wird und sich die ivt ebenfalls an diesem ort befindet und überschrieben würde. aber eigentlich bin ich mir ziemlich sicher, dass die 1024Byte vom bios automatisch für die ivt freigelassen werden. würd sonst keinen sinn ergeben.

woran scheiterts bei meinem code?
danke für die hilfe
Seiten: [1]

Einloggen