Lowlevel

Lowlevel => Softwareentwicklung => Thema gestartet von: sebi2020 am 14. February 2010, 11:51

Titel: Speicherverwaltung - Adressenberechnung
Beitrag von: sebi2020 am 14. February 2010, 11:51
Hey,
ich bin gerade dabei die Speicehrverwaltung zu schreiben und hab jetzt ein mathematisches Problem. Eine physische Adresse berechne ich so:
(i * 32 + i2) * 4096 = PhysAddr
i steht in dem Fall für den 32Bit Eintrags des Arrays und i2 für die Bitposition in dem Eintrag.
Das klappt auch so ganz gut. Durch umstellen erhalte ich für i2
i2 = PhysAddr/4096 - (i * 32)
Das klappt auchganz gut allerdings nur wenn ich von pmm_alloc (genau 4k Adressen) damit auflöse, also 0x1000, 0x2000, 0x3000 usw...
Was mach ich wen ich jetzt allerdings ne Adresse habe wie 0x1021 oder so. Wie berechne ich dafür die Bitposition in der Bitmap und den entsprechenden Eintrag im Array?

mfg Sebi
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: XanClic am 14. February 2010, 12:28
Du kannst ja nur 4k allokieren. Also musst du die Adresse halt auf 4096 abrunden (was mit Bitoperationen ja kein Problem sein sollte).
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: sebi2020 am 14. February 2010, 14:17
okay, ich habs jetzt so versucht:
typedef unsigned long* uptr32_t;
#define I_BITMAP_ADDR (byte_addr / 131072)
#define I2_BITMAP_ADDR byte_addr/4096 - (I_BITMAP_ADDR * 32)
void pmm_mark_used(uptr32_t byte_addr)
{
byte_addr &= (uptr32_t) ~0xF;
uint32_t i = I_BITMAP_ADDR;
uint32_t i2 = I2_BITMAP_ADDR;
pmm_bitmap[i] &= ~(0x1 << i2);
return;
}
Jetzt bekomm ich vom Kompiler folgendes:
src/modules/pmm.c: In function 'pmm_mark_used':
src/modules/pmm.c:57: error: invalid operands to binary & (have 'uptr32_t' and 'long unsigned int *')
src/modules/pmm.c:58: error: invalid operands to binary / (have 'uptr32_t' and 'int')
src/modules/pmm.c:59: error: invalid operands to binary / (have 'uptr32_t' and 'int')
src/modules/pmm.c:59: error: invalid operands to binary / (have 'uptr32_t' and 'int')

Wieso invalid, was ist daran nicht richtig?

mfg Sebi
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: XanClic am 14. February 2010, 14:25
Du kannst keinen Pointer ohne Cast mit einem Integer verknüpfen. Und uptr32_t ist ein Pointer, währen byte_addr, i, i2 und pmm_bitmap Integer sind.

Außerdem willst du eher byte_addr &= ~0xFFF; statt byte_addr &= ~0xF;, damit es auf 4096 und nicht auf 16 aligned wird.
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: sebi2020 am 14. February 2010, 14:42
Du kannst keinen Pointer ohne Cast mit einem Integer verknüpfen. Und uptr32_t ist ein Pointer, währen byte_addr, i, i2 und pmm_bitmap Integer sind.

Außerdem willst du eher byte_addr &= ~0xFFF; statt byte_addr &= ~0xF;, damit es auf 4096 und nicht auf 16 aligned wird.
void pmm_mark_used(uptr32_t byte_addr)
{
byte_addr &= (uptr32_t) ~0xF;

byte_addr ist eben kein integer, zumindest wenn c beachtet das byte-addr den typ uptr32_t hat, wies im parameter drin steht.
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: bluecode am 14. February 2010, 14:44
Man kann trotzdem keine Adressen bitweise traktieren. Das geht halt nur mit Integern (und bool).
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: XanClic am 14. February 2010, 14:49
byte_addr ist eben kein integer, zumindest wenn c beachtet das byte-addr den typ uptr32_t hat, wies im parameter drin steht.
Ah, stimmt, tschuldige. Dann siehe eben bluecode. :wink:
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: sebi2020 am 14. February 2010, 15:16
okay, aber wie arbeite ich dann damit, normalerweise soll pmm_free nen pointer übergeben werden, bzw. pmm_mark_used.
wenn ich jetzt mit nem pointer nicht arbeiten kann was mach ich dann? casten kann ichs nicht, weil er mir dann sagt, dass ich nen cast von nem pointer zu integer verschiedener größe mache obwohl ich uint64_t var = (uint64_t) addrptr hab. wie mach ich dass, ich hab ja noch so meine wissenlücken was c betrifft.
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: bluecode am 14. February 2010, 15:19
Dann nimm den Integertyp mit der richtigen Größe, also einen mit 32bit (zumindest wenn du im 32bit pmode bist), sonst ist doch klar, dass C beim casten von diesem Integer zum Pointer meckert, der Integer ist schließlich zu groß und es könnte was vorloren gehen. Wenn der Integer zu klein ist meckert C beim Cast andersrum, aus genau dem gleichen Grund.
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: sebi2020 am 14. February 2010, 15:21
Dann nimm den Integertyp mit der richtigen Größe, also einen mit 32bit (zumindest wenn du im 32bit pmode bist), sonst ist doch klar, dass C beim casten von diesem Integer zum Pointer meckert, der Integer ist schließlich zu groß und es könnte was vorloren gehen. Wenn der Integer zu klein ist meckert C beim Cast andersrum, aus genau dem gleichen Grund.
// uint64_t* addrptr = 0x1100000; - Beispiel
uint64_t var = (uint64_t) addrptr;
wo ist da was zu groß? (Ich nehme übrigens ein 64bit pointer weil die multibootstruktur dass so vorschreibt.
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: bluecode am 14. February 2010, 15:22
Der Pointer hat 32Bit und der 64Bit Integer 64Bit oder meinst du sizeof(T*) passt sich irgendwie an sizeof(T) an? :-D
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: sebi2020 am 14. February 2010, 15:23
Der Pointer hat 32Bit und der 64Bit Integer 64Bit.
uint64_t* addrptr = 0x120000;
uint64_t* == 32bit???!!!
unsigned long long* == unsigned long??!!
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: bluecode am 14. February 2010, 15:24
Wenn du mir nicht glaubst, dann lass dir sizeof(uint64_t*) ausgeben. Wie gesagt, sizeof(T*) = sizeof(void*) und hat nichts mit sizeof(T) zu tun.
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: sebi2020 am 14. February 2010, 15:26
Wenn du mir nicht glaubst, dann lass dir sizeof(uint64_t*) ausgeben.
ich weiß es ja nciht, aber wieso ist ein unsigend long long*= unsigend long groß, ich versteh die logik darin nich? wie groß ist dann ein unsigned long* ? unsigned long* = unsigned short?
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: bluecode am 14. February 2010, 15:27
Die Logik ist, dass ein Zeiger (egal auf was) immer gleich groß ist. Den Zeiger interessiert ja nicht, was für ein Objekt sich dahinter verbirgt. Die Zeigergröße hängt nur von der Größe des virtuellen Adressraums ab.
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: sebi2020 am 14. February 2010, 15:30
Die Logik ist, dass ein Zeiger (egal auf was) immer gleich groß ist. Den Zeiger interessiert ja nicht, was für ein Objekt sich dahinter verbirgt. Die Zeigergröße hängt nur von der Größe des virtuellen Adressraums ab.
also heißt im pmmode = 32bit, im real-mode = 16bit und im long-mode = 64bit?
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: bluecode am 14. February 2010, 15:32
Ja.
Titel: Re: Speicherverwaltung - Adressenberechnung
Beitrag von: sebi2020 am 14. February 2010, 15:35
ah und schon geht mir ein licht auf, danke! ^^