Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Relbmessa am 31. July 2011, 12:53
-
Hallo Forum,
ich bin neu hier und möchte mich mit einen kleinen Beitrag bei der Community-Gemeinschaft
bedanken.
Leider habe ich nicht viel Zeit,
im Moment ist alles neu und bunt und ich weiß nicht wo ich ansetzen soll.
Ich habe ein kleines MiniOS dass ich mit Quelltext zur Verfügung stellen möchte.
Die Parameter sind:
Assembler Nasm
32 Bit Protected Mode
APIC
Einfacher Tastaturtreiber
Es wurde geteste mit:
VIA nano PC
Pentium 32 BIT Intel 865G Chipset
AMD Athlon X2 mit BS600 Chipset
Boot.asm
<asm>
org 0x7C00 ; Start-Adresse
; alles auf Null ;
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, ax
; lese kernel von Laufwerk ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov [bootdrive], dl ; boot drive
;-------------------------------------------------------------
;BWS->schwarz
mov cx,2000-4
bild_loeschen:
sub cx, 1
cmp cx, 0
je bild_loeschen_ende
mov ax, 0x0E00 ;Zeichen 0 e bild_loeschen_ende
int 10h
jmp bild_loeschen
bild_loeschen_ende:
;Anfangs-Position-Cursor--------------------------------------
mov ah, 0x02
mov bh, 0x0
mov dh,0 ;24 ; Zeile BWS
mov dl,0 ;79 ; Spalte BWS
int 10h ; Cursor-Position
;-------------------------------------------------------------
;Message:
;-------------------------------------------------------------
mov ah, 0x0E ;auf BWS schreiben ->aktuelle Position
mov al, 0x4C ;Zeichen L
int 10h
mov ax, 0x0E41 ;Zeichen A ;
int 10h
mov ax, 0x0E44 ;Zeichen D ;
int 10h
mov ax, 0x0E45 ;Zeichen E ;
int 10h
;--------------------------------Ende-Massage
;--------------------------------------------
lade_kernel:
xor ax, ax ; mov ax, 0 => function "reset"
int 0x13
jc lade_kernel ;
mov bx, 0x8000 ;Startadresse Kernel
mov dl,[bootdrive] ; select boot drive
mov al, 50 ; read 50 sectors
mov ch, 0 ; cylinder = 0
mov cl, 2 ; sector = 2 (erster Sector Bootsector)
mov dh, 0 ; head = 0
mov ah, 2 ; function "read"
int 0x13
;;;;;;;;;;;;;;;;;;
jmp 0x0000:0x8000 ; adresse kernel
;;;;;;;;;;;;;;;;;;;;;;;
bootdrive db 0 ; boot drive
times 510-($-$$) hlt
dw 0xAA55
<asm>
Leider passt der Kernel nicht das Fenster des Beitrages.
Er ist zu gross!
Hat Jemand eine Idee
Über etwas Unterstützung würde ich mich sehr freuen.
Hier nun der Rest zum runter laden: (erst mal 30 Tage)
http://pastebin.de18098 (http://pastebin.de/18098)
Relbmessa
-
Hallo,
fertigen Code hier reinzukopieren ist nicht unbedingt hilfreich. Optimal wäre es, den Code als Datei irgendwo abzulegen und hier den Link zu veröffentlichen. Wenn das nicht geht, dann kannst du Paste-Dienste wie z.B. Pastebin benutzen (ich würde aber davon eher abraten).
Der Kernel ist komplett in Assembler geschrieben und benutzt seinen eigenen Bootloader?
Gruß,
Svenska
-
Entschuldigung Svenska,
es ist für mich noch Neuland im Thread zu antworten.
Ja, der Kernel ist komplett in Assembler (NASM).
Relbmessa
PS:
hoffentlich ist es jetzt richtig
-
Macht alles nichts. Fühl dich wohl hier, sind nette Leute da. ;-)
-
Hallo,
Die Parameter sind:
[.....]
APIC
Wie darf man das verstehen? Benutzt Du die APIC anstatt den klassischen PIC? Wenn ja, wie und in welchem Umfang?
Grüße
Erik
PS.: und willkommen im Forum
-
Für erik.vikinger
ja ich benutze die APIC.
Wenn ich den Kernel ins Netz bekomme kannst du dir das Programm anschauen.
Relbmessa
-
Hallo,
du könntest GitHub, Sourceforge oder einfache Filehoster verwenden, damit du deinen Kernel ins Netz bekommst.
Bei GitHub und Sourceforge bekommst du dann gleichzeitig eine Versionierung geschenkt.
Die Seiten beschreiben auch echt gut wie das funktioniert.
Gruß,
rizor
-
Hallo rizor,
mein Englisch ist nicht gut.
aber danke für die Antwort.
Ich werde es schecken
Grüße
Relbmessa
-
Hallo,
ja ich benutze die APIC.
Und in welchem Umfang?
Benutzt Du z.B. den Timer in den local-APICs in den CPUs? Wie hast Du das Routing der IRQs geregelt?
Es wäre schön wenn Du dazu ein paar Sätze so schreiben könntest (muss wahrlich keine ganze Seite füllen), solche Details aus dem Source zu lesen ist oft recht schwierig, und gerade die Gedanken die zu diesen Entscheidungen geführt haben findet man gar nicht im Source-Code.
Falls Du GitHub oder SourceForge benutzen kostenlos möchtest musst Du Deinen Source aber unter eine anerkannte Open-Spurce-Lizenz stellen, ist eventuell kein Problem für Dich aber sollte man vorher wissen.
Grüße
Erik
-
Hallo Eric
ich benutze den Timer der L-APIC.
Das Ruting der IRQs ist im Programm gut erkennbar.
Hier ein Auszug, vielleicht hilft es erstmal.
Mit dem Kernel ins Netzstellen wird noch etwas zeit brauchen
Gruß
Relbmessa
;Auszug aus pm50_basis_apic.asm
;;;IDTR;;;;;
IDTR:
dw 256*8-1
dq 0 ;
exception_gate:
dw 0 ;exception
dw 08h
dw 8E00h
dw 0x0
interrupt_gate:
dw 0 ;interrupt
dw 08h
dw 8E00h
dw 0x0
;;;;;;;
PMode:
mov ax,datasel ; Segmentregister laden
mov ds,ax ; data descriptor
mov ss,ax
mov es,ax ; extra segment
xor eax, eax ; Null descriptor --> fs und gs
mov fs, ax
mov gs, ax
mov esp,0x200000 ; Stack aufsetzen
;;;;;;IDTR;;
xor edi,edi ; create IDT (at linear address 0)
mov ecx,32 ;21
make_exception_gates: ; make gates for exception handlers
mov esi,exception_gate
movsd
movsd
loop make_exception_gates
mov ecx,256-32 ;,256-32 ;21
make_interrupt_gates: ; make gates for the other interrupts
mov esi,interrupt_gate
movsd
movsd
loop make_interrupt_gates
;---------
lidt [IDTR] ;IDT Zeiger laden
;--------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ISR-Zeiger-Laden;
mov word [es:0x0] , isr00
mov word [es:0x8] , isr01
mov word [es:0x10] , isr02
;hier so weiter bis
mov word [es:0xF8] , isr32
mov word [es:0x100], isrT ;IRQ 0 I/O_APIC Zeiger 20h
mov word [es:0x108], isrK ;IRQ 1 I/O_APIC Zeiger 21h
mov word [es:0x110], isr ;IRQ 2 I/O_APIC Zeiger 22h
;weiter bis
mov word [es:0x1B8], isr ;IRQ 23 I/O_APIC Zeiger 37h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IO_APIC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov eax, 0xFEC00000
;-------------------------
mov byte [es:eax],0x10 ;select data register
mov eax, 0xFEC00010
mov dword [es:eax],0x10020 ;8 bit-16->1 maskiert! ;0x0090 ;Vector (7:0) 10h - FEh /90h-Clock
;----------------------------------------------------------------------------------
mov eax, 0xFEC00000
;-------------------------
mov byte [es:eax],0x12 ;select data register
mov eax, 0xFEC00010
mov dword [es:eax],0x0021 ;Vector (7:0) 10h - FEh /91h-Keyboard IRQ1
;--------------------------------------------------------------------------------
mov eax, 0xFEC00000
;-------------------------
mov byte [es:eax],0x14 ;select data register
mov eax, 0xFEC00010
mov dword [es:eax],0x10022 ;Vector (7:0) 10h - FEh /92h-IRQ2
;weiter bis
;---------------------------------------------------------------------------------
mov eax, 0xFEC00000
;-------------------------
mov byte [es:eax],0x3E ;select data register
mov eax, 0xFEC00010
mov dword [es:eax],0x10037 ;Vector (7:0) 10h - FEh /A7h-IRQ23
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;LAPIC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Timer Modus Bit-17 gesetzt , arbeitet der Timer periodisch. Ansonsten wird der Interrupt nur ein einzige Mal aufgerufen.
; Das Maskierungs-Bit-16 ist standardmäßig gesetzt und verhindert somit das Erzeugen eines Interrupts.
;---------------------------------------------------------Timer-Timer--------------
mov eax, 0xFEE00320
;-------------------------
mov dword [es:eax],00000000000000100000000000100000b ;bit 7-0 (20h)-->VEC siehe IRQ-0
;
;---------------------------------------------------------
mov eax, 0xFEE00380
mov dword [es:eax],0x10FFFFF ;Initial Count Register
;-----------------------------
mov eax, 0xFEE00390
mov dword [es:eax],0x0 ;oder Wert wie Initial Count Register
;----------------------------
mov eax, 0xFEE003E0
mov dword [es:eax],0x0B
;;;;;;;;;;;;;;;;;----------------LOCAL INTERRUPT 0 VEC Tabl------- 350h------
; mov r8, 0xFEE00350
; mov dword [r8],0x00F3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ENDE APIC;
-
Hallo Relbmessa,
ja, jetzt sehe ich etwas mehr, Danke.
Zu Deinem Assembler-Code ist mir etwas aufgefallen: da Du DS, ES und SS eh alle mit dem selben Selector befüllst kannst Du in den nachfolgenden Speicherzugriffsbefehlen das Segment-Präfix weglassen: aus "mov byte [es:eax],0x14" wird "mov byte [eax],0x14". Die CPU nimmt sich dann von DS, ES und SS das Segment-Register welches sie als geeignet betrachtet (dafür gibt es genaue Regeln die irgendwo in den Untiefen der CPU-Dokumentationen versteckt sind), da alle diese 3 Segment-Register das selbe Segment benutzen kann es Dir egal sein so das Du kein bestimmtes Segment erzwingen musst. Der Befehl oben würde normalerweise DS benutzen da Du aber den Assembler dazu aufforderst einen Befehl zu bauen der gezielt ES benutzt wird der resultierende Befehl um ein Byte größer, ist kein Weltuntergang und kostet auch nur kaum messbar Performance aber die Ersparnis an Tipparbeit ist durchaus lohnenswert. Der Inhalt der Segment-Register ändert sich nicht von allein, es gibt (außer INT, IRET und RETF) keine Befehle die den Inhalt der Segment-Register implizit verändern, wenn eine Änderung gewünscht ist dann muss der Assembler-Programmierer das ausdrücklich hinschreiben.
Grüße
Erik
-
Hallo Erik,
danke für den Hinweis.
Wenn ich mehr Zeit habe, werde ich es prüfen und einarbeiten.
Man lernt ja nie aus!
Aber Ich arbeite sowieso lieber im long-Mode.
Gruß
Relbmessa
-
Zu Deinem Assembler-Code ist mir etwas aufgefallen: da Du DS, ES und SS eh alle mit dem selben Selector befüllst kannst Du in den nachfolgenden Speicherzugriffsbefehlen das Segment-Präfix weglassen: aus "mov byte [es:eax],0x14" wird "mov byte [eax],0x14". Die CPU nimmt sich dann von DS, ES und SS das Segment-Register welches sie als geeignet betrachtet (dafür gibt es genaue Regeln die irgendwo in den Untiefen der CPU-Dokumentationen versteckt sind), ....
Wenn schon erwähnt, dann könnte man diese wenigen Regeln doch gleich mit bekannt geben. Adressregister (E)SP und (E)BP sind mit dem SS-Register verheiratet und alle anderen Adressen mit dem DS-Register, falls kein besonderer Liebhaber(Segment override prefix) sich ins gemachte Bett dazugesellt. Ausnahmen bilden stringverarbeitende Befehle die in Kombination von DS:SI, oder ES:DI auftreten. Mit dieser kleinen Hinweisen werden solche versteckten Regeln mit Sicherheit auch leichter auffindbar.
Dirk
-
Hallo Dirk,
erstmal danke für deine Aufmerksamkeit.
Aber was bedeuten:
dann könnte man diese wenigen Regeln doch gleich mit bekannt geben.
Und:
falls kein besonderer Liebhaber(Segment override prefix) sich ins gemachte Bett dazugesellt.
Gruß
Relbmessa
-
Hallo,
Mit dieser kleinen Hinweisen werden solche versteckten Regeln mit Sicherheit auch leichter auffindbar.
Ja, Du hast ja recht, aber dafür war ich erstens zu faul und zweitens sind meine x86-Kenntnisse nicht immer perfekt (wie ich in letzter Zeit häufiger feststellen musste als mir lieb ist) so das ich diesen Part dann einfach anderen überlassen wollte.
Aber Deine, äh, blumige Ausdrucksweise ist auch nicht unbedingt das Optimum. ;)
Grüße
Erik
-
Hallo Dirk,
erstmal danke für deine Aufmerksamkeit.
Aber was bedeuten:
dann könnte man diese wenigen Regeln doch gleich mit bekannt geben.
Und:
falls kein besonderer Liebhaber(Segment override prefix) sich ins gemachte Bett dazugesellt.
Gruß
Relbmessa
Beispielsweise wurde bei "mov word [es:0x0], isr00" das ES-Segmentregister mit angegeben. Der Assembler trägt dafür das entsprechende Segment override prefix vor dem Opcode ein. So wird anstelle des DS-Segments für die Adressierung das ES-Segment verwendet. Es gibt folgende Segment override prefixe; CS(0x2E), SS(0x36:), DS(0x3E), ES(0x26), FS(0x64) und GS(0x65). Bei der Verwendung von (E)SP und/oder (E)BP als Adressregister wird (ohne die Angabe eines Segment override prefix) standardmäßig das SS-Segment zur Adressierung zugeordnet. Bei allen anderen Adressen die gebildet werden (ohne Segment override prefix) wird standardmäßig das DS-Segment zur Adressierung zugeordnet. (Im 64 Bit Mode werden Segment override prefixe ignoriert.)
SS:EBP
SS:ESP
sonst DS:Adresse
...
Eine Ausnahme sind die String-Befehle: MOVSx, CMPSx, SCASx, LODSx, and STOSx (x= B, W, or D for byte, word, or double word)
Die Quelladresse bildet sich hierbei aus DS:SI und die Zieladresse bildet sich aus ES:DI.
Dirk
-
Hallo,
Im 64 Bit Mode werden Segment override prefixe ignoriert.
Ich würde wetten das stimmt nicht so ganz, selbst im Long-Mode gibt es doch noch FS und GS als letzten Rest vom Glanz längst vergangener Zeiten.
Das andere ist IMHO richtig, aber das hatten wir ja schon.
Grüße
Erik
-
Hallo,
Im 64 Bit Mode werden Segment override prefixe ignoriert.
Ich würde wetten das stimmt nicht so ganz, selbst im Long-Mode gibt es doch noch FS und GS als letzten Rest vom Glanz längst vergangener Zeiten.
Grüße
Erik
Uff stimmt, nur CS, DS, ES, SS werden als Segment override prefix im 64 Bit-Mode ignoriert.
Dirk
-
Sicher, dass sie komplett ignoriert werden? AMD doch wieder teilweise Limits für die Segmente eingeführt. Wobei ich die Details nicht auswendig kenne.
-
Hallo,
ich habe noch nicht ganz mit gekriegt, ob Ihr über das Programm oder über Grundlagen
philosophiert.
Hier ein Ausschnitt vom Long Mode Programm.
<asm>
;Version_03.03.1_alpha_50s
;-----------------------------------------------
;nasm -f bin -o nasmA64_ioa.bin nasmA64_ioa.asm
;-----------------------------------------------
;Super I/O ->Up (call super_io ; call super_io_exit
;Chip IT8716F (IT8712)
;-----------
;KBC->Register auslesen (später manipulieren)
;call super_io_LDN_05_lesen
;-----------------------------------------------
;Programm_06 TEST-1 USB BAR-OHCI_0 (BAR FE02E000h)
;FE02E004h HcControl Register 04-07 IR-> Bit-8 Interrupt Routing
;
;amd64_longmode_Interface_00
;Tastatur_eingabe abfragen (64-bit 8-bit-schritte) dezimal oder hex
;Tastatur eingabe abfrage ja ,nein , Enter
;Funktions_tasten F1-10
;F1->Programm_Funktionsauswahl PROGRAMM_01-10 Programme in Arbeit
;Auswahl PROGRAMM_XX mit Zahlen->hier von 01-10
;PROGRAMM_01 : Auswahl Floppy lesen oder schreiben
;PROGRAMM_02: Speicherinhalt auf BWS anzeigen
;Adresse Quelldaten Eingabe mit Tastatur (64-bit)
;POGRAMM_03: Speicherinhalt auf BWS anzeigen
;-Adresse Quelldaten Eingabe mit Tastatur (32-bit)
;-Abfrage ja nein enter
;F2-F6 frei
;F7->FDC-schreiben
;F8->FDC-lesen
;F9->FDC-reset
;FDC_polling/Parameter-Eingabe-> PROGRAMM_01 sector und Wiederholung Xmal
;oder indirekt mit Assembler
;F10->anzeige_auf_bws
ORG 08000h
[BITS 16] ;
mov ah, 0x02
mov bh, 0x0
mov dh, 24 ; Zeile BWS
mov dl, 79 ; Spalte BWS
int 10h ; Cursor-Position
cli ; keine maskierbaren interrupt
lgdt [cs:gdtr] ; lade GDT Register
mov eax,cr0 ; Aktivierung protected mode
or al,1
mov cr0,eax
in al,92h ; enable A20
or al,02h
out 92h,al
jmp CODE_SELECTOR:pm_start
gdtr: ; Desktiptortabelle
dw gdt_end-gdt-1 ; Limit
dq gdt ; Basisadresse;;;dd -->dq
gdt:
dd 0,0 ; Null-Deskriptor
DATA_SELECTOR equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x92 ; Zugriffsberechtigung und Typ
db 0x8F ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
CODE_SELECTOR equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x9A ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
LONG_SELECTOR equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x9A ; Zugriffsberechtigung und Typ
db 0xAF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
gdt_end:
[BITS 32]
pm_start:
mov eax,DATA_SELECTOR ; load 4 GB data descriptor
mov ds,ax ; to all data segment registers
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov eax,cr4
or eax,00000000000000000000000000100000b; byte +0x20 ; or eax,1 shl 5
; or eax, 10100000b
mov cr4,eax ; enable physical-address extensions
;--------------------------------------------------------------------------------
;--------------------------------------------------------------------------------
mov edi,010000h
mov ecx,0xF000 ;mov ecx,4000h shr 2
xor eax,eax
rep stosd ; clear the page tables
;--------------------------------------------------------------------------------
mov dword [010000h],011000h + 111b ; first PDP table
mov dword [010008h],011008h + 111b ; zweite
mov dword [010010h],011010h + 111b ; dritte
mov dword [010018h],011018h + 111b ; vierte
mov dword [011000h],012000h + 111b ; first page directory
mov dword [011008h],013000h + 111b ; zweite
mov dword [011010h],014000h + 111b ; dritte
mov dword [011018h],015000h + 111b ; vierte
;-------------------------------------------------------------------
mov edi,12000h ;page table
mov eax,1000000h +111b
mov ecx, 2048 ;190 ;1mal 2MB
page_table:
stosd
add edi,0x4
add eax,0x1000
loop page_table
mov edi,1000000h ; address of first page table
mov eax,0 + 111b
mov ecx, 512*2048 ;512*1=2MB ;256 ; number of pages to map (1 MB)
make_page_entries: ;Bemerkung: 512*4=2048-->800h
stosd
add edi,4
add eax,1000h
loop make_page_entries
;------------------------------------------------------------------------------
mov eax,10000h ;010FF7h ;siehe first PDP table hier 10000h
mov cr3,eax ; load page-map level-4 base
mov ecx,0C0000080h ; EFER MSR
rdmsr
or eax, 0x100 ;or eax,1 shl 8 ; enable long mode
wrmsr
mov eax,cr0
or eax,10000000000000000000000000000000b ;0x80000000 ;or eax,1 shl 31
mov cr0,eax ;enable paging
jmp LONG_SELECTOR:long_start
[BITS 64] ;
long_start:
mov rsp, 0x200000 ;0x20000 ;stack /hat gefehlt 0x60 INT8 Double Fault
;0x80 geht gerade so
xor edi,edi ; create IDT (at linear address 0)
mov ecx,32 ;21
make_exception_gates: ; make gates for exception handlers
mov esi,exception_gate
movsq
movsq
loop make_exception_gates
mov ecx,256-32 ;21
make_interrupt_gates: ; make gates for the other interrupts
mov esi,interrupt_gate
movsq
movsq
loop make_interrupt_gates
;------------------------------------------------------------------------------
lidt [IDTR] ; load IDT register
;---------------------------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;IDTR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IDTR: ; Interrupt Descriptor Table Register
dw 256*16-1 ; limit of IDT (size minus one)
dq 0 ; linear address of IDT
exception_gate:
dw 0x0 ; exception ; and 0FFFFh ;dw exception and 0FFFFh,LONG_SELECTOR
dw 0018h ;LONG_SELECTOR ;dw 8E00h,exception shr 16
dw 8E00h ;dd 0,0
dw 0x0 ;exception shr 16
dw 0x0 ; dd 0,0
dw 0x0
interrupt_gate:
dw 0x0 ; interrupt ; and 0FFFFh ;dw interrupt and 0FFFFh,LONG_SELECTOR
dw 0018h ;LONG_SELECTOR
dw 8F00h ;dw 8F00h,interrupt shr 16
dw 0x0 ;interrupt shr 16
dw 0x0 ; dd 0,0 ;dd 0,0
dw 0x0
;;;;;;;;;;;;;;;;;;;;;;;;;;IDTR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov word [0x00],softw_int0 ; exception divide
mov word [0x10],softw_int1 ; Software-Unterbrechung int 0x1
mov word [0x20],softw_int2 ; Software-Unterbrechung int 0x2
mov word [0x30],softw_int3 ; Software-Unterbrechung int 0x3
Hier weiter mit: mov word [0F6h*16],IRQ_22 ; set IRQ 22 handler
mov word [0F7h*16],IRQ_23 ; set IRQ 23 handler
;------------------------------------------------------------------
mov word [0xF80],softw_int80 ; Software-Unterbrechung int 0x80
mov word [0xF90],softw_int80 ; Software-Unterbrechung int 0x80
mov word [0xFA0],softw_int80 ; Software-Unterbrechung int 0x80
mov word [0xFB0],softw_int80 ; Software-Unterbrechung int 0x80
mov word [0xFC0],softw_int80 ; Software-Unterbrechung int 0x80
mov word [0xFD0],softw_int80 ; Software-Unterbrechung int 0x80
mov word [0xFE0],softw_int80 ; Software-Unterbrechung int 0x80
mov word [0xFF0],softw_int80 ; Software-Unterbrechung int 0x80
;------------------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;IDTR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IO_APIC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov r8, 0xFEC00000
;-------------------------
mov byte [r8],0x10 ;select data register
mov r8, 0xFEC00010
mov dword [r8],0x100E0 ;8 bit-16->1 maskiert! ;0x0090 ;Vector (7:0) 10h - FEh /90h-Clock
;----------------------------------------------------------------------------------
mov r8, 0xFEC00000
;-------------------------
mov byte [r8],0x12 ;select data register
mov r8, 0xFEC00010
mov dword [r8],0x00E1 ;Vector (7:0) 10h - FEh /91h-Keyboard IRQ1
;--------------------------------------------------------------------------------
mov r8, 0xFEC00000
<asm>
Gruß Relbmessa
-
Sicher, dass sie komplett ignoriert werden? AMD doch wieder teilweise Limits für die Segmente eingeführt. Wobei ich die Details nicht auswendig kenne.
[AMD64 ArchitectureV3.pdf] ....auf der Seite von AMD kann ich dieses PDF leider selber gar nicht mehr finden.
Im PDF findet man folgenden Inhalt:
1.2.1 Summary of Legacy Prefixes
In 64-bit mode, the CS, DS, ES, and SS segment override prefixes are ignored.
Edit: Nun habe ich es gefunden: http://support.amd.com/us/Processor_TechDocs/24594.pdf
Dirk
-
Hallo,
ich habe noch nicht ganz mit gekriegt, ob Ihr über das Programm oder über Grundlagen
philosophiert.
Bei den Segment override prefixe geht es u.A. um Grundlagen, aber auch um deinen vorherigen Code wo du Segment override prefixe verwendet hast,
obwohl CS = DS = ES war. Hierbei kann man auch die Segment override prefixe weglassen und dann wird DS benutzt, um die selben Adressen zu erreichen.
Segment override prefixe machen nur dann Sinn, wenn damit verschiedene Segmentadressen angesprochen werden können.
Dirk
-
Hier ein Ausschnitt vom Long Mode Programm.
Dein Code sieht besser aus, wenn du ihn in [code]-tags tust statt <asm>. Also [code] vor den Code, und [/code] dahinter. (Oder du klickst auf den Button, der so aussieht: (http://forum.lowlevel.eu/Themes/lowlevel/images/bbc/code.gif)
-
Hallo,
AMD doch wieder teilweise Limits für die Segmente eingeführt.
Was echt? Segmente haben wohl doch auch ihre Vorteile. ;)
Es wäre schön wenn dazu mal jemand etwas konkreteres schreiben könnte, wenigstens ein Stichwort zum Suchen, würde mich persönlich echt mal interessieren.
Oder du klickst auf den Button....
Aber dazu muss vorher der Code im Eingabefenster korrekt markiert sein.
Grüße
Erik
-
Volume 2, 4.2.12 (Data Limit Checks in 64-bit Mode):
In 64-bit mode, data reads and writes are not normally checked for segment-limit violations. When
EFER.LMSLE = 1, reads and writes in 64-bit mode at CPL > 0, using the DS, ES, FS, or SS segments,
have a segment-limit check applied.
This limit-check uses the 32-bit segment-limit to find the maximum allowable address in the top 4GB
of the 64-bit virtual (linear) address space.
-
Es wäre schön wenn dazu mal jemand etwas konkreteres schreiben könnte, wenigstens ein Stichwort zum Suchen, würde mich persönlich echt mal interessieren.
http://www.o3one.org/hwdocs/amd64bit/x86-64_overview.pdf
Special Treatment of FS and GS Segments. The FS and GS segment
registers are used by the Windows NT™ operating system to
locate the thread-environment-block (TEB) and processorcontrol-
region (PCR) data structures. The FS and GS segmentoverride
prefixes provide quick access to these data structures
in an otherwise unsegmented (flat address space) operating
system. To facilitate compatible access to these structures, the
FS and GS segment overrides can be used in 64-bit mode.
When FS and GS segment overrides are used in 64-bit mode,
their respective base addresses are used in the effectiveaddress
(EA) calculation. The complete EA calculation then
becomes (FS or GS).base + base + index + displacement.
In 64-bit mode, FS.base and GS.base are expanded to the full
virtual-address size supported by the implementation. The
resultant EA calculation is allowed to wrap across positive and
negative addresses.
In 64-bit mode, FS-segment and GS-segment overrides are not
checked for limit or attributes.
Normal segment loads (MOV to Sreg and POP Sreg) into FS and
GS only load a standard 32-bit base value into the hidden
portion of the segment descriptor register. The base address
bits above the standard 32 bits are cleared to 0. Because the
first implementation of the Hammer family of processors
supports 48 virtual-address bits, a segment-load instruction
loads the base value into the lower 32 address bits and clears
the high 16 bits to 0.
To load all address bits supported by a 64-bit implementation,
the FS.base and GS.base hidden descriptor register fields are
physically mapped to MSRs. Privileged software (CPL=0) can
load all supported virtual-address bits into FS.base or GS.base
using a single WRMSR instruction. The FS.base MSR index is
C000_0100h while the GS.base index is C000_0101h.
The addresses written into the expanded FS.base and GS.base
registers must be in canonical form. A WRMSR instruction that
attempts to write a non-canonical address to those registers
generates a general-protection exception, #GP.
When in compatibility mode, the FS and GS overrides operate
as defined by the legacy x86 architecture regardless of the
value loaded into the upper 32 virtual-address bits of the
hidden descriptor register base field. Compatibility mode
ignores the upper 32 bits when calculating an effective address.
Dirk
-
Hallo,
@ freecrac & taljeth :
Danke Euch beiden.
Das mit der Basis-Adresse von FS und GS war mir im wesentlichen bekannt aber das mit dem Limit-Check bei DS, ES, FS und SS (?ist da wirklich auch FS dabei?) war mir neu (darauf zielte auch meine Bitte von vorhin ab).
Grüße
Erik
-
Hallo Forum,
für die es interessiert, hier nun der ganze Quelltext:
http://pastebin.de/18098 (http://pastebin.de/18098)
Gruß
Relbmessa
PS
Erst mal 30 Tage
-
Zum Abfragen der Tastatur wäre es sinvoll vorher zu schauen ob dort überhaupt etwas im Ausgabebuffer vorhanden ist:
in al, 64h ; Tastatur-Status holen
test al, 1
jz NOKEY ; wenn keine Taste weiter
test al, 20h
jnz NOKEY ; wenn PS2-Mouse weiter
in al, 60h ; Tasten-Code holen
NOKEY:
-
Hallo,
ich arbeite nicht mit Polling sondern mit IRQ.
Maus wird nicht installiert.
Gruß
Relbmessa
-
Hallo,
ich arbeite nicht mit Polling sondern mit IRQ.
Ups, jetzt habe ich "isrK" gefunden.
Maus wird nicht installiert.
Gruß
Relbmessa
Ok.
Dirk
-
Hallo,
kleine Info für die Tester vom PM-Programm.
Es besteht ein kleiner Fehler , der mir erst jetzt aufgefallen ist.
Auf dem ASRockP4i65G Motherboard Intel 865 G Chipset läuft das Programm nur bedingt.
Der IRQ von der KBC wird inaktiv .
Im Moment keine Ahnung warum. Der Rest funktioniert aber wie vorgesehen.
Gruß
Relbmessa
PS
Ist in Arbeit
-
Hallo,
habe das Problem mit dem IRQ für das ASRock P4i65G Motherboard Intel 865 G und ICH5 Chipsatz gelöst.
Es muß die Locale APIC eingetragen werden.BIT 56-63
Zum Code muß wie im Beispiel Unten,die IO-APIC geladen werden.
Für alle IRQs natürlich auch alle Register wie im Beispiel.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IO_APIC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov eax, 0xFEC00000
;-------------------------
mov byte [eax],0x10 ;select data register
mov eax, 0xFEC00010
mov dword [eax],0x10020 ;8 bit-16->1 maskiert! ;0x0090 ;Vector (7:0) 10h - FEh /90h-Clock
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;BEACHTE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;----------------------------------------------------------------------------------
mov eax, 0xFEC00000
;-------------------------
mov byte [eax],0x12 ;select data register
mov eax, 0xFEC00010
mov dword [eax],0x0021 ;Vector (7:0) 10h - FEh /91h-Keyboard IRQ1
;--------------------------------------------------------------------------------
;;;;;;;;;BIT 56-63 gibt die empfangende Locale APIC an;;;;;;;;;;;;;;;;;;;;;;;;;;
mov eax, 0xFEC00000
;-------------------------
mov byte [eax],0x13 ;select data register
mov eax, 0xFEC00010
mov dword [eax],0x0100000 ;BIT 56-63 (7:0) 10h - FEh /91h-Keyboard IRQ1
;Hier Locale APIC 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Gruß
Relbmessa