Lowlevel

Lowlevel => Softwareentwicklung => Thema gestartet von: lolxdfly am 16. September 2013, 17:45

Titel: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 16. September 2013, 17:45
Hi,
danke erstmal an alle, die mir bis jetzt schon geholfen haben.
Da sich bei mir viele Fragen bezüglich des C++-Kernel anhäufen habe ich mal eine AllInOne-Question erstellt  :-D
Den Code hab ich aber größtenteils verstanden! Im momment ist der Kernel noch fast unverändert. Ich habe nur die stdint.h anstatt die types.h verwendent. Außerdem habe ich die newline-Escape-Sequenz(#n) hinzugefügt.
Ich habe ich 5 Fragen mit absteigender Priorität:

Frage 0: Gibt es irgendwo eine TuT-Reihe, wo ein C++-Kernel fortgesetzt und erklärt wird? Inaktiv

Frage 1: Wie kann man die Tastatur im Kernel nutzen? Gibt es vorgefertigte libs, die ich dafür verwenden kann?? Ich habe nur 1 TuT gefunden. Das war allerdings nur schwer zu verstehen... Gelöst!

Frage 2: Wie kann man Bilder anzeigen lassen/ einzelne Pixel färben? Ich habe es mit der Pixeltoaster-lib(systemunabhängig) versucht. Hat aber nur errors ausgespuckt. Inaktiv

Frage 3: Wie ist der QEMU-log zu verstehen? (http://pastebin.com/4vUfBPpr (http://pastebin.com/4vUfBPpr)) Gelöst!

Frage 4: Wie kann man die Maus im Kernel nutzen? Ist nur nötig, wenn Frage 1+2 schon beantwortet wurden und funktionieren! Inaktiv
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: streetrunner am 16. September 2013, 19:35
Zu Frage 0: Wenn Tante Google da nichts findet, dürfte die Wahrscheinlichkeit eher gering sein. Außerdem hat es schon seine Gründe, warum man einen Kernel in C ohne die beiden + schreibt. Aber letztenendlich dürfte es kein Problem darstellen einen C-Kernel in C++ nachzuprogrammieren, der Code könnte sogar fast der selbe sein (es zwingt dich ja keiner dazu Klassen zu verwenden). Das einzige Problem das ich immo sehe ist dass der Inline-Assembler wegfällt, womit du diesen Code als Funktionen in eine eigene Datei stecken musst.

Zu Frage 1: Hier http://www.lowlevel.eu/wiki/Teil_5_-_Interrupts (http://www.lowlevel.eu/wiki/Teil_5_-_Interrupts) findest du Interrupts, und hier http://www.lowlevel.eu/wiki/Keyboard_Controller (http://www.lowlevel.eu/wiki/Keyboard_Controller) wie du den Tastatur-Controller benutzt. Wenn du dann noch die Foren-Suche benutzt solltest du alles beisammen haben um die Tastatur ans laufen zu bekommen.

Zu Frage 2: Um Pixel anzuzeigen kannst du dich entweder mit VESA rumärgern, welches nur so lala funktioniert aber einen riesen Aufwand bedeutet, oder einen Grafiktreiber schreiben, was noch wesentlich mehr Aufwand bedeutet.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 16. September 2013, 19:47
Frage 3: Wie ist der QEMU-log zu verstehen? (http://pastebin.com/4vUfBPpr (http://pastebin.com/4vUfBPpr))

In dem speziellen Log steht nichts interessantes. Es sind darin zwei Registerdumps (SMM: enter und SMM: after RSM) aufgezeichnet, die QEMU immer beim Systemstart ausgibt. Da du anscheinend Interrupts noch deaktiviert hast, stehen darin keine weiteren Registerdumps. Das ändert sich später, wenn du IRQs aktivierst, die INT-Instruktion ausführst oder Exceptions aufgrund von Fehlern ausgelöst werden. Für die Fehlersuche könntest du dann daraus weitere Informationen gewinnen.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 16. September 2013, 19:55
Zu Frage 2: Um Pixel anzuzeigen kannst du dich entweder mit VESA rumärgern, welches nur so lala funktioniert aber einen riesen Aufwand bedeutet, oder einen Grafiktreiber schreiben, was noch wesentlich mehr Aufwand bedeutet.

Hab das hier gefunden:
//Pointer auf den Speicher
unsigned char* VGA = (unsigned char*) 0xA0000;

void setpixel(int x, int y, unsigned char color) {
  int offset;
  if(0 <= x && x < 320) {
    if(0 <= y && y < 200) {
      offset = 320*y + x;
      VGA[offset] = color;
    }
  }
}
Wäre auch zu schön gewesen hätte es funktioniert  :-)
Liegt es daran, dass ich in text mode und in 13h mode was machen wollte?


Zu Frage 0: Wenn Tante Google da nichts findet, dürfte die Wahrscheinlichkeit eher gering sein. Außerdem hat es schon seine Gründe, warum man einen Kernel in C ohne die beiden + schreibt. Aber letztenendlich dürfte es kein Problem darstellen einen C-Kernel in C++ nachzuprogrammieren, der Code könnte sogar fast der selbe sein (es zwingt dich ja keiner dazu Klassen zu verwenden). Das einzige Problem das ich immo sehe ist dass der Inline-Assembler wegfällt, womit du diesen Code als Funktionen in eine eigene Datei stecken musst.

Soll ich auf C umsteigen? Bis jetzt hatte ich mit C nur Probleme. Außerdem lernen wir in der Schule grade c++. Wobei wir da erstmal lernen was cin und cout ist -.-
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: TheThing am 16. September 2013, 20:47
Wäre auch zu schön gewesen hätte es funktioniert  :-)
Liegt es daran, dass ich in text mode und in 13h mode was machen wollte?
Das liegt daran, dass du Copy-Paste-gesündigt hast ;) Stell dir mal folgende Frage: Wieso hätte es funktionieren sollen? Du befindest dich im Textmodus und versuchst Pixel zu setzen.

Für Grafik gibt es eigentlich drei Möglichkeiten:
1. VGA: Nur geringe Auflösungen und wenige Farben, dafür aber (meines Wissens nach) problemlos aus dem Protected-Mode verwendbar da VGA-Hardware per I/O Ports angesteuert wird.
2. VBE (VESA Bios Extensions): Höhere Auflösungen und mehr Farben, unterstützt aber nicht immer alle möglichen Auflösungen (z.B. ist auf meinem Notebook die native Auflösung des Bildschirms nicht per VBE setzbar). Schwieriger zu benutzen, da die Verwendung im Real Mode vorgesehen war. Es gab zwar später ein Protected-Mode Interface, aber nach allem was ich bisher gehört habe war das auch nur halbgarer Käse.
3. Eigener Treiber: Extrem hoher Aufwand, dafür kann ein eigener Treiber dann alles unterstützen was die Hardware bietet. Aus Mangel an Dokumentation und Beispielcode extrem schwierig, und selbst große Projekte wie nouveau, die schon seit Jahren existieren und zu denen hunderte Menschen beigetragen haben, können die Hardware nicht komplett ausreizen.
Wobei, eine eingeschränkte vierte Möglichkeit gibts auch noch:
4. Emulator-Treiber: Fällt zwar eigentlich unter Nr.3, aber Treiber für emulierte Hardware sind deutlich einfacher zu schreiben. Vor einiger Zeit hab ich mal ein paar Minuten investiert und mir den BGA (Bochs Graphics Adaptor) angesehen, innerhalb von Minuten hatte ich bunte Pixel auf dem Bildschirm. Eine echt einfache Sache, aber dafür läufts halt nicht auf echter Hardware.

Aber an dieser Stelle noch einen Rat: Nicht zu früh an Grafik denken. Die buntesten Pixel bringen nichts wenn das OS dahinter nichts kann ;)

Soll ich auf C umsteigen? Bis jetzt hatte ich mit C nur Probleme. Außerdem lernen wir in der Schule grade c++. Wobei wir da erstmal lernen was cin und cout ist -.-
Diese Frage solltest du niemals einer anderen Person stellen, höchstens dir selbst. Benutz einfach die Sprache die dir am angenehmsten ist bzw. die deinen gesteckten Zielen dienlich ist. Wenn du bereits in C++ angefangen hast, warum solltest du in C neu anfangen? Auch mit C++ ist OS-dev möglich.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 16. September 2013, 21:09
Wäre auch zu schön gewesen hätte es funktioniert  :-)
Liegt es daran, dass ich in text mode und in 13h mode was machen wollte?
Das liegt daran, dass du Copy-Paste-gesündigt hast ;) Stell dir mal folgende Frage: Wieso hätte es funktionieren sollen? Du befindest dich im Textmodus und versuchst Pixel zu setzen.

Nunja ich befinde mich ja nicht nur im Textmodus. Ich hab einmal den Textmodus zum Text-anzeigenlassen. Und einmal den 13h(VGA)-Modus indem ich versucht habe Pixel zu setzen. Ich dachte es wäre so wie in XNA(C#). Dort kann man einfach die Ebenden überschreiben.(Text und 3d-View) :-D Wie kann ich denn beides machen? Wenn ich nur 13h-Modus nehme kann ich ja kein Text mehr darstellen...
So so sieht meine Video.cpp aus:
#include "Video.h"

Video screen;

Video::Video()
  : m_videomem((uint16_t*) 0xB8000 ), m_off(0), m_pos(0), m_color(0x0700)
{
  //Bildschirm leeren
  clear();
}
 
 //Pointer auf den Speicher
unsigned char* VGA = (unsigned char*) 0xA0000;

void setpixel(int x, int y, unsigned char color) {
  int offset;
  if(0 <= x && x < 320) {
    if(0 <= y && y < 200) {
      offset = 320*y + x;
      VGA[offset] = color;
    }
  }
}
 
Video::~Video(){
}
 
void Video::clear(){
  // Füllen des Bildschirms mit Leerzeichen
  for(int i = 0;i < (80*25);i++)
    m_videomem[i] = (unsigned char)' ' | m_color;
 
  // Zurücksetzen der Textausgabe nach links oben
  m_pos = 0;
  m_off = 0;

  setpixel(10, 10, '4');
}
 
Video& Video::operator << (const char* s){
  // Für jedes einzelne Zeichen wird put() aufgerufen
  bool checkfores = false, draw = true;
  char es = '0';
  while (*s != '\0')
  {
draw = true;
    if(checkfores == true)
{
  es = *s;
}
if(es == 'n' && checkfores == true)
{
  m_off+=80; //newline
  m_pos=0;
  checkfores = false;
  draw = false;
}
    if(*s == '#')
    {
  checkfores = true;
    }
else if (*s != '#' && draw == true)
{
  put(*s);
}
*s++;
  }
  return *this;
}
 
Video& Video::operator << (color::type color){
  m_color = (static_cast<uint16_t>(color) << 8) | (m_color & 0xF000);
  return *this;
}
 
Video& Video::operator << (const background& color){
  m_color = (static_cast<uint16_t>(color.m_color) << 12) | (m_color & 0x0F00);
  return *this;
}
 
void Video::put(char c){
  // Wenn die Textausgabe den rechten...
  if(m_pos >= 80){ //Zeile voll
    m_pos = 0;
    m_off += 80;
  }
 
  // ...oder den unteren Bildschirmrand erreicht, gibt es
  // einen Umbruch bzw. es wird aufgeräumt.
  if(m_off >= (80*25)) //Bildschirm voll
    clear();
 
  // Setzen des Zeichens und der Farbe in den Videospeicher
  m_videomem[m_off + m_pos] = (uint16_t)c | m_color;
  m_pos++;
}
Die Video.h kannst du aus http://www.lowlevel.eu/w/index.php?title=C%2B%2B-Kernel_mit_GRUB&oldid=11074#Kernel (http://www.lowlevel.eu/w/index.php?title=C%2B%2B-Kernel_mit_GRUB&oldid=11074#Kernel) nehmen.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 16. September 2013, 21:27
Nunja ich befinde mich ja nicht nur im Textmodus. Ich hab einmal den Textmodus zum Text-anzeigenlassen. Und einmal den 13h(VGA)-Modus indem ich versucht habe Pixel zu setzen. Ich dachte es wäre so wie in XNA(C#). Dort kann man einfach die Ebenden überschreiben.(Text und 3d-View) :-D

So ist es aber nicht. Entweder Textmodus oder Grafikmodus. Wenn du Text im Grafikmodus darstellen willst, musst du die Zeichen Pixel für Pixel malen. Pixelgrafik im Textmodus ist nicht möglich. Du musst also zunächst in den Grafikmodus schalten, wenn du das haben willst.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 16. September 2013, 21:51
So ist es aber nicht. Entweder Textmodus oder Grafikmodus. Wenn du Text im Grafikmodus darstellen willst, musst du die Zeichen Pixel für Pixel malen. Pixelgrafik im Textmodus ist nicht möglich. Du musst also zunächst in den Grafikmodus schalten, wenn du das haben willst.

Das heißt, dass wenn ich auch nur einen Mauszeiger machen will, muss jeden einzelnen Buchstaben mit jedem einelnem Pixel setzen  :-o
Ich glaube fange dann doch erst mit der Tastatur an  :|
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Svenska am 16. September 2013, 23:00
Hallo,

Frage 0: Gibt es irgendwo eine TuT-Reihe, wo ein C++-Kernel fortgesetzt und erklärt wird?
Eher nicht. Tutorials bringen etwas bis zu dem Punkt, wo das Zusammenspiel aus Compiler, Linker, Umgebung und Emulator soweit läuft, dass der Startup-Code zuverlässig funktioniert plus ein kleines bisschen mehr (Textausgabe, Interrupts, Tastatur) zur Demonstration. Alles, was darüber hinaus geht, kann dir von einem Tutorial nicht abgenommen werden, weil es sehr stark vom Kernel selbst abhängt.

Frage 1: Wie kann man die Tastatur im Kernel nutzen? Gibt es vorgefertigte libs, die ich dafür verwenden kann?? Ich habe nur 1 TuT gefunden. Das war allerdings nur schwer zu verstehen...
Ab diesem Punkt bist du selbst auf dich gestellt. Was du dann in großen Mengen benutzen möchtest, sind die originalen Datenblätter oder aufbereitete Hardwarebeschreibungen (siehe hier im Wiki). Du musst lernen, aus dem "aha, so funktioniert die Tastatur" den passenden Code zu erzeugen, um sie passend anzusteuern (Treiber) und sie den Anwendungen zur Verfügung zu stellen.

Frage 2: Wie kann man Bilder anzeigen lassen/ einzelne Pixel färben?
Dazu brauchst du einen Grafiktreiber. Allerdings, wie schon geschrieben, verlierst du damit den Textmodus: Alles oder nichts. (Wobei es nicht besonders schwer ist, eine Textausgabe in einem Grafikmodus herzustellen. Es ist nur deutlich langsamer.)

Frage 4: Wie kann man die Maus im Kernel nutzen? Ist nur nötig, wenn Frage 1+2 schon beantwortet wurden und funktionieren!
Ähnlich wie die Tastatur, zumindest gilt das bei PS/2-Tastaturen und PS/2-Mäusen. Serielle und USB-Mäuse funktionieren wieder anders.

Gruß,
Svenska
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 17. September 2013, 16:37
Hallo,
ich habe den Kernel abgeändert, sodass er VGA nutzt und eigentlich ein Pixel der Position x=10 und y=10 blau färben müsste. Nun tut er dies leider nicht. Es kommt einfach ein schwarzer Bildschirm, wo nur steht, dass das BIOS geladen wurde. Der QEMU-log ist genauso wie vorher! Das Compilen ging fehlerfrei. Es gabe lediglich 3 warnungen auf unbenutze Werte. Das ist aber normal. Ich hoffe ihr könnt mir noch einmal helfen. Solbalt ich ein pixel erfolgreich gefärbt habe komme ich vorerst alleine weiter. Hier mein Code:

asmKernel.asm:
global loader ; Unser Einsprungspunkt
extern kernelMain ; kernelMain() aus Kernel.cpp
extern initialiseConstructors ; aus Startup.cpp
 
FLAGS    equ 0
MAGIC    equ 0x1BADB002 ; Magicnumber - Erkennungsmerkmal für GRUB
CHECKSUM equ -(MAGIC + FLAGS) ; Checksum
 
section .text
align 4
MultiBootHeader:
  dd MAGIC        ; Magic number
  dd FLAGS        ; Flags
  dd CHECKSUM    ; Checksum
 
loader:
  mov esp,0x200000 ; Stack an die 2MB-Grenze platzieren
  push eax          ; Multiboot-Magicnumber auf den Stack legen
  push ebx          ; Adresse der Multiboot-Structure auf den Stack legen
  call initialiseConstructors    ; Konstruktoren aufrufen
  call kernelMain      ; kernelMain aufrufen
 
stop:
  jmp stop

Kernel.cpp:
// Einbinden unseres Header
#include "Video.h"
#include "Multiboot.h"
#include "stdio.h"
 
extern "C" void kernelMain(const Multiboot& multiboot_structur,
                           uint32_t multiboot_magic);
 
void kernelMain(const Multiboot& multiboot_structur,
                uint32_t multiboot_magic)
{
  if (multiboot_magic != MULTIBOOT_MAGIC)
  {
    // Fehler!
//screen << background(color::light_gray) << color::blue << "Loading BOS(S)-Kernel...";
    return;
  }

}

link.txt:
ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386:i386)

SECTIONS
{
  . = 0x0100000;

  .text :
  {
    *(.text*)
    *(.rodata)
  }

  .data  :
  {
    start_ctors = .;
    *(.ctors)
    end_ctors = .;

    *(.data)
  }

  .bss  :
  {
    *(.bss)
  }

  /DISCARD/ : { *(.dtors) *(.comment) }
}

Multiboot.h:
#ifndef MULTIBOOT_H
#define MULTIBOOT_H
 
#include "stdint.h"
 
#define MULTIBOOT_MAGIC 0x2BADB002
 
struct Multiboot
{
  uint32_t flags;
  uint32_t mem_lower;
  uint32_t mem_upper;
  uint32_t bootdevce;
  uint32_t cmdline;
  uint32_t module_count;
  uint32_t module_address;
  /* etc... */
} PACKED;
 
#endif

Startup.cpp:
typedef void (*constructor)();
 
// Im Linkerskript definiert
extern "C" constructor start_ctors;
extern "C" constructor end_ctors;
 
extern "C" void initialiseConstructors();
 
// Ruft die Konstruktoren für globale/statische Objekte auf
void initialiseConstructors()
{
  for (constructor* i = &start_ctors;i != &end_ctors;++i)
    (*i)();
}

stdint.h:
/* ISO C9x  7.18  Integer types <stdint.h>
 * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794)
 *
 *  THIS SOFTWARE IS NOT COPYRIGHTED
 *
 *  Contributor: Danny Smith <danny_r_smith_2001@yahoo.co.nz>
 *
 *  This source code is offered for use in the public domain. You may
 *  use, modify or distribute it freely.
 *
 *  This code is distributed in the hope that it will be useful but
 *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
 *  DISCLAIMED. This includes but is not limited to warranties of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 *  Date: 2000-12-02
 */


#ifndef _STDINT_H
#define _STDINT_H
#define __need_wint_t
#define __need_wchar_t
#include <stddef.h>

/* 7.18.1.1  Exact-width integer types */
typedef signed char int8_t;
typedef unsigned char   uint8_t;
typedef short  int16_t;
typedef unsigned short  uint16_t;
typedef int  int32_t;
typedef unsigned   uint32_t;

/* 7.18.1.2  Minimum-width integer types */
typedef signed char int_least8_t;
typedef unsigned char   uint_least8_t;
typedef short  int_least16_t;
typedef unsigned short  uint_least16_t;
typedef int  int_least32_t;
typedef unsigned   uint_least32_t;

/*  7.18.1.3  Fastest minimum-width integer types
 *  Not actually guaranteed to be fastest for all purposes
 *  Here we use the exact-width types for 8 and 16-bit ints.
 */
typedef signed char int_fast8_t;
typedef unsigned char uint_fast8_t;
typedef short  int_fast16_t;
typedef unsigned short  uint_fast16_t;
typedef int  int_fast32_t;
typedef unsigned  int  uint_fast32_t;

/* 7.18.1.4  Integer types capable of holding object pointers */

#ifndef _INTPTR_T_DEFINED
#define _INTPTR_T_DEFINED
#ifdef _WIN64
  typedef __int64 intptr_t;
#else
  typedef int intptr_t;
#endif
#endif

#ifndef _UINTPTR_T_DEFINED
#define _UINTPTR_T_DEFINED
#ifdef _WIN64
  typedef unsigned __int64 uintptr_t;
#else
  typedef unsigned int uintptr_t;
#endif
#endif

/* 7.18.2  Limits of specified-width integer types */
#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS)

/* 7.18.2.1  Limits of exact-width integer types */
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN  (-9223372036854775807LL - 1)

#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL

#define UINT8_MAX 0xff /* 255U */
#define UINT16_MAX 0xffff /* 65535U */
#define UINT32_MAX 0xffffffff  /* 4294967295U */
#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */

/* 7.18.2.2  Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN

#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX

#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX

/* 7.18.2.3  Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN

#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX

#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX

/* 7.18.2.4  Limits of integer types capable of holding
    object pointers */
#ifdef _WIN64
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif

/* 7.18.2.5  Limits of greatest-width integer types */
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX

/* 7.18.3  Limits of other integer types */
#define PTRDIFF_MIN INTPTR_MIN
#define PTRDIFF_MAX INTPTR_MAX

#define SIG_ATOMIC_MIN INTPTR_MIN
#define SIG_ATOMIC_MAX INTPTR_MAX

#define SIZE_MAX UINTPTR_MAX

#ifndef WCHAR_MIN  /* also in wchar.h */
#define WCHAR_MIN 0
#define WCHAR_MAX 0xffff /* UINT16_MAX */
#endif

/*
 * wint_t is unsigned short for compatibility with MS runtime
 */
#define WINT_MIN 0
#define WINT_MAX 0xffff /* UINT16_MAX */

#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */


/* 7.18.4  Macros for integer constants */
#if !defined ( __cplusplus) || defined (__STDC_CONSTANT_MACROS)

/* 7.18.4.1  Macros for minimum-width integer constants

    Accoding to Douglas Gwyn <gwyn@arl.mil>:
"This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
9899:1999 as initially published, the expansion was required
to be an integer constant of precisely matching type, which
is impossible to accomplish for the shorter types on most
platforms, because C99 provides no standard way to designate
an integer constant with width less than that of type int.
TC1 changed this to require just an integer constant
*expression* with *promoted* type."
*/

#define INT8_C(val) val
#define UINT8_C(val) val
#define INT16_C(val) val
#define UINT16_C(val) val

#define INT32_C(val) val
#define UINT32_C(val) val##U
#define INT64_C(val) val##LL
#define UINT64_C(val) val##ULL

/* 7.18.4.2  Macros for greatest-width integer constants */
#define INTMAX_C(val)  INT64_C(val)
#define UINTMAX_C(val) UINT64_C(val)

#endif  /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */

#endif

Video.cpp:
#include "Video.h"

Video screen;

Video::Video()
  : m_videomem((uint16_t*) 0xA0000 ), m_color(0x0700)
{
  clear();
}
 
Video::~Video(){
}
 
void Video::clear(){
  setpixel(10, 10, color::blue);
}
 
Video& Video::operator << (const char* s){

  return *this;
}
 
Video& Video::operator << (color::type color){

  return *this;
}
 
Video& Video::operator << (const background& color){

  return *this;
}

void Video::setpixel(int x, int y, color::type color) {
  int offset;
  if(0 <= x && x < 320) {
    if(0 <= y && y < 200) {
      offset = 320*y + x;
      m_videomem[offset] = color;
    }
  }
}

Video.h:
#ifndef VIDEO_H
#define VIDEO_H
 
#include "stdint.h"
 
namespace color
{
  enum type
  {
    black         = 0x00,
    blue          = 0x01,
    green         = 0x02,
    cyan          = 0x03,
    red           = 0x04,
    magenta       = 0x05,
    brown         = 0x06,
    light_gray    = 0x07,
    dark_gray     = 0x08,
    light_blue    = 0x09,
    light_green   = 0x0A,
    light_cyan    = 0x0B,
    light_red     = 0x0C,
    light_magenta = 0x0D,
    yellow        = 0x0E,
    white         = 0x0F
  };
}
 
struct background
{
  inline background(color::type color)
    : m_color(color){}
 
  color::type m_color;
};
 
class Video
{
  public:
    // Konstruktor
    Video();
 
    // Destruktor
    ~Video();
 
    // Leeren des Bildschirms, die Größe beträgt 80x25 Zeichen
    void clear();
 
    // Textausgabe
    Video& operator << (const char* s);
 
    // Vordergrundfarbe setzen
    Video& operator << (color::type color);
 
    // Hintergrundfarbe setzen
    Video& operator << (const background& color);
 
    // Ausgabe eines einzelnen Zeichens
    void setpixel(int x, int y, color::type color);
 
  private:
    // Zeiger auf den Videospeicher
    uint16_t* m_videomem;
 
    // FB/BG-Farbe
    uint16_t m_color;
};
 
// Globale Instanz der Video-Klasse, Definition in Video.cpp
extern Video screen;
 
#endif
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 17. September 2013, 17:15
ich habe den Kernel abgeändert, sodass er VGA nutzt und eigentlich ein Pixel der Position x=10 und y=10 blau färben müsste.

Du hast das Wichtigste und Schwierigste vergessen: Den Grafikmodus zu aktivieren. Ich glaube das Konzept ist dir nicht ganz klar, deswegen werde ich das mal versuchen zu illustrieren. Wenn du in z. B. Windows in der Systemsteuerung die Bildschirmauflösung änderst, dann sendet der Grafiktreiber über die I/O-Schnittstelle Befehle an die Grafikkarte, die sie dazu veranlassen diese Änderung durchzuführen. Wenn du z. B. als Auflösung 1600x1200 wählst, werden andere Befehle an die Grafikkarte gesendet, als wenn du 1920x1080 wählst. Genauso gibts es Befehlsfolgen, die die Grafikkarte in den Textmodus versetzen oder in den 320x200 Grafikmodus. Je nach Modus, verwendet die Grafikkarte einen anderen Speicherbereich aus dem sie Daten für Darstellung ausliest. Für den Textmodus ist das 0xB8000, für 320x200 ist das 0xA0000 und für höhere Auflösungen wieder eine andere Adresse. Was aber nicht funktioniert ist einfach an diese Adressen Sachen zu schreiben und zu erwarten, dass Grafikkarte weiß, welche Auflösung, etc. sie verwenden soll. Der Grund dafür ist wie bereits erwähnt, dass du nicht die entsprechende Befehlssequenz an die Grafikkarte geschickt hast.

Wie TheThing weiter oben schon erwähnt hat, gibt es mehrere Möglichkeiten diese Befehlssequenz an die Grafikkarte zu schicken. Da du dich im Protected Mode befindest, musst du entweder selbst die Grafikkarte ansteuern oder in den Real Mode (bzw. VM86) wechseln und das BIOS dafür aufrufen. Ersteres ist kompliziert und sieht ungefähr so aus: http://files.osdev.org/mirrors/geezer/osd/graphics/modes.c (das ist natürlich Code für mehrere Auflösungen), und das zweite ist in etwa genauso kompliziert und sieht ungefähr so aus: http://git.tyndur.org/?p=tyndur.git;a=blob;f=src/kernel2/src/arch/i386/vm86.c;h=50cc9f3cb1bdbad78bd779459453cb4f0cea16ab;hb=HEAD

Du könntest versuchen die erste Möglichkeit umzusetzen und die modes.c auf einem modernen Compiler zu laufen zu bringen, oder du beschäftigst dich damit in deinem OS den VM86 (http://www.lowlevel.eu/wiki/VM86) zu implementieren (den verlinkten Code aus tyndur nicht kopieren). Von der Illusion, dass wir dir nur helfen müssen einen Pixel zu färben und dann kommst du schon weiter, solltest du dich trennen. Nicht nur hast du noch einiges vor dir, sondern du wirst noch auf viele weitere Hürden stoßen, und ohne dich mit den Grundlagen zu beschäftigen kommst du nicht weit. Wenn du hingegen nur eine grafische Oberfläche umsetzen willst, dann solltest du vielleicht kein OS schreiben, sondern auf einem anderen aufbauen (was spricht gegen XNA, wenn du das schon kannst?). Wenn du so wenig andere Betriebssysteme wie möglich zwischen dir und der Hardware haben willst, kannst du auch versuchen mit einer Bibliothek wie z. B. Allegro unter DOS deine Vorstellungen umzusetzen.

Edit: Sorry wenn das etwas harsch klang. Ich will dich nicht demotivieren. Aber ich will auch nicht um den heißen Brei reden und irgendwelche Illusionen aufbauen.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 17. September 2013, 17:35
ich habe den Kernel abgeändert, sodass er VGA nutzt und eigentlich ein Pixel der Position x=10 und y=10 blau färben müsste.

Du hast das Wichtigste und Schwierigste vergessen: Den Grafikmodus zu aktivieren. Ich glaube das Konzept ist dir nicht ganz klar, deswegen werde ich das mal versuchen zu illustrieren. Wenn du in z. B. Windows in der Systemsteuerung die Bildschirmauflösung änderst, dann sendet der Grafiktreiber über die I/O-Schnittstelle Befehle an die Grafikkarte, die sie dazu veranlassen diese Änderung durchzuführen. Wenn du z. B. als Auflösung 1600x1200 wählst, werden andere Befehle an die Grafikkarte gesendet, als wenn du 1920x1080 wählst. Genauso gibts es Befehlsfolgen, die die Grafikkarte in den Textmodus versetzen oder in den 320x200 Grafikmodus. Je nach Modus, verwendet die Grafikkarte einen anderen Speicherbereich aus dem sie Daten für Darstellung ausliest. Für den Textmodus ist das 0xB8000, für 320x200 ist das 0xA0000 und für höhere Auflösungen wieder eine andere Adresse. Was aber nicht funktioniert ist einfach an diese Adressen Sachen zu schreiben und zu erwarten, dass Grafikkarte weiß, welche Auflösung, etc. sie verwenden soll. Der Grund dafür ist wie bereits erwähnt, dass du nicht die entsprechende Befehlssequenz an die Grafikkarte geschickt hast.

Wie TheThing weiter oben schon erwähnt hat, gibt es mehrere Möglichkeiten diese Befehlssequenz an die Grafikkarte zu schicken. Da du dich im Protected Mode befindest, musst du entweder selbst die Grafikkarte ansteuern oder in den Real Mode (bzw. VM86) wechseln und das BIOS dafür aufrufen. Ersteres ist kompliziert und sieht ungefähr so aus: http://files.osdev.org/mirrors/geezer/osd/graphics/modes.c (das ist natürlich Code für mehrere Auflösungen), und das zweite ist in etwa genauso kompliziert und sieht ungefähr so aus: http://git.tyndur.org/?p=tyndur.git;a=blob;f=src/kernel2/src/arch/i386/vm86.c;h=50cc9f3cb1bdbad78bd779459453cb4f0cea16ab;hb=HEAD

Du könntest versuchen die erste Möglichkeit umzusetzen und die modes.c auf einem modernen Compiler zu laufen zu bringen, oder du beschäftigst dich damit in deinem OS den VM86 (http://www.lowlevel.eu/wiki/VM86) zu implementieren (den verlinkten Code aus tyndur nicht kopieren). Von der Illusion, dass wir dir nur helfen müssen einen Pixel zu färben und dann kommst du schon weiter, solltest du dich trennen. Nicht nur hast du noch einiges vor dir, sondern du wirst noch auf viele weitere Hürden stoßen, und ohne dich mit den Grundlagen zu beschäftigen kommst du nicht weit. Wenn du hingegen nur eine grafische Oberfläche umsetzen willst, dann solltest du vielleicht kein OS schreiben, sondern auf einem anderen aufbauen (was spricht gegen XNA, wenn du das schon kannst?). Wenn du so wenig andere Betriebssysteme wie möglich zwischen dir und der Hardware haben willst, kannst du auch versuchen mit einer Bibliothek wie z. B. Allegro unter DOS deine Vorstellungen umzusetzen.

Edit: Sorry wenn das etwas harsch klang. Ich will dich nicht demotivieren. Aber ich will auch nicht um den heißen Brei reden und irgendwelche Illusionen aufbauen.

Puhh... Die modes.c ist ziemlich groß! und ziemlich kompliziert. Hmm mal sehen ob da was von verstehen kann. Ich gehe auch nochmal die Grundlagen durch.
Gegen XNA spricht im Grunde nichts. Ich habe ein EgoShooter fast komplett hinbekommen. Nur habe ich nicht die Zeit und die Lust alles mit blender zu designen.
 
Edit: Da ich nächste Woche 3 Klausuren schreibe (auch Informatik :-)) hab ich nicht so viel Zeit. Deswegen werde ich mich nach den Grundlage im Textmode an die Tastaturunterstützung setzen.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Svenska am 17. September 2013, 23:21
Hallo,

Puhh... Die modes.c ist ziemlich groß! und ziemlich kompliziert. Hmm mal sehen ob da was von verstehen kann.
Frage mal die Entwickler, die Grafiktreiber für aktuelle Grafikkarten und Smartphones schreiben. Deren Aussage ist, dass es derzeit kein komplizierteres Gerät als eine GPU gibt. (Und die haben in der Regel auch schon Erfahrung mit anderen Treibern.) Dagegen ist VGA noch recht gemütlich.

Wie ich bereits schrieb, beschäftige dich weniger mit Tutorials und Anleitungen und mehr mit Datenblättern oder aufbereiteten Spezifikationen. OS-Entwicklung beschäftigt sich hauptsächlich damit, Treiber für verschiedene Hardware (inklusive der CPU) zu schreiben und eine Umgebung zu schaffen, in der dann Anwendungen laufen.

Grafische Benutzeroberflächen gehören da normalerweise nicht dazu. (Auch unter Windows wird der Desktop von "explorer.exe" bereitgestellt und nicht vom NT-Kernel.) Wenn es dir eher darum geht, solltest du eher einen funktionierenden Kernel nehmen, der einen funktionierenden Grafiktreiber hat, und damit arbeiten.

Noch was: Mit einer direkten Ansteuerung von VGA-Karten bist du auf 640x480 (16 Farben) oder 320x200 (256 Farben) beschränkt. Mehr bietet auch die modes.c nicht. Mit VESA kannst du immerhin alles nutzen, was das Grafik-BIOS anbietet, aber dafür solltest du den Real Mode (oder VM86) nutzen. Beide Ansätze sind ziemlich langsam. Alles, was darüber hinausgeht, ist effektiv nicht machbar.

Gruß,
Svenska
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 26. September 2013, 19:55
Hi,
habe in den vergangeden Tagen den Tastatursupport fast komplett selbst hinbekommen  :-). Ich lese den port 0x60 aus und übersetze den Scancode mittels einer Header-Datei in Charwerte.
Es werden mittlerweile alle Tasten außer ä,ö,ü,ß,´,Shift, Tab, [Pfleiltasten],[PageUp, Einfg...] unterstützt! Wie ich das mit Shift und Tab hinbekomme weiß ich bereits, aber bei den Umlauten hab
ich keine Ahnung wie ich das angehen soll. Im I-net stand da auch nichts zu. Das größere Problem ist allerdings, das manche Tasten mehrere Scancodes haben(so meine Vermutung :-D).
Wenn ich z.B. - drücke printet er -/ . Das gleiche passiert, wenn ich /(auf Numpad) drücke. Wenn ich aber das Minus auf dem Numpad drücke kommt auch nur ein minus.
Ein weiteres Beispiel ist PageUp. Dann printet er eine 9. Wenn ich dem Scancode 201 noch nur zum Test # zuweise, printet er 9 und #.
Das ist die Codestelle zu dem -:
        // unsigned char c = Scancode aus Wertübergabe
else if(c==53 || c==74) //Scancodeabfrage (normal || numpad)
{
c1='-'; //Charwert zuweisen
}
Ich weiß, dass es besser ist, wenn man es mit einem Array löst. Das kommt noch...
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 26. September 2013, 20:03
Ich glaube du hast das Konzept von Make- und Breakcodes nicht richtig umgesetzt. Scancode 201 existiert nicht, sondern dass ist der Breakcode von 73, da 73 + 128 = 201. Die Scancodes von 0-127 heißen "make codes", und werden gesendet, wenn die Taste gedrückt wurde. Die Scancodes 128-255 heißen "break codes" und werden gesendet, wenn die Taste wieder losgelassen wurde. Das heißt die make codes sollten (fürs erste) bei dir veranlassen, dass das Zeichen ausgegeben wurde, und die break codes sollten nichts tun (außer du hast damit kompliziertes vor).
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: streetrunner am 26. September 2013, 20:27
Es kommt mir so vor als ob du über das amerikanische Tastatur-Layout stolperst. Da gibt es keine Umlaute, da diese halt im Englischen nicht vorkommen. Dafür sind diese Tasten mit anderen Zeichen belegt, das gilt auch für etliche andere Tasten (das y und z vertauscht sind ist da nur die Spitze des Eisbergs). Was du auf deiner Tastatur siehst ist das Deutsche Layout, aber deine Tastatur weiß davon natürlich nichts, sie sendet weiterhin die Englischen Codes.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Svenska am 27. September 2013, 04:21
Was du auf deiner Tastatur siehst ist das Deutsche Layout, aber deine Tastatur weiß davon natürlich nichts, sie sendet weiterhin die Englischen Codes.
Jaein: Es gibt keine englischen oder deutschen Codes. Die Tastatur sendet Scancodes für die Tasten, nicht für deren Bedeutung. Einen Sinn aus den Tastendrücken musst du selbst rauslesen. Darum ist es ziemlich sinnvoll, die (tastaturabhängigen*) Scancodes erst in (tastaturunabhängige) Tastencodes umzusetzen und erst danach mit einem Tastaturlayout ein Zeichen zuzuweisen (sofern es eins gibt - F2 hat eher keins, ist aber trotzdem eine Taste).

* Die 105-Tasten-PC-Tastatur ist zwar standardisiert, aber Sondertasten wie "Play/Pause", "Browser öffnen" u.ä. sind unterschiedlich.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 29. September 2013, 14:09
Ich glaube du hast das Konzept von Make- und Breakcodes nicht richtig umgesetzt. Scancode 201 existiert nicht, sondern dass ist der Breakcode von 73, da 73 + 128 = 201. Die Scancodes von 0-127 heißen "make codes", und werden gesendet, wenn die Taste gedrückt wurde. Die Scancodes 128-255 heißen "break codes" und werden gesendet, wenn die Taste wieder losgelassen wurde. Das heißt die make codes sollten (fürs erste) bei dir veranlassen, dass das Zeichen ausgegeben wurde, und die break codes sollten nichts tun (außer du hast damit kompliziertes vor).
Ok. Aber wie kann ich jetzt Make- und Breakcode unterscheiden? Lässt sich der Breakcode irgendwie identifizieren?

 Ich habe erstmal den / entfernt. Wenn ich - gedrückt halte macht er ein Minus. Wenn ich / gredückt halte macht er ganz viel Minus. Das heiß er nimmt bei beiden den Makecode. Nur nimmt er den bei - nur einmal und bei / unendlich.  :?

Wenn ich z.B. das l auf 166 setzte, dann setzt er auch nur ein l wenn ich die Taste auch loslasse. (so wie es soll)
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Svenska am 29. September 2013, 15:21
Aber wie kann ich jetzt Make- und Breakcode unterscheiden? Lässt sich der Breakcode irgendwie identifizieren?
Wenn der Scancode kleiner als 128 ist, ist es ein Make-Code, sonst ist es ein Break-Code (für die Taste "Scancode-128").
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 29. September 2013, 15:53
Da hätte ich auch drauf kommen können  :-)
Aber in meiner ScConverter.h ist mein höchster Wert 86. Also habe ich noch nie was mit dem Breakcode gemacht. Trotzdem habe ich das Problem mit dem - und /(man drückt / und es kommt -). Was vielleicht wichtig zu erwähnen ist: am Ende habe ich in der ScConverter.h:
else
c1='\0';
und in der Video.cpp:
    key=inb(0x060);
    final_key=SC2Char(key); //ScanCode in Char
    if(oldkey!=key && final_key!='\0'){
      put(final_key);
    }

Die Scancodes habe ich von http://www.blitzforum.de/help/Scancodes (http://www.blitzforum.de/help/Scancodes)
Stimmt mit denen was nicht?
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 03. October 2013, 12:40
Hallo,
habe jetzt versuch alles mit einem Array zu machen. Allerdings gibt er bei manchen Buchstaben noch ein anderes Zeichen mit aus. Wenn ich das mit den Breakcode richtig verstanden habe kann es daran nich liegen O.o
Hier der Code:
#ifndef ScConverter_H
#define ScConverter_H
 
#include "stdint.h"
 
  char SC2Char(unsigned char c)
  {
unsigned char nonShifttabel[] = {0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 0, 0, 0,
0, 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 0, '+', 0, 0,
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0, 0, '^', 0, '#',
'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-', 0, 0, 0, ' ', 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ',', '<', 0, 0, 0, 0 };

        //kommt später:
/*unsigned char Shifttabel[] = {0, 0, '!', 0, '§', '$', '%', '&', '/', '(', ')', '=', '?', 0, 0,
0, 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 0, '*', 0, 0,
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0, 0, '^', 0, 0,
'Y', 'X', 'C', 'V', 'B', 'N', 'M', ';', ':', '-', 0, 0, 0, ' ', 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ',', '<', 0, 0, 0, 0 };*/
unsigned char c1;

if(nonShifttabel[c] != 0)
{
c1=nonShifttabel[c];
}
else
{
c1='\0';
}
return c1;
  }
#endif
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 09. October 2013, 17:15
Aber wie kann ich jetzt Make- und Breakcode unterscheiden? Lässt sich der Breakcode irgendwie identifizieren?
Wenn der Scancode kleiner als 128 ist, ist es ein Make-Code, sonst ist es ein Break-Code (für die Taste "Scancode-128").

Hallo,
ich habe jetzt glaub ich mein Problem erkannt! Die eine Frage zur Unterscheidung von Make und Breakcode war flasch gestellt! Was ich eigentlich fragen wollte war, wie man z.B. zwischen PgUp und 9(Numpad) unterscheidet. In den Tabellen, die man im Internet findet steht:
Zitat
Keypad 9  (PgUp)
Soll das heißen, dass die 9 auf dem Numpad und PageUp den gleichen Make und Breakcode haben? Irgendwie unterscheiden sie sich ja schon:
Zitat
9 gedrückt halten = 9
!=
Zitat
PgUp gedrückt halten = 999999...

EDIT: Ich seh grade das das höchstwahrscheinlich an den extended Scancodes liegt. Habe versucht sie hiermit abzufangen... hat aber nicht geklappt :( :

if(c==0xE0 || c==0xE1)
return '\0';

lolxdfly
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 11. October 2013, 17:41
Ja, soweit ich weiß hat das was mit Extended Scan Codes zu tun. Wenn du einen Keyboard-IRQ bekommst, der dir einen Extended Scan Code liefert, solltest du das in einer Variable merken, und beim nächsten IRQ dann entsprechend behandeln. Siehe auch Beispiel im Wiki (http://www.lowlevel.eu/wiki/KBC#IRQ-Handler). Ich weiß nicht, ob die 9 oder die Bild-Auf-Taste den Extended Scan Code sendet, aber das kann man ja experimentell feststellen.

Vermutlich hast du bisher auch noch nichts getan, um die Taste Num Lock zu behandeln. Wenn Num Lock aus ist, dann sollte beim Drücken der 9 ja tatsächlich dasselbe passieren wie bei der Bild-Auf-Taste. Die Unterscheidung ob Num Lock an oder aus ist, geschieht übrigens im Treiber, nicht in der Tastatur selbst. Du solltest also die LEDs (Num Lock, Caps Lock und Scroll Lock) so initialisieren wie du das haben willst(mit Tastatur-Befehl 0xED (http://www.lowlevel.eu/wiki/KBC#Tastatur-Befehle)), und in deinem Treiber entsprechende Variablen setzen, um dir zu merken welche LED an ist. Wenn der User dann die Num Lock Taste drückt, musst du die Variable entsprechend ändern. Wenn du den Scancode für 9 bekommst, schaust du dann in dieser Variable nach, und wenn Num Lock aus ist, tust du so, als ob Bild-Auf gedrückt wurde, ansonsten halt eine 9.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Svenska am 11. October 2013, 22:22
Hallo,

die ersten PC-Tastaturen hatten 10 F-Tasten links, Buchstaben, Ziffernblock und sonst nichts. Das ganze Extended-Scancode-Zeug ist darum so kompliziert, damit Software, die solche alten Tastaturen erwartet, nicht verwirrt wird (solange unbekannte Scancodes ignoriert werden).

Gruß,
Svenska
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 12. October 2013, 14:09
Hallo,
danke für die Antworten :-).
Leider habe ich das Arbeiten mit Befehlen von Ports noch nie richtig hinbekommen (Habe es bis jetzt ja auch noch nie dringend gebraucht).
Ich habs mal so versucht:
bool ScrollLock=0;
bool NumLock=0;
bool CapsLock=0;
uint8_t led=inb(0xED); //Port:0x60 Befehl:0xED ...hmmm outb hätte 2 Wertübergaben, aber es returnt kein Wert
if(led == 00000001)         ScrollLock=1;
if(led == 00000010)            NumLock=1;
if(led == 00000100) CapsLock=1;
if(led == 00000110) CapsLock=1;    NumLock=1;
if(led == 00000011)    NumLock=1;   ScrollLock=1;
if(led == 00000111) CapsLock=1;    NumLock=1; ScrollLock=1;       
Kann mir jemand erklären, wie man es richig macht?

lolxdfly
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Svenska am 12. October 2013, 14:30
Es gibt wie immer mehrere Lösungen. Aus meiner Sicht ist die eleganteste Möglichkeit ein Zustandsautomat (state machine). Suche dir mal im Internet raus, wie das funktioniert. Implementieren kannst du es mit einem switch/case.

IN liest von einem Port. Du übergibst also die Adresse des Ports und bekommst einen Wert geliefert.
OUT schreibt auf einen Port. Du übergibst also die Adresse des Ports und zusätzlich einen Wert.

Wenn du auf einen Port etwas schreiben sollst und dann die Antwort lesen sollst, dann musst du erst OUT(Port, Daten) machen, um dann mit Ergebnis = IN(Port) das Ergebnis zu lesen.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 13. October 2013, 14:20
Es gibt wie immer mehrere Lösungen. Aus meiner Sicht ist die eleganteste Möglichkeit ein Zustandsautomat (state machine). Suche dir mal im Internet raus, wie das funktioniert. Implementieren kannst du es mit einem switch/case.

IN liest von einem Port. Du übergibst also die Adresse des Ports und bekommst einen Wert geliefert.
OUT schreibt auf einen Port. Du übergibst also die Adresse des Ports und zusätzlich einen Wert.

Wenn du auf einen Port etwas schreiben sollst und dann die Antwort lesen sollst, dann musst du erst OUT(Port, Daten) machen, um dann mit Ergebnis = IN(Port) das Ergebnis zu lesen.

Danke. Hmm trotzdem mache ich noch immer was falsch. Ich habe outb(0x60, 0xED) eingefügt! Außerdem habe ich vorsichtshalber den Binärcode in Dezimalcode umgerechnet, weil ich mir nicht sicher war, ob er den als binär erkennt:
bool ScrollLock=0;
bool NumLock=0;
bool CapsLock=0;
outb(0x60, 0xED); // Befehl 0xED an Port 0x60 schreiben
uint8_t led=inb(0x60); //Port 0x60 auslesen
if(led == 1) ScrollLock=1;
if(led == 2) NumLock=1;
if(led == 4) CapsLock=1;
if(led == 5) CapsLock=1; ScrollLock=1;
if(led == 6) CapsLock=1; NumLock=1;
if(led == 3) NumLock=1; ScrollLock=1;
if(led == 7) CapsLock=1; NumLock=1; ScrollLock=1;
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Svenska am 13. October 2013, 14:50
Hallo,

Portzugriffe sind Hardwarezugriffe, im Allgemeinen ist das kein RAM. Das heißt, wenn du etwas reinschreibst, dann heißt das nicht, dass du das auch wieder rauslesen kannst. Lese- und Schreibzugriffe können völlig verschiedene Dinge in der Hardware auslösen.

Der Tastaturbefehl 0xED setzt den LED-Zustand. Lesen kannst du ihn damit nicht. "OUT(0x60, 0xED); OUT(0x60, 0x07);" sollte die drei LEDs einschalten.

Verlasse dich niemals darauf, dass reservierte Bits beim Lesen den Wert Null haben. Aktualisierte Chips nutzen diese Bits möglicherweise für Sonderfunktionen, sind aber zur älteren Version kompatibel. Dann gilt in der Regel (siehe Datenblatt!), dass man reservierte Bits ignoriert (Lesezugriff) oder nullsetzt (Schreibzugriff). Das heißt, dass deine Liste von Abfragen alle(!) 256 möglichen Einträge abfragen sollte. Um sich das zu ersparen, arbeitet man mit Bitmasken, die man mit logischen Operatoren auswertet:

if(led & 0x01) ScrollLock=1; else ScrollLock=0;
if(led & 0x02) NumLock=1;    else NumLock=0;
if(led & 0x04) CapsLock=1;   else CapsLock=0;

oder kürzer (ternäres if):

ScrollLock = (led & 0x01) ? 1 : 0;
NumLock    = (led & 0x02) ? 1 : 0;
CapsLock   = (led & 0x04) ? 1 : 0;

Damit erleichterst du es dem Compiler außerdem, guten Code zu erzeugen.

Gruß,
Svenska
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: kevin am 13. October 2013, 14:57
oder kürzer (ternäres if):

ScrollLock = (led & 0x01) ? 1 : 0;
NumLock    = (led & 0x02) ? 1 : 0;
CapsLock   = (led & 0x04) ? 1 : 0;
Das ist immer noch unnötig kompliziert. Das hier reicht, weil die Variablen ja bools sind:
ScrollLock = led & 0x01;
NumLock    = led & 0x02;
CapsLock   = led & 0x04;
Wenn man ints dafür missbrauchen würde und trotzdem immer 0/1 als Ergebnis haben wollte, könnte man auch !!(led & 0x01) benutzen.


Quizfrage noch für lolxdfly: Welche Anweisungen in folgender Zeile sind bedingt und welche nicht?
if(led == 7) CapsLock=1; NumLock=1; ScrollLock=1;
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 13. October 2013, 15:21
Quizfrage noch für lolxdfly: Welche Anweisungen in folgender Zeile sind bedingt und welche nicht?
if(led == 7) CapsLock=1; NumLock=1; ScrollLock=1;
hmm ich glaube es geht nur bis zum ersten Semikolon  :-D also hört es nach CapsLock=1; und NumLock=1; ScrollLock=1; sind nicht mehr bedingt... (mist)

War das jetzt richtig, dass ich mit outb(0x60, 0xED) den LED-Zustand setzte und dann mit inb(0x60) den LED-Status auslese?
Oder soll ich alle LEDs aus machen und dann den Scancode für die Tasten abscannen, die die LED-Status ändern können?
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Svenska am 14. October 2013, 00:40
Frage:
War das jetzt richtig, dass ich mit outb(0x60, 0xED) den LED-Zustand setzte und dann mit inb(0x60) den LED-Status auslese?
Antwort:
Der Tastaturbefehl 0xED setzt den LED-Zustand. Lesen kannst du ihn damit nicht.

 :evil:

Das ist immer noch unnötig kompliziert. Das hier reicht, weil die Variablen ja bools sind:
ScrollLock = led & 0x01;
NumLock    = led & 0x02;
CapsLock   = led & 0x04;
Stimmt natürlich, allerdings sind die Variablen dann nicht mehr 0 oder 1. Aus !!(led & 0x01) sollte der Compiler aber den gleichen Code generieren wie aus (led & 0x01) ? 1 : 0.

Gruß,
Svenska
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: kevin am 14. October 2013, 09:59
Stimmt, sie sind nicht 0 oder 1, sondern true oder false (wie vorher auch, waren ja auch bei dir schon bools). Was in einen Integer gecastet aber 0 oder 1 gibt und nicht irgendwelche anderen Zahlen, insofern ist das praktisch gesehen das gleiche.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 21. January 2014, 17:32
Hallo,
innerhalb meiner "Pause" in der Kernelentwicklung habe ich viele neue Erfahrungen gewonnen, mitdessen Hilfe ich jetzt den KeyboardTreiber fertig gekommen habe. Er funktioniert auch fast fehlerfrei (kernel crash, wenn ein 'd' im Input gelesen wird). Damit funktioniert endlich das Login meines Kernels  :lol:

Da ich alles was mit Grafik und Maus zutun hat erstmal auf später verschoben habe, wollte ich jetzt erst einmal alles was mit Interrupts zutun hat zum laufen bekommen.
Ersteinmal muss ich sagen, dass dieses http://www.lowlevel.eu/wiki/PIC_Tutorial (http://www.lowlevel.eu/wiki/PIC_Tutorial) echt gut erklärt ist. Ich hab zum ersten mal alles verstanden, was auf der Seite stand.  :-D
Mein Problem ist das implementieren der Interrupt Service Routine. Da ich noch fast keine ASM-Erfahrungen habe fällt es mir schwer den ASM-Teil zu codieren.

Wenn man nach dem hier vorgeht http://www.lowlevel.eu/wiki/Teil_5_-_Interrupts (http://www.lowlevel.eu/wiki/Teil_5_-_Interrupts) muss man "nur" die Descriptor Tables implementieren. Vom ISR wird hier nichts gesagt :/
Oder sind das 2 verschieden Sachen?

lolxdfly

EDIT: der crash wenn ich das 'd' drücke habe ich behoben!! Bei den Interrups bin ich nix weiter...

EDIT2: Bin jetzt mit dem GDT angefangen. Sooo schwer ist das ja gar nicht. Überseh ich was oder geht aus dem TuT nicht hervor, welche Größe GDT_ENTRIES haben muss?
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: kevin am 21. January 2014, 20:05
Die Adresse des Interrupthandlers ist Teil des Eintrags in der IDT, du kommst also nicht drum herum. ;)
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 06. February 2014, 21:33
Hallo,
das GTD gibt mir zwei Compile Error:
Zitat
expected primary-expression before '.' token

Eigentlich ist relativ klar was da falsch gelaufen ist, aber der Fix der gehen sollte geht nicht:
struct __TEST {
    uint16_t limit;
    void* pointer;
} __attribute__((packed)) gdtp = {
    __TEST.limit = GDT_ENTRIES * 8 - 1,
    __TEST.pointer = gdt,
};
(Ich musste den anonymous struckt in einen normel umformen da dies sonst bei c++ probleme machen würde: non-local '<anonymous struct> gdtp' vairable uses anonymus types.)

Oder hab ich irgendwas anderes falsch gemacht?  :?

lolxdfly
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 06. February 2014, 21:44
Initialisierung von structs funktioniert nur in C, nicht in C++. Der Fix sollte vermutlich eher so aussehen:

struct gdt_pointer {
    uint16_t limit;
    void* pointer;
} __attribute__((packed));

gdt_pointer gdtp;

gdtp.limit = GDT_ENTRIES * 8 - 1;
gdtp.pointer = gdt;
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 06. May 2014, 13:58
Initialisierung von structs funktioniert nur in C, nicht in C++. Der Fix sollte vermutlich eher so aussehen:

struct gdt_pointer {
    uint16_t limit;
    void* pointer;
} __attribute__((packed));

gdt_pointer gdtp;

gdtp.limit = GDT_ENTRIES * 8 - 1;
gdtp.pointer = gdt;

Auch diese Version geht nicht... aber das ist mittlerweile egal. Habs selber hinbekommen  :wink:

Ich hab quasi von neu angefangen und and das meiste selber im eigenen Stiel gemacht. Mag sein, dass ich jz die Verbesserungen von C++ gegüber C nicht ganz ausnutze, aber das spielt ja denke ich keine große Rolle. Es läuft jetzt endlich das ganze GDT, IDT, IRQs und PIT Krams.
Im mom. bin ich beim Paging angelangt...

Ich habe vor den Codeaufbau wie er hier (http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html (http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html)) beschrieben ist als Beispiel zu nehmen. Ich bekomme nur eine undefenierte Referenz zu der panic Funktion...

#define PANIC(msg) (panic(msg, __FILE__, __LINE__)) //undefined reference to panic(....

extern void panic(const char *message, const char *file, uint32_t line);

Auch wenn panic als extern "C" void deklariert ist gibt es den linking error ;/
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: kevin am 06. May 2014, 14:03
Wenn ich die ganz blöde Frage stellen darf: Hast du nur den panic()-Prototypen oder auch wirklich eine Implementierung dafür? Und falls ja, wird die Implementierung auch mitgelinkt?
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 06. May 2014, 14:11
Wenn ich die ganz blöde Frage stellen darf: Hast du nur den panic()-Prototypen oder auch wirklich eine Implementierung dafür? Und falls ja, wird die Implementierung auch mitgelinkt?
Ja ich habe auch eine fertige Funktion in der .cpp and ja die .o wird mitgelinkt!
extern void panic(char *message, char *file, uint32_t line)
{
    asm volatile("cli"); // Disable interrupts.

    video_write("PANIC(", COLOR_BLACK, COLOR_RED);
    video_write(message, COLOR_BLACK, COLOR_RED);
    video_write(") at ", COLOR_BLACK, COLOR_RED);
    video_write(file, COLOR_BLACK, COLOR_RED);
    video_write(":", COLOR_BLACK, COLOR_RED);
    video_write_dec(line, COLOR_BLACK, COLOR_LIGHT_GRAY);
    video_write("\n", COLOR_BLACK, COLOR_LIGHT_GRAY);
    // Halt by going into an infinite loop.
    for(;;);
}

PS: Erlich gesagt habe ich keine Ahnung warum die Funktion hier als extern deklariert wurde, aber in dem TuT war es genauso und wenn man sie "normal" deklariert ändert das nichts am Error :/

EDIT: Habs X_X... dummer Fehler:

in .h: void panic(const char *message, const char *file, uint32_t line);
in .cpp: void panic(char *message, char *file, uint32_t line);

EDIT2:Ok.. wie ich es schon befürchtet hatte crasht es wenn ich Paging aktiviere...
im Qemu Log taucht folgendes auf:
Zitat
check_exception old: 0xffffffff new 0xe
check_exception old: 0xe new 0xe
Im ObjDump gibt es kein
Zitat
00102c17
!!!

EDIT3:Habs gefunden, nicht gefixt :/
Ist genauso wie hier: nur mit 10187e: http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren (http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren)

EDIT4: Dürfte am link script liegen... die Adresse ist ein externes Symbl aus dem Link Script:
  end = .; _end = .; __end = .;soll ich dass einfach ans Ende dranklatschen? Hab leider überhaupt keine Ahnung was Link Scripte angeht :S
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 06. May 2014, 20:53
EDIT3:Habs gefunden, nicht gefixt :/
Ist genauso wie hier: nur mit 10187e: http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren (http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren)

EDIT4: Dürfte am link script liegen... die Adresse ist ein externes Symbl aus dem Link Script:
  end = .; _end = .; __end = .;soll ich dass einfach ans Ende dranklatschen? Hab leider überhaupt keine Ahnung was Link Scripte angeht :S
Das verstehe ich nicht. Ist an der Adresse 10187e das Symbol "end"?
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 06. May 2014, 21:05
EDIT3:Habs gefunden, nicht gefixt :/
Ist genauso wie hier: nur mit 10187e: http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren (http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren)

EDIT4: Dürfte am link script liegen... die Adresse ist ein externes Symbl aus dem Link Script:
  end = .; _end = .; __end = .;soll ich dass einfach ans Ende dranklatschen? Hab leider überhaupt keine Ahnung was Link Scripte angeht :S
Das verstehe ich nicht. Ist an der Adresse 10187e das Symbol "end"?

Ne... war vllt etwas unglücklich formuliert.
Der Qemu log sagt folgendes:
check_exception old: 0xe new 0xe
     3: v=08 e=0000 i=0 cpl=0 IP=0008:0010188e pc=0010188e SP=0010:001fff90 EAX=80000011
Da ich sachen geändert habe hat sich die Adresse wieder geändert... vorher war es 10187e!

Dann habe ich mein Kernel disasm.:
  10187b: 0f 22 c0              mov    %eax,%cr0
  10187e: c9                    leave 
  10187f: c3                    ret   
Wie man sieht scheint der gleiche Fehler, wie hier beschrieben vorzuliegen: http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren (http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren)

In "meiner" Source findet man bezüglich der Speicheradresse das hier:
// end ist im linker script definiert!
extern uint32_t end;
uint32_t placement_address = (uint32_t)&end;

Die Deklarierung von end im LinkerScript sieht bei dem BeispielKernel wiefolgt aus:
ENTRY(start)
SECTIONS
{

    .text 0x100000 :
    {
        code = .; _code = .; __code = .;
        *(.text)
        . = ALIGN(4096);
    }

    .data :
    {
        data = .; _data = .; __data = .;
        *(.data)
        *(.rodata)
        . = ALIGN(4096);
    }

    .bss :
    {
        bss = .; _bss = .; __bss = .;
        *(.bss)
        . = ALIGN(4096);
    }

    end = .; _end = .; __end = .;
}
Ich denke mal ich hab das was im Linker Script bezüglich end falsch gemacht:
ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386:i386)

SECTIONS
{
  . = 0x0100000;

  .text :
  {
    *(.text*)
    *(.rodata)
  }

  .data  :
  {
    start_ctors = .;
    *(.ctors)
    end_ctors = .;

    *(.data)
  }

  .bss  :
  {
    *(.bss)
  }

  end = .; _end = .; __end = .;
 
  /DISCARD/ : { *(.dtors) *(.comment) }
}
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 06. May 2014, 21:28
Der Qemu log sagt folgendes:
check_exception old: 0xe new 0xe
     3: v=08 e=0000 i=0 cpl=0 IP=0008:0010188e pc=0010188e SP=0010:001fff90 EAX=80000011
Das ist bereits der zweite Fault. Der Registerdump, der mit check_exception old: 0xffffffff new 0xe anfängt, ist der interessante, weil es der erste ist. In diesem Fall scheints aber keinen Unterschied zu machen.

Zitat
Dann habe ich mein Kernel disasm.:
  10187b: 0f 22 c0              mov    %eax,%cr0
  10187e: c9                    leave 
  10187f: c3                    ret   
Wie man sieht scheint der gleiche Fehler, wie hier beschrieben vorzuliegen: http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren (http://www.lowlevel.eu/wiki/Teil_9_-_Paging#Paging_aktivieren)
Falls du das Tutorial befolgst: Hast du den Rest des Artikels abgearbeitet, also ein sinnvolles Page Directory erstellt? Falls du das Tutorial nicht befolgst: Du musst ein sinnvolles Page Directory erstellen, das den Kernel sowie alle sonstigen Datenstrukturen, auf die der Kernel zugreift (beispielsweise das Page Directory, alles was deine alloc-Funktion zurückgibt, ...) mappen.

In "meiner" Source findet man bezüglich der Speicheradresse das hier:
// end ist im linker script definiert!
extern uint32_t end;
uint32_t placement_address = (uint32_t)&end;
Wie kommst du zu der Folgerung, dass sich die Speicheradresse auf diesen Ausschnitt bezieht? Du hast ja eben noch das kurze Schnipsel Assemblercode gezeigt, das für mich eher danach aussieht.

Zitat
Ich denke mal ich hab das was im Linker Script bezüglich end falsch gemacht:
Sieht eigentlich alles richtig aus. Du könntest ein
        . = ALIGN(4096);davor tun, um die Adressen auf ein vielfaches von 4096 zu runden, falls dein Code das nicht selbst tut.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 07. May 2014, 19:58
Okay... danke erstmal für die Informationen.
Natürlich habe ich mir den Paging Artikel durchgelesen, aber beim programmieren gehe ich nach einem anderen TuT vor. Daher müsste ich die Page Directory bereits drinne haben!

das es etwas mit end zutun hat war nur so ein Gedanke :/

Habe alles erneut debuggt, aber den Fehler habe ich noch nicht wirklich gefunden. Allerdings weiß ich an welche Stelle es im Code crasht:
    current_directory = newdir;
    asm volatile("mov %0, %%cr3":: "r"(&newdir->tablesPhysical));
    uint32_t cr0;
    asm volatile("mov %%cr0, %0": "=r"(cr0));
    cr0 |= 0x80000000; // Enable paging!
    asm volatile("mov %0, %%cr0":: "r"(cr0)); // <==crash here
Das sieht im Beispiel Code allerdings 100% genauso aus. Kann es daran liegen, dass der Beispielcode in C ist?
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 07. May 2014, 20:03
Es liegt definitv daran, dass was Falsches im Page Directory steht. Der Crash an der Stelle, an der Paging aktiviert wird, heißt nämlich, dass der Code direkt nach dem Aktivieren nicht mehr ausgeführt werden konnte. Das heißt, dass was da eigentlich sein sollte (Code) ist nicht mehr da.

Die Ursachen dafür können vielfältig sein, und du solltest mal den Prozess des Erstellens und Befüllens des Page Directories debuggen.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Martin Erhardt am 08. May 2014, 15:06
Etwas was Ich dir auch absolut empfehlen würde ist memory examining. Setze einfach kurz vor der Aktivierung von Paging eine Endlos-schleife und lass dir die Adresse der Pagedirectory table ausgeben. Dann Qemu starten, in den Qemu monitor wechseln(Strg-Alt-2) und mit xp <addresse der page_directory table> schauen was dort steht. Dann kannst du so zu den pagetables navigieren und schauen ob die Einträge stimmen die Flags gesetzt sind, überhaupt irgendwas im Eintrag steht oder die Flags vielleicht von den addressen überschrieben wurden. Häufig ist in solchen Fällen einfach ein Datentyp, eine Struktur, oder ein Mokro falsch definiert. Mit memory examining siehst du das sofort.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Svenska am 08. May 2014, 17:07
Wenn du mit GDB einen Breakpoint direkt auf den "mov cr0, %%"-Befehl setzt und danach die CPU einmalig single-stepst, dann hast du Paging aktiviert, bevor der Crash auftritt. Dann kannst du dir im Qemu-Monitor mit "info mem" und "info tlb" besser anschauen, was die CPU gerade denkt.

Bei deaktiviertem Paging gibt der Qemu-Monitor bei beiden Befehlen nur "PG disabled" aus.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 10. May 2014, 23:29
Danke.
Hab jetzt so hinbekommen. Keine Ahnung woran es lag. Ich habe das komplette Paging System neugeschrieben(ohne Codeteile aus TuTs zu nehmen). War gar nicht so schwer wie ich anfangs dachte  :-D

Edit: Ist wohl doch schwerer  :|
Wenn ich paging aktiviere crasht der Kernel, sobald eine Taste grdrückt wird(Im kernel wird getinput(COLOR_BLACK, COLOR_WHITE); ausgeführt. Es crasht also, weil das paging irgendwie mein KBC behindert).
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 02. August 2014, 17:20
Hi,
ich habe wiedermal angefangen an meinem Kernel weiter zuarbeiten..
Als erstes wollte ich den Ps2-Tastaturtreiber überarbeiten. Alles läuft soweit gut. Jedoch scheitere ich daran, das eingegebene auszulesen -.- 
Hier seht ihr meine Funktion, die den keycode verarbeiten soll:
typedef char* string; //aus string.h
string tmp = "";
void send_keycode(unsigned char keycode, bool isBreakcode)
{
if(keycode!=0 && !break_code)
{
if(keycode == RETURN)
{
readkbc = false;
return;
}
monitor_put(keycode, backg, forg);
tmp += keycode; //failed
//strcat(tmp, keycode); //<= hat den gleichen Effekt
}
}

string GetKBCInput(color bg, color fg)
{
backg = bg;
forg = fg;
readkbc = true;
for(;;)
{
if(!readkbc)
break;
}
monitor_write("\nDebug: ", COLOR_BLACK, COLOR_YELLOW);
monitor_write(tmp, COLOR_BLACK, COLOR_YELLOW);
return tmp;
}

Als Ausgabe bekomme ich lediglich: "Debug: ". Also muss tmp unverändert, also leer sein :/
Zuvor noch natürlich das Eingegebene. Das heißt, dass er alles richtig übersetzt und es verarbeitet, nur irgendwie scheint er tmp += keycode; zu ignorieren..

mfg
lolxdfly
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 02. August 2014, 18:16
Zuvor noch natürlich das Eingegebene. Das heißt, dass er alles richtig übersetzt und es verarbeitet, nur irgendwie scheint er tmp += keycode; zu ignorieren..
Richtig, das funktioniert nicht, weil C nicht C++ ist. Der Operator += funktioniert da nicht, wie du denkst (er macht insbesondere nicht dasselbe wie strcat), auch wenn du char* "string" nennst.

Der Wert "" (leerer String) kann nicht verändert werden, weil er eine Konstante ist. Der Compiler allokiert keinen dynamischen Speicher dafür, das heißt, wenn du versuchst, da was ranzuhängen, hast du einen Bufferoverflow. Das heißt strcat geht auch nicht.

Wenn du eine Zeichenkette dynamisch verlängern willst, musst du mit malloc (oder strdup) arbeiten, wobei du das free() vom Originalstring nicht vergessen solltest, sonst hast du Memory Leaks. Wäre mir allerdings zu aufwändig für sowas einfaches. Deswegen würde ich einen statischen Puffer konstanter Länge vorschlagen:

unsigned char key_buffer[16 + 1]; // statt tmp. Das +1 brauchst du nur für deine GetKBCInput
int next_key = 0;

// in send_keycode Zeichen in den Puffer tun
if (next_key >= 16) { return; } /* Fehler: Puffer ist voll */
key_buffer[next_key++] = keycode;
key_buffer[next_key] = 0; // Null-terminieren nicht vergessen (nur nötig für deine GetKBCInput)

// deine Ausgabe in GetKBCInput (was soll die Funktion eigentlich machen?)
monitor_write(key_buffer, ...)
return key_buffer;

Meine Frage wäre, was die GetKBCInput-Methode eigentlich machen soll. Soll die sowas wie getchar() (http://www.cplusplus.com/reference/cstdio/getchar/) sein? Dann sollte sie nur ein Zeichen (das älteste) aus key_buffer zurückgeben und dieses Zeichen aus key_buffer entfernen. Das kannst du durch Kopieren machen oder key_buffer als Ringpuffer (http://de.wikipedia.org/wiki/Warteschlange_%28Datenstruktur%29#Implementierung_als_Ringpuffer) implementieren.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 02. August 2014, 18:54
Danke.. damit läuft es.
Und zu GetKBCInput: GetKBCInput soll den Input liefern, bis der Benutzer Return drückt. Hat also viel Ähnlichkeit mit getchar(); :)
Bei getchar(); werden jedoch nur die einzelnen chars returnt und ich fand, dass es für so einen Anwendungszweck besser einen ganzen string returnen sollte:
  if(GetKBCInput(COLOR_BLACK, COLOR_WHITE)=="lolxdfly")
monitor_write("Hello, KBC!\n", COLOR_BLACK, COLOR_WHITE);
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 09. August 2014, 17:30
Eine kleine Frage: Sollte mir Folgendes Sorgen bereiten?

SMM: enter
EAX=00000001 EBX=80000b58 ECX=00000000 EDX=00000cfc
ESI=000e857d EDI=0003802d EBP=80000070 ESP=00006ee0
EIP=000ef7b2 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fce38 00000037
IDT=     000fdcf0 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=000e8550 CCD=00000001 CCO=LOGICB 
EFER=0000000000000000
SMM: after RSM
EAX=00000001 EBX=80000b58 ECX=00000000 EDX=00000cfc
ESI=000e857d EDI=0003802d EBP=80000070 ESP=00006ee0
EIP=000ef7b2 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fce38 00000037
IDT=     000fdcf0 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=ffffff9c CCO=EFLAGS 
EFER=0000000000000000
     0: v=21 e=0000 i=0 cpl=0 IP=0008:001007a0 pc=001007a0 SP=0010:001fffd4 EAX=00102100
EAX=00102100 EBX=00009500 ECX=000b8000 EDX=000003d5
ESI=00000000 EDI=00105000 EBP=001ffff0 ESP=001fffd4
EIP=001007a0 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00102940 00000027
IDT=     00102980 000007ff
CR0=80000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000004 CCD=001fffd4 CCO=SUBL   
EFER=0000000000000000
     1: v=21 e=0000 i=0 cpl=0 IP=0008:001007a0 pc=001007a0 SP=0010:001fffd4 EAX=00102100
EAX=00102100 EBX=00009500 ECX=000b8000 EDX=000003d5
ESI=00000000 EDI=00105000 EBP=001ffff0 ESP=001fffd4
EIP=001007a0 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00102940 00000027
IDT=     00102980 000007ff
CR0=80000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000004 CCD=001fffc8 CCO=EFLAGS 
EFER=0000000000000000
     2: v=21 e=0000 i=0 cpl=0 IP=0008:001007a0 pc=001007a0 SP=0010:001fffd4 EAX=00102100
EAX=00102100 EBX=00009500 ECX=000b8000 EDX=000003d5
ESI=00000000 EDI=00105000 EBP=001ffff0 ESP=001fffd4
EIP=001007a0 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00102940 00000027
IDT=     00102980 000007ff
CR0=80000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000004 CCD=001fffc8 CCO=EFLAGS 
EFER=0000000000000000
     3: v=21 e=0000 i=0 cpl=0 IP=0008:001007a0 pc=001007a0 SP=0010:001fffd4 EAX=00102100
EAX=00102100 EBX=00009500 ECX=000b8000 EDX=000003d5
ESI=00000000 EDI=00105000 EBP=001ffff0 ESP=001fffd4
EIP=001007a0 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00102940 00000027
IDT=     00102980 000007ff
CR0=80000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000004 CCD=001fffc8 CCO=EFLAGS 
EFER=0000000000000000
     4: v=21 e=0000 i=0 cpl=0 IP=0008:001007a0 pc=001007a0 SP=0010:001fffd4 EAX=00102100
EAX=00102100 EBX=00009500 ECX=000b8000 EDX=000003d5
ESI=00000000 EDI=00105000 EBP=001ffff0 ESP=001fffd4
EIP=001007a0 EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00102940 00000027
IDT=     00102980 000007ff
CR0=80000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000004 CCD=001fffc8 CCO=EFLAGS 
EFER=0000000000000000
     5: v=20 e=0000 i=0 cpl=0 IP=0008:00101aff pc=00101aff SP=0010:001fff98 EAX=00000004

...

  2125: v=20 e=0000 i=0 cpl=0 IP=0008:00100e2d pc=00100e2d SP=0010:001fffb8 EAX=00000000
EAX=00000000 EBX=00009500 ECX=000b8000 EDX=00000000
ESI=00000000 EDI=00105000 EBP=001fffc0 ESP=001fffb8
EIP=00100e2d EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00102940 00000027
IDT=     00102980 000007ff
CR0=80000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000044 CCD=00000000 CCO=EFLAGS 
EFER=0000000000000000
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: Jidder am 09. August 2014, 19:28
Meinst du die Menge der Interrupts? Der Timer tickt ca. 18x pro Sekunde. Nach rund 2 Minuten sollte man da also über 2000 Interrupts erwarten.
Titel: Re: [All In One]-Question lolxdfly
Beitrag von: lolxdfly am 09. August 2014, 20:19
Ja.
Habe jetzt den Timer schon etwas entschäft  :-)