Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - RW2003

Seiten: [1]
1
Lowlevel-Coding / Antw:Probleme mit aarch64
« am: 16. August 2021, 15:50 »
is ne Weile her, aber danke für die Antwort  :-D
immerhin einer der seinen Senf dazugeben will  :-D

Ich habe nur eine Datei: start.S, welche dann start.o erzeugt; also keine weitere start.c oder so.
Die Objektdateien werden mittels:
SRCS = start.S init.c
OBJS = $(addsuffix .o,$(basename $(SRCS)))

gesammelt.

Das ganze "Projekt" hatte ich erstmal auf Eis gelegt, da ich eifnach nciht weiter kam....
Also wenn du denn möchtest, kannst du den Code gerne durchgehen :-D
Ansonsten bleibt das Projekt erstmal auf Eis.

2
Lowlevel-Coding / Antw:Probleme mit aarch64
« am: 13. July 2021, 17:12 »
ich hab nun etwa mit gdb rum probiert... und, es verwirrt mich noch mehr..
ich hab immerhin geschafft dass die Schleife nun funktioniert (auch ohne i < 5).
Hello World wird also ganz ausgegeben. yeay.

Wenn man sich die Zeile i = i + 1; mit gdb anguckt bzw einen Breakpoint setzt, bekomm ich folgendes:

Breakpoint 4, print (s=0x2008 "Hello World\n") at init.c:16
16
(gdb) x/gx i
0x3 <KERNEL_START+3>:    0x00000d1400000e14
(gdb) c
Continuing.

Breakpoint 4, print (s=0x2008 "Hello World\n") at init.c:16
16
(gdb) x/gx i
0x4 <KERNEL_START+4>:    0x1400000d1400000e
(gdb) c
Continuing.

Breakpoint 4, print (s=0x2008 "Hello World\n") at init.c:16
16
(gdb) x/gx i
0x5 <KERNEL_START+5>:    0x0c1400000d140000
(gdb) c
Continuing.

Breakpoint 4, print (s=0x2008 "Hello World\n") at init.c:16
16
(gdb) x/gx i
0x6 <KERNEL_START+6>:    0x000c1400000d1400
(gdb) c
Continuing.


Das Format sollte doch Speicheradresse: Wert sein, oder nciht?
Wieso verändert sich denn beides beim inkrementieren?

3
Lowlevel-Coding / Antw:Probleme mit aarch64
« am: 12. July 2021, 15:30 »
da ich nun gdb an der Reihe ist, hab ich gcc mit dem Argument -O0 versucht.
Dabei komm ich in eine Endlosschleife mit der Ausgabe von ganz vielen Zeilen von 0 0  .
mit -O1 udn -O2 bekomm ich lediglich ein A ausgegeben.

Ich finde es sehr seltsam dass es nur mit -O3 läuft, und selbst damit hat er ja offenbar Probleme ._.
4
Lowlevel-Coding / Antw:Probleme mit aarch64
« am: 12. July 2021, 14:46 »
danke für die Antwort.
Mein Makefile hab ich geändert  :-D
anstatt short int etwas anderes zu versuchen, hab ich schon versucht.
Tatsächlich macht es jetzt aber einen Unterschied.

Bei short oder unsigned short und unsigned int bekomme ich folgende Ausgabe:
A

H00  1
 11  2
 22  3
 33  4
 44  5
U00  1
 11  2
 22  3
 33  4
 44  5

Mit int, long, long long oder unsigned long und unsigned long long folgendes:
A

H00He1
e11el2
l22ll3
l33lo4
o44o 5
 55 W6
W66  7
U00U 1
 11  2
 22  3
 33  4
 44  5


Wenn man das i < 5 aus der While-Schleife entfernt gibt es in allen Fällen nur den ersten Buchstaben aus, und verlässt dann die Schleife...

ich werde es mal mit dem Debugger versuchen ._.

Das mit dem .global versteh ich; was ich nciht verstehe, ist die Verwendung davon bzw. wieso dies nciht so funktiniert wie ich das erwarten würde...
wenn ich in start.S folgendes schreibe:
.global _test
_test:
...
bekomme ich beim Linken folgenden Fehler:
aarch64-linux-gnu-ld: start.o: in function `_test':
(.text+0x3c): multiple definition of `_test'; start.o:(.text+0x3c): first defined here
demnach hab ich es ohne _ versucht.. sowohl:
.global test
_test:
als auch
.global _test
test:

scheint der linker auch erstmal so hinzunehmen.
Möchte ich nun in C darauf zugreifen:
extern void _test();
...
_test();

bekomme ich nur:
aarch64-linux-gnu-ld: init.o: in function `init':
init.c:(.text+0x194): undefined reference to `_test'
das gleiche auch wenn ich es als test(); ohne _ deklariere.

kannst du mir erklären wie ich das .global konkret einsetzen kann?
Bei meinem vorherigen Projekt ging es mit:
.global _name
_name:
...

Was ist denn die korrekte Syntax für .global?

5
Lowlevel-Coding / Probleme mit aarch64
« am: 11. July 2021, 12:17 »
Hallo allerseits.
Ich wollte mich mal etwas an arm versuchen und habe mich an das ARM-OS-Dev Tutorial aus dem Wiki gehalten.
Naja, mit ein paar Änderungen, da ich nciht für 32-bit sondern für armv8 bzw. aarch64 entwickeln möchte.

Nun ja, der kernel wird kompiliert und von qemu gestartet. Ausgaben auf den Bildschirm bzw. seriellen Schnittstelle funktionieren halbwegs.
Es scheint Probleme mit den Variablen bzw. Speicherzugriffen zu geben...

Einzelne Zeichen auszugeben funktioniert.
Wenn ich das aber in einer Schleife machen möchte, dann tut er sich mit der Zählervariablen schwer...
Im ersten Durchlauf funktioniert es. Dann wird die Schleife aber nciht mehr fortgeführt, weil s == 0 sei...
irgendwie verkackt er hier den Zugriff über die Variable i.
Wenn man die Zeichen per Zahl, also s[1], s[2], etc. ausgibt dann bekommt man auch das Zeichen und kein '\0'.
Gleiches gilt auch, wenn man den Wert in der Schleife auf einen konkreten Wert setzt: z.b. i = 4;.
Das Inkrementieren von i hingegen scheint einfach nciht zu funktionieren. Danach bekommt er aus s == '\0' raus und beendet die Schleife.

Vllt. könnt ihr mir helfen und mir meine Fehler aufzeigen; und mir sagen ob ich die Adresse für den Stack richtig zugewiesen habe, oder dort vllt. das Problem liegt...


Da man hier leider keine zip archive hochladen kann, gibt es hier meine Dateien als Text.

Start.S
/* Init ist eine Funktion aus init.c */
.extern init
.org 0x0

/* Hier befinden sich die Einsprungspunkte für Exceptions, der erste wird beim
   Reset aufgerufen. Da die Einsprungspunkte nur vier Byte voneinander entfernt
   sind, bleibt jeweils nur Platz für einen Opcode – und damit springen wir
   woanders hin. */
b       _start
/* Hier folgen jetzt die Einsprungspunkte für Undefined Instruction, SWI,
   Prefetch Abort, Data Abort, eine bisher reservierte Exception, IRQ und FIQ.
   Da all diese Exceptions noch nicht behandelt werden können, legen wir dort
   einfach Endlosschleifen hin. */
b       end
b       end
b       end
b       end
b       end
b       end
b       end

.global start
_start:
/* Stack initialisieren  */
mov x0, #kernel_stack
mov     sp, x0


sub  sp, sp, #8
mov  x0, #17
str  x0, [sp]

/* C-Code aufrufen */
bl      init

/* Falls wir jemals aus init zurueckkommen sollten, gehen wir in eine
   Endlosschleife */
b       end

end:
ldr x0, =0x84000008
hvc #0


/* Enthält die Adresse des Kernelstacks */
kernel_stack_addr:
.8byte kernel_stack

/* 8 kB Stack für den Kernel. Das Label steht hinter dem freien Speicher,
   weil der Stack nach unten wächst */
.section .bss
.space 8192
kernel_stack:


init.c
// Data register of first UART (PL011)
volatile unsigned int * const UART0_DR = (unsigned int *) 0x09000000;


// Stop guest so Qemu terminates
void system_off() {
__asm__("ldr x0, =0x84000008;hvc #0;");
}


void print(const char *s) {
    short int i = 0;
    while(s[i] != '\0' || i <5){
        //*UART0_DR = 48 + i;

        *UART0_DR = s[i];

        *UART0_DR = 48 + i;
        *UART0_DR = 48 + i;
       
        *UART0_DR = s[i];
        *UART0_DR = s[i + 1];

        i = i + 1;

        *UART0_DR = 48 + i;
        *UART0_DR = '\n';
    }
}

void init(int value) {
   const char *hw = "Hello World!\n";
   char text[25];

   *UART0_DR = (48 + value);
   *UART0_DR = '\n';
   *UART0_DR = '\n';

   print(hw);
   //print(text);
   print("U");

   system_off();
}


makefile
SRCS = $(shell find -name '*.[cS]')
OBJS = $(addsuffix .o,$(basename $(SRCS)))

CC = aarch64-linux-gnu-gcc
LD = aarch64-linux-gnu-ld

ASFLAGS = -march=armv8-a
CFLAGS = -march=armv8-a -O3 -ffreestanding -nostartfiles -nostdinc -nodefaultlibs -Wall -Wextra -fno-stack-protector
LDFLAGS = -e 0x00000000 -T link.ld

kernel: $(OBJS)
$(LD) $(LDFLAGS) -o $@ $^

%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^

%.o: %.S
$(CC) $(ASFLAGS) -c -o $@ $^

clean:
rm $(OBJS)

.PHONY: clean


link.ld
/* Wir nehmen einen ARMv8-Prozessor an */
OUTPUT_ARCH("aarch64")
/* Diese Datei muss im Speicher nach 0x00000000 geladen werden */
STARTUP(start.o)

/*
 * Hier wird festgelegt, in welcher Reihenfolge welche Sektionen in die Binary
 * geschrieben werden sollen
 */
SECTIONS
{
    /* Die Standardsektionen einfach hintereinander weg ab 0x00000000 einbinden. */
    .text 0x00000000 : AT(0x00000000) {
        *(.text)
    }
    .data ALIGN(4096) : {
        *(.data)
    }
    .rodata ALIGN(4096) : {
        *(.rodata)
    }
    .bss ALIGN(4096) : {
        *(.bss)
    }
}


Aso.. wenn ich hier schon dabei bin zu posten..
vllt. kann mir jemand das .global in Assembler erklären.
Ich wollte die system_off(); funktion in C benutzen und hatte sie davor in der Assemblerdatei wie folgt stehen:
.global _system_off
_system_off:
ldr x0, =0x84000008
hvc #0
In C hab ich das als extern void _system_off(); deklariert.
Damit konnte der Linker aber nichts anfangen, und warf mir doppelte Definierung vor.
Deshalb hab ich den Code dann in C kopiert...
Wie hätte ich das definieren müssen?


Ich hoffe ihr könnt mir dabei helfen  :-)

Seiten: [1]

Einloggen