Sourcecode Fortschritt
-
Rev. 108:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=108pci.c: Erkennen von Netzwerkkarte RTL 8139 eingebaut (thx to "tty")
Testen mit Qemu:
qemu-system-x86_64.exe -soundhw pcspk -usbdevice mouse -net nic,model=rtl8139,macaddr=00:12:12:12:12:12 -fda FloppyImage.bin -boot a -localtime
Wer den IRQ-Handler testen will, gibt nach dem PCI-Scan folgenden Code ein (qemu wählt bei mir IRQ 11):
///TEST printformat("Test with IRQ 32+11: "); settextcolor(14,0); __asm__ volatile( "int $43" : : "a"(0) ); settextcolor(15,0); ///TEST
Leider ist es bisher nicht gelungen, den IRQ durch "anpingen" über das Netz auszulösen.
Siehe auch Links bei:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-251851.html (unten)EDIT: Sun Virtual Box, MS Virtual PC laufen
-
Rev. 109:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=109Den von tty erstellten Code auf die Vorgaben von http://lowlevel.brainsware.org/wiki/index.php/RTL8139 erweitert/angepasst:
1. Vom PCI-Treiber den IRQ und die I/O-Ports holen
2. IRQ-Handler und ggf. I/O-Ports registrieren
3. Einen Reset der Karte durchführen: Bit 4 im Befehlsregister (0x37, 1 Byte) setzen. Wenn ich hier Portnummern von Registern angebe, ist damit der Offset zum ersten Port der Karte gemeint, der durch die PCI-Funktionen ermittelt werden muss.
4. Aktivieren des Transmitters und des Receivers: Setze Bits 2 und 3 (TE bzw. RE) im Befehlsregister (0x37, 1 Byte). Dies darf angeblich nicht erst später geschehen, da die folgenden Befehle ansonsten ignoriert würden.
5. TCR (Transmit Configuration Register, 0x40, 4 Bytes) und RCR (Receive Configuration Register, 0x44, 4 Bytes) setzen. An dieser Stelle nicht weiter kommentierter Vorschlag: TCR = 0x03000700, RCR = 0x0000070a
6. Puffer für den Empfang (evtl auch zum Senden, das kann aber auch später passieren) initialisieren. Wir brauchen für bei den vorgeschlagenen Werten 8K + 16 Bytes für den Empfangspuffer und einen ausreichend großen Sendepuffer. Was ausreichend bedeutet, ist dabei davon abhängig, welche Menge wir auf einmal absenden wollen. Anschließend muss die physische (!) Adresse des Empfangspuffers nach RBSTART (0x30, 4 Bytes) geschrieben werden.
7. Interruptmaske setzen (0x3C, 2 Bytes). In diesem Register können die Ereignisse ausgewählt werden, die einen IRQ auslösen sollen. Wir nehmen der Einfachkeit halber alle und setzen 0xffff.umgesetzt in pci.c
IRQ konnte aber bisher nicht über Netzwerk ausgelöst werden.
Bisheriger Versuch: Mac-Adresse ermittelt von der Netzwerkkarte mit RTL 8139, statisch in den Router (LAN, DHCP) eingetragen und IP 192.168.10.97 vergeben, dann ein "ping". Kein Erfolg, weder durch IRQ in PrettyOS noch durch erfolgreiche Rückmeldung des Pings ("Zeitüberschreitung der Anforderung", alle Pakete verloren). arp -a zeigt die IP ebenfalls nicht.
Was fehlt hier noch für diesen ersten Schritt des Auslösens des Interrupts via Netzwerk?
http://prettyos.svn.sourceforge.net/viewvc/prettyos/trunk/Source/kernel/pci.c?view=markup&pathrev=109EDIT: Sun Virtual Box, MS Virtual PC laufen
-
Rev. 110:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=110Überarbeiteter Zwischenschritt:
- bleibt in qemu hängen (keine Zurücksetzung des Reset-Bit)
- mac address wird nicht korrekt ausgegeben ?wie kommt man korrekt an folgende Strukturen:
http://www.digitale-elektronik.de/shopsystem/rtl8139d-datasheet.pdf (S.14/15)http://svn.rot13.org/index.cgi/pearpc/view/src/io/rtl8139/rtl8139.cc?rev=1
/* registers */ struct Registers { uint8 id0; // 0x00 (mac address) uint8 id1; uint8 id2; uint8 id3; uint8 id4; uint8 id5; uint16 rsvd0; // 0x06-0x07 uint8 mar0; uint8 mar1; uint8 mar2; uint8 mar3; uint8 mar4; uint8 mar5; uint8 mar6; uint8 mar7; uint32 TxStatusD0; // 0x10 uint32 TxStatusD1; // 0x14 uint32 TxStatusD2; // 0x18 uint32 TxStatusD3; // 0x1c uint32 TxStartAddrD0; // 0x20 uint32 TxStartAddrD1; // 0x24 uint32 TxStartAddrD2; // 0x28 uint32 TxStartAddrD3; // 0x2c uint32 RxBufferStartAddr; // 0x30 uint16 EarlyRxByteCount; // 0x34 uint8 EarlyRxStatus; // 0x36 uint8 CommandRegister; // 0x37 uint16 CAPR; // 0x38 initial 0xfff0 uint16 CBA; // 0x3a initial 0x0000 uint16 InterruptMask; // 0x3c uint16 InterruptStatus; // 0x3e uint32 TxConfiguration; // 0x40 uint32 RxConfiguration; // 0x44 uint32 TimerCount; // 0x48 uint32 MissedPacketCounter; // 0x4c uint8 Command93C46; //0x50 uint8 Config0; // 0x51 uint8 Config1; // 0x52 uint8 rsvd1 ; // 0x53 uint32 TimerInterrupt; // 0x54 uint8 MediaStatus; // 0x58 uint8 Config3; // 0x59 uint8 Config4; // 0x5a uint8 rsvd2; // 0x5b uint16 MultipleInterruptSelect; // 0x5c uint8 PCIRevisionID; // 0x5e should be 0x10 uint8 rsvd3; // 0x5f uint16 TSAD; // 0x60 Transmit Status of All Descriptors uint16 BMCR; // 0x62 Basic Mode Control uint16 BMSR; // 0x64 Basic Mode Status uint16 ANAR; // 0x66 Auto-Negotiation Advertisement uint16 ANLPAR; // 0x68 "" Link Partner uint16 ANER; // 0x6a "" Expansion uint16 DisconnectCounter; // 0x6c uint16 FalseCarrierSenseCounter; // 0x6e uint16 NWayTest; // 0x70 uint16 RX_ER_Counter; //0x72 uint16 CSConfiguration; // 0x74 uint16 rsvd4; uint32 PHY1; //0x78 uint32 Twister; // 0x7c uint8 PHY2; // 0x80 } PACKED;
EDIT: Sun Virtual Box, MS Virtual PC laufen
-
Rev. 111:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=111IRQ kann jetzt über Netz ausgelöst werden!
BAR[1].baseAddress ist die richtige! (MMIO anstelle I/O)
Ich habe folgendes gemacht:
- im Router bei DHCP die mac-Adresse fest an eine IP gekoppelt (statisch)
- PING geschickt, "RTL8139 IRQ" kommtTODO: hängt komplett da fest (da fehlt: 16 bit von 003Eh bis 003Fh lesen und genauso wieder zurück schreiben. "writing a 1 to any bit will reset that bit")
TODO: Basis-Adresse noch mit & 0xFFFC bearbeitet werden (analog USB-Treiber)
TODO: Ping wird nicht sauber bearbeitet, löst nur IRQ ausAber immerhin, Netzwerkkarte wurde erkannt und angesprochen. (thx to tty and homix)
Warum geht das mit qemu nicht?
Beim real PC gibt es jetzt ständig IRQ-Alarm
http://www.digitale-elektronik.de/shopsystem/rtl8139d-datasheet.pdf (S. 19 von 67)?EDIT: Sun Virtual Box, MS Virtual PC laufen
-
Rev. 112:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=112Einige Verbesserungen in pci.c
Der IRQ muss im Handler noch zurück gesetzt werden. Dazu brauchen wir aber eine Funktion: phys. Addr. ---> virt. Addr. (gilt auch für USB)
Wir verwenden momentan die MMIO-Adresse der RTL8139 Netzwerkkarte. Mit der IO-Adresse klappt es nicht (warum? sollte gehen!).
EDIT: Sun Virtual Box, MS Virtual PC laufen
-
Rev. 113:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=113Netzwerk IRQ bei RTL8139 funktioniert, der Install-Handler wurde aber wieder deaktiviert, weil wir momentan den Interrupt nicht wieder abstellen können (Paging-Problem). Erst, wenn das Design stimmt, wird daran weiter entwickelt.
EDIT: Sun Virtual Box, MS Virtual PC laufen
-
Rev. 114:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=114Netzwerk IRQ bei RTL8139 funktioniert, der Install-Handler wurde wieder aktiviert, nachdem wir den Interrupt abstellen können, geht über out(...,data) also über den IO anstelle MMIO. Wir fahren momentan zweigleisig.
User-Lib: auf Wunsch von tty wurde strchr(...) hinzu gefügt (bitte testen)
EDIT: Sun Virtual Box, MS Virtual PC laufen
-
Erhard Henkes schrieb:
wie kommt man korrekt an folgende Strukturen:
http://www.digitale-elektronik.de/shopsystem/rtl8139d-datasheet.pdf (S.14/15)http://svn.rot13.org/index.cgi/pearpc/view/src/io/rtl8139/rtl8139.cc?rev=1
[cpp]/* registers */
struct Registers {
uint8 id0; // 0x00 (mac address)
...
uint8 PHY2; // 0x80
} PACKED;Wieso haust Du die Register des Ethernernet-Controllers in eine Struktur? Das ist doch Blödsinn. Mach Dir Makros dafür
-
Baba Yaga schrieb:
Wieso haust Du die Register des Ethernernet-Controllers in eine Struktur? Das ist doch Blödsinn. Mach Dir Makros dafür
Für MMIO ist das kein Blödsinn, für I/O-Space dann schon eher. Aber bis jetzt wird MMIO ja noch fleißig benutzt.
-
Rev. 115:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=115Weitere Verbesserungen in pci.c bezüglich RTL8139.
Die gelesenen Inhalte (receiving buffer) werden angezeigt (Länge der Eingangsdaten (Bit 2 u.3), auf max. 300 Byte begrenzt).Realer PC, Bochs, Qemu laufen.
MS VPC und Sun VB brechen nach dem Start der Shell ab.Analyse der Daten im Receiving Buffer:
"Bytes 0-1: Paketheader (Bit 0 = ROK)"
"Bytes 2-3: Länge des Pakets"
Dann geht es mit der MAC-Adresse des Empfängers weiter (Präambel, SFD ignorieren):
http://lowlevel.brainsware.org/wiki/index.php/RTL8139#Empfangen
http://lowlevel.brainsware.org/wiki/index.php/EthernetScreenshot:
http://www.henkessoft.de/OS_Dev/Bilder/rev115.pngEDIT: 22.feb. Sun VB und MS VPC laufen mit dem FloppyImage (SVN)
-
Wieso haust Du die Register des Ethernernet-Controllers in eine Struktur?
Habe ich nicht gemacht, wollte das nur beispielhaft zeigen.
-
Rev. 116:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=116Analyse des Receiving Buffer Contents
EDIT: Version läuft mit Sun VB und MS VPC.
-
Rev. 117:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=117Übersichtlichere Analyse/Darstellung des Receiving Buffers
EDIT: Version läuft mit Sun VB und MS VPC.
-
Rev. 118:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=118- in/out-Funktionen optimiert (util.c)
- neues TicTacToe
- einige Strukturen auf packed umgestelltEDIT: Version läuft mit Sun VB und MS VPC.
-
Rev. 119:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=119- Funktion eingebaut um Speicher bei 0xF...... zu ID-mappen:
bool paging_do_idmapping( uint32_t phys_addr )
- Einige kleinere syntaktische Sachen, weil's sonst (bei mir) nicht kompiliert hat.
-
Rev. 120:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=120- Funktion "testch", um zu checken ob eine Taste gedrückt wurde und abholbereit ist
- Zug fährt jetzt unabhängig von TastatureingabenEDIT: nein, macht er nicht
-
Rev. 121:
http://prettyos.svn.sourceforge.net/viewvc/prettyos?view=rev&revision=121Einige Korrekturen:
- in kernel.ld stand noch shared.o
- user/user_test_c/userlib..h/c und user/user_program_c/... waren verschieden (muss leider immer von Hand von user_program nach user_test kopiert werden.
- hello.c ist nun TTT 0.3EDIT: Version läuft mit Sun VB und MS VPC.
-
Problem: stellt man in ckernel.c pciScan nach Installation von Paging und versucht in pci.c
paging_do_idmapping( BaseAddressRTL8139_MMIO );
dann erhält man einen #PF.
Debugging ergibt folgendes:
bool paging_do_idmapping( uint32_t phys_addr ) { // TODO: Ensure that the physical memory is not used otherwise // TODO: The page table entry may point to a different address // TODO: Create solution for addreses != 0xF... // Adress must be a 0xF...-address if ( (phys_addr & 0xF0000000) != 0xF0000000 ) return false; printformat("\tDEBUG: phys addr OK\n"); const uint32_t pagenr = phys_addr/PAGESIZE; const uint32_t aligned = phys_addr & ~4095; // Setup the page page_table_t* pt = kernel_pd->tables[pagenr/1024]; printformat("DEBUG: behind page_table_t* pt = kernel_pd->tables[pagenr/1024];\n"); ASSERT( pt ); printformat("DEBUG: behind ASSERT. pt = %X\n", &pt); printformat("DEBUG: pt->pages[pagenr%1024] = %X\n", &(pt->pages[pagenr%1024])); pt->pages[pagenr%1024] = aligned | MEM_PRESENT | MEM_WRITE | MEM_KERNEL; //<--- #PF entsteht hier printformat("DEBUG: behind pt->pages[pagenr%1024] = aligned | MEM_PRESENT | MEM_WRITE | MEM_KERNEL;\n"); // Reserve the physical memory phys_set_bits( aligned, aligned+PAGESIZE, true ); printformat("DEBUG: behind phys_set_bits( aligned, aligned+PAGESIZE, true );\n"); return true; }
Problematische Zeile: pt->pages[pagenr%1024] = aligned | MEM_PRESENT | MEM_WRITE | MEM_KERNEL;
Screenshot: http://www.henkessoft.de/OS_Dev/Bilder/rev121a_PF.JPG
-
Das ist wirklich merkwürdig, die Pages für 3 GB bis 4 GB sind alle von vornherein gemappt; hier dürfte es eigentlich keinen Page Fault geben (siehe Funktion paging_install).
-
Also, die Page Table Einträge sind nicht auf physische Adressen gemappt, die Page Tables an sich haben aber ihren Platz. 0xC9028004 erscheint mir aber auch ein wenig hoch.