marco123
Goto Top

LPI Aufgabe - 32 und 64 Bit Programmierung

Die Nutzung des Systemaufrufs
Um den neu definierten Systemaufruf zu nutzen, kann er in einem beliebigen
Programm mit dem Prototypen aufgerufen werden, z. B. in einem Programm
mit dem Namen gauss.c:
Für 32-Bit Prozessoren:

# include <stdio.h>
# include <linux/unistd.h>
# include <errno.h>
# define __NR_prosys 320
_syscall0(long, prosys);
main ()
{
printf(„Berechnung nach der Gauß-Formel \n“);
printf(„Die Summe ist: %d \n“, prosys() );
}

INFORMATION
Kompilieren Sie dieses Programm und führen Sie es aus; als Meldung
müsste auf 32-Bit-Systemen ausgegeben werden:

Berechnung nach der Gauß-Formel
Die Summe ist: 55

AUFGABE:
Für Prozessoren mit 64-Bit Kern ist auch dann, wenn kein 64-Bit Betriebssystem
genutzt wird, die obige Form von
_syscall0(long, prosys);
sowie
printf(„Die Summe ist: %d \n“, prosys() );
nicht möglich. Bei 64-Bit Prozessoren ist der obige Programmcode unter
Berücksichtigung der Funktion syscall() zu ändern.

Nach 3 Tagen googeln, hab ich genug und ersuche das Forum nach Rat.
Meine gefundenen Erkentnisse lauten wie folgt: anstatt "long" sollte man long long nehmen ?
und syscallX() -> X bezeichnet die anzahl der zu übergebenden Parameter.

Aber damit hab ich das Rätzel leider noch nicht gelöst.
Bin erst am beginn meiner C Programmierung unter Linux. Java NPEH aber C :/

vielen Dank

Content-ID: 131876

Url: https://administrator.de/contentid/131876

Ausgedruckt am: 05.11.2024 um 23:11 Uhr

Tommy70
Tommy70 17.12.2009 um 12:38:07 Uhr
Goto Top
Hallo,

welches Rätsel? Oder habe ich etwas übersehen...
Und ja, es gibt die Möglichkeit Code mittels eines Codeblocks zu formatieren. Dann wäre er eventuell besser lesbar. face-wink
Marco123
Marco123 17.12.2009 um 12:54:22 Uhr
Goto Top
Für Prozessoren mit 64-Bit Kern ist auch dann, wenn kein 64-Bit Betriebssystem
genutzt wird, die obige Form von
_syscall0(long, prosys);
sowie
printf(„Die Summe ist: %d \n“, prosys() );
nicht möglich. Bei 64-Bit Prozessoren ist der obige Programmcode unter
Berücksichtigung der Funktion syscall() zu ändern.
6890
6890 17.12.2009 um 15:10:55 Uhr
Goto Top
Hallo,

abgesehen das ich deine Frage nicht verstehe, würde dir wahrscheinlich ein Blick in manpages von syscall(2) und _syscall(2) helfen:

_syscall(2):
NOTES
Starting around kernel 2.6.18, the _syscall macros were removed from header files supplied to user space. Use syscall(2) instead. (Some architectures, notably ia64, never provided the _syscall
macros; on those architectures, syscall(2) was always required.)

Wenn ich es richtig verstehe, musst du also nur syscall() anstatt _syscall() verwenden:

# include <stdio.h>
# include <linux/unistd.h>
# include <errno.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
# define __NR_prosys 320

main ()
{
long gaus = syscall( SYS_prosys ) /* ich schaetze mal dein syscall heisst so?! dann muesste irgendwo noch ein #define SYS_prosys __NR_prosys - oder du nimmst direkt syscall(__NR_prosys) */
printf(„Berechnung nach der Gauß-Formel \n“);
printf(„Die Summe ist: %d \n“, gaus );
}

Hoffe ich habe dich korrekt verstanden. BTW was hat das ganze mit LPI zu tun?

MfG
Marco123
Marco123 17.12.2009 um 15:49:38 Uhr
Goto Top
Hey, danke erstmal

Die Aufgabe heisst: ändern Sie den 32 bit code in 64bit code um unter berücksichtigung der funktion syscall.

Das ist eine Übungsaufgabe vom Studium für LPI.
-> Da der Linux Kernel in C geschrieben ist, müssen wir die Basics dafür erlernen, deshalb hat es was mit lpi zu tuen :- )

System Calls selber schreiben können ;) @ Linux

jo muss in der System Call Tabelle den Eintrag noch hinzufügen und in ner C Datei noch die Funktion erstellen + prototyp.

Aber vielen dank schonmal, wieso sagt mir mein "man" nichts zu syscall oO in Section 2.

moep moep

dankeschööön
6890
6890 17.12.2009 um 15:58:13 Uhr
Goto Top
Hallo,

omfg naja syscalls selber schreiben ist imho schon höherer bis ganz hohe schule und hat nix mit LPI 1/2 zu tun.
Auf die zweite Frage kann ich nur sagen:
apt-get install manpages-dev

MfG
Marco123
Marco123 17.12.2009 um 16:12:36 Uhr
Goto Top
Hey,
wieso omfg ?

Finde als Linux Administrator gehört das Wissen über die Funktionsweise des Kernels dazu.....
Sowie auch Syscalls.

Für die LPIC ist es villeicht zu hoch gegriffen, aber das Wissen rund um Kernel und C Programmierung finde ich gut, dass es angeschnitten wird.

Oder wieso findest du das nicht gut ?


greetz
6890
6890 17.12.2009 um 16:22:06 Uhr
Goto Top
Heho,

nein du hast mich da falsch verstanden. Ich finde es natürlich auch gut. Es macht aber IMHO keinen sinn gleich mit dem Kernel anzufangen ohne das dazugehörige Grundlagenwissen zu erlangen.
Als KFZ-Mechaniker fängst du ja auch nicht an den Motor auseinander zu nehmen, weißte?

MfG
Oimel1980
Oimel1980 19.12.2009 um 00:50:59 Uhr
Goto Top
@Marco123 mich würde interessieren was bei dir rauskommt "55" ???

mfg
Marco123
Marco123 03.01.2010 um 17:52:20 Uhr
Goto Top
hey, ja es kommt 55 heraus

Ein Kommentar muss mehr als 30 Zeichen enthalten! Bitte geben Sie einen aussagefähigen Kommentar ein.
Oimel1980
Oimel1980 03.01.2010 um 20:02:27 Uhr
Goto Top
Hi Marco, bei mir kommt nun auch 55 raus! Aber die Aufgabe

Sie haben sich in einem Programm dieses Lehrbriefs mit der Gauß’schen-Formel beschäftigt. Erzeugen Sie nun einen Systemaufruf mit der Gauß-Formel, an dem bei seinem Aufruf ein Parameter überreicht werden kann. Sodann schreiben Sie ein kleines Shell-Skript (entweder für 32- oder 64-Bit Prozessoren), welches den Systemaufruf
nutzt und als Parameter eine Zahl n weitergibt, der den letzten Wert angibt, der innerhalb der Gauß-Berechnung aufsummiert werden soll: ergebnis = ergebnis + n;
Als n soll maximal der Wert 70.000 gewählt werden können.

Hinweis: Verwenden Sie bei 32-Bit Prozessoren folgenden Prototypen:
#define _syscall1(type_sys, name_sys, type_param, param)

wie und wo bau ich das ein?! Muss dazu prosys.c oder gauss.c abgeändert werden? Die Übergabe eines Wertes ist von der Shell ist dabei eher das kleiner Problem!

mfg
Oimel
Marco123
Marco123 03.01.2010 um 20:08:33 Uhr
Goto Top
Hey,

hatte mir das kurz in Java gebaut, die for schleife mit der hochzählung -> bezug auf 55, Korrekt.

Ich hänge auch noch an der ### Aufgabe, finde die ein wenig doof gestellt.
Ich schaue jetzt noch 2 filme, dann mache ich mich ebenfalls an die Aufgabe.

also ich habe es bis jetzt erstmal so stehen:

statt void habe ich -> long n -> damit ich einen Parameter abgreifen kann.
prosys.c:

#include <linux/linkage.h>

asmlinkage long sys_prosys(long n) {
long ergebnis = 0;
int i;
for (i=1;i <=10; i++) {
ergebnis = +=i;
}
return ergebnis;
}


// Film geht los bis gleich :- )
Marco123
Marco123 06.01.2010 um 13:59:03 Uhr
Goto Top
So Hey,

sry hat länger gedauert, musste noch was anderes machen :/

erstmal der code meines Systemaufrufes prosys.c:

[CODE]

#include <linux/linkage.h>


asmlinkage long sys_prosys(long n) {

long ergebnis=0;
int i;

for(i=1; i<=10;i++) {
ergebnis +=i;
}
ergebnis = ergebnis + n;

return ergebnis;
}


[/CODE]

meine frage ist nun:
in der Aufgabe steht:
erstellen Sie nun ein Script, welches den Systemaufruf nutzt.

Würdest du erst noch gauss.c schreiben um von dort den Systemcall zu nutzen, oder kennst du eine Möglichkeit direkt aus nem Shellscript nen Systemaufruf zu nutzen ?

danke


PS: ich habe die Gaussformel direkt in den Systemaufruf implementiert.

gruß
90476
90476 12.05.2010 um 11:25:31 Uhr
Goto Top
Hallo zusammen,

ist das Ding gelöst ? Mich würde die Lösung ineteressieren, da ich am gleichen Problem hänge.

Grüße
Marco123
Marco123 12.05.2010 um 20:12:14 Uhr
Goto Top
25 € gibts die Musterlösung :- )

0 € = les Dir oben meine Antwort durch und versuche mit deinem Wissen was du gelernt hast dies zu vollenden.

Wieso gebe ich nicht gleich die antwort? da ich sie nicht bekam und auch froh darum bin! sonst hätte ich es nicht gerafft wie es geht. face-smile
90476
90476 12.05.2010 um 21:19:21 Uhr
Goto Top
Ich kriegs noch nicht mal gebacken meinen sch...kernel zu kompilieren. undefined reference to sys_prosys. ###dreck ... sorry.
Ist aber so. Ich sitze jetzt 3 Wochen an diesem Müll rum und schmeiße den Mist gleich ganz weg. Das ist der Punkt wo ich echt am verzweifeln bin.
Ich bin nicht zu blöde. Habe schon Ubuntu, Debian 5, Gentoo versucht. Nix. Habe 2000000 Anleitungen gelesen und befolgt. Die Anleitung aus dem Lehrbief inbegriffen. Nix.
Mein Gott, das kann doch nicht so wild sein so einen ### Systemcall zu implementieren.
Wie gesagt. Ich bin fertig damit und werde das noch ein wenig probieren bis ich den Lehrgang schmeiße. Ich bin kein Programmierer und kann das einfach nicht. Ich weiß nicht wo mein Fehler liegt. Alles ist gemacht, ob unistd_32.h, ob syscalls.h ob prosys.c, das Makefile usw usw. 1000000000 mal geprüft und wiederholt. Nix.
Ich weiß ich mach es richtig. Ich habe mit Sicherheit irgendeine Miniatur-Kleinigkeit vergessen. Ich wäre um die Antwort dankbar. Dafür gäbe es sogar 30 € face-smile


Zusatz vom 18.05.2010

Habe es jetzt hinbekommen meinen Kernel zu komilieren. Macht auch schön seine "55" aus gauss.c heraus.
Leider aber nicht mit dem Programm aus dem Lehrbuch.
Bei mir funktioniert aber:

#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

#define __NR_prosys 337

int prosys ()
{
return syscall(__NR_prosys);
}
main()
{
printf("Berechnung nach der Gauss-Formel \n");
printf("Die Summe ist: %d \n", prosys());
}

ohne Probleme.