Introduction to ARM64 architecture (Chapter 3 experiment)

Introduction to ARM64 architecture

1. Install Raspberry Pi OS on raspberry pie

(1) Get installation files
Download the latest raspberry OS. Domestic partners can download it from Tsinghua open source software site.
https://mirrors.tuna.tsinghua.edu.cn/raspberry-pi-os-images/raspios_arm64/images/raspios_arm64-20
(2) Burning installation files (similar to raspberry pie OpenEuler installation)
If complete is displayed, the burning is successful
Modify the config.txt configuration file in the boot partition of the MircoSD card and add two lines to this file.  
uart_2ndstage=1 
enable_uart=1

Then plug the boot U disk into the raspberry pie and connect the power to use it.

The default user name of raspberry pie OS is pi and the password is raspberry

  Note: many students here may have a Network Error problem when logging in on Putty. At this time, just create a text file under the boot partition, name it ssh, and delete the suffix. Then a dialog box will appear. Just click Yes and enter the user's password to enter our raspberry pie interface~

(3) Configure wifi on raspberry pie
(4) Update the package.
We'd better use the system wide update package, which will automatically update the SPI BootRom firmware
sudo apt update
sudo apt full-upgrade 
sudo reboot

  At this point, Raspberry Pi OS installation is complete.

 

2. Assembly language practice - find the maximum number

  1. Experimental purpose

Understand and be familiar with ARM64 assembly language through this experiment

2. Experimental requirements

ARM64 assembly language is used to realize the following functions: find the maximum number in a given set of numbers. Program available
GCC (Aarch64 version) tool to compile, and can be implemented on raspberry Linux system or QEMU + ARM64
Run on the inspection platform. (I conducted this experiment under the raspberry pie Linux system)
3. Experiment code link
.section .data
 
data_items:
.long 3, 68, 12, 37, 198, 10, 1, 4, 26, 255, 11, 22, 33, 44, 0
 
.section .text
 
.globl _start
 
_start:
        movl    $0, %edi              
        movl    data_items(,%edi,4), %eax  
        movl    %eax, %ebx               
start_loop:
        cmpl    $0, %eax
        je      loop_exit
        incl    %edi
        movl    data_items(,%edi,4), %eax
        cmpl    %ebx, %eax
        jle     start_loop
        movl    %eax, %ebx
        jmp     start_loop
loop_exit:
        movl    $1, %eax
        int     $0x80
4. Compiling and running process

 

  Note: enter 15 numbers, the maximum number is 255, which is consistent with the final compilation result and runs correctly.

5. Commissioning
We can use gdb to step through the assembler:
(1) Start gdb to debug the test program

In_ Set a breakpoint in the start function and enter the "r" command to run the test program

Then you can step through the test program. Enter "s" for single step debugging.

You can use the "info reg" command to view the value of the register. For example, check the values of the $eax, $edi, $ebx registers

 

3. Assembly language practice - calling assembly functions through C language

1. Experimental purpose

  Through this experiment, understand and be familiar with how to call assembly functions in C language.

  2. Experimental platform

It operates under the newly installed raspberry pie OpenEuler system

3. Experimental code

compare.S

.section .text
.globl compare_data
compare_data:
cmp x0, x1
csel x0, x0, x1, hi
ret

main.c

#include <stdio.h>
extern int compare_data(int a, int b);
int main()
{ 
int val;
val = compare_data(5, 6);
printf("big data: %d\n", val);
}

makefile

main:main.o compare.o
    gcc -o main main.o compare.o
main.o:main.c
    gcc -c main.c
compare.o:compare.S
    gcc -c compare.S
clean:
    rm main main.o compare.o

4. Compile and run

 

4. Assembly language practice - calling C functions through assembly language

1. Experimental purpose

Through this experiment, understand and be familiar with how to call C functions in assembly language.
2. Experimental platform
It operates under the newly installed raspberry pie OpenEuler system
3. Experimental code
compare.c
int compare_data(int a, int b)
{ 
return (a >= b) ? a : b;
}

main.S

.section .data
.align 3
print_data:
.string "big data: %d\n"
.section .text
.globl main
main:
stp x29, x30, [sp, -16]!
mov x0, #6
mov x1, #5
bl compare_data
mov x1, x0
ldr x0, =print_data
bl printf
ldp x29, x30, [sp], 16
ret

makefile

main:main.o compare.o
    gcc -o main main.o compare.o
main.o:main.S
    gcc -c main.S
compare.o:compare.c
    gcc -c compare.c
clean:
    rm main main.o compare.o

4. Compile and run

 

5. Assembly language practice - GCC inline assembly

1. Experimental purpose

Through this experiment, understand and be familiar with the use of GCC inline assembly.
2. Experimental platform
It operates under the newly installed raspberry pie OpenEuler system
3. Experimental code
#include <stdio.h>
static int compare_data(int a, int b)
{ 
int val;
asm volatile (
 "cmp %1, %2\n"
 "csel %0, %1, %2, hi\n"
 : "+r" (val)
 : "r" (a), "r" (b)
 : "memory");
return val;
} 
int main()
{ 
int val;
val = compare_data(5, 6);
printf("big data: %d\n", val);
val = compare_data(6, 4);
printf("big data: %d\n", val);
}

5. Compile and run

 

6. Write a bare metal program on raspberry pie (reference link: https://www.lmlphp.com/user/13377/article/item/433984/)

1. Experimental purpose

(1) Through this experiment, understand and be familiar with ARM64 assembly language.
(2) Understand and be familiar with how to debug bare metal programs using QEMU and GDB.
2. Experimental requirements
(1) Write a bare metal program and run it in QEMU virtual machine to output "hello world!" string.
(2) Run the compiled bare metal program on raspberry pie.
3. Experimental code
hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
 
MODULE_LICENSE("Dual BSD/GPL");
 
static int hello_init(void)
{
    printk(KERN_ALERT"Hello, world\n");
    return 0;
}
 
static void hello_exit(void)
{
    printk(KERN_ALERT"Goodbye, cruel world\n");
}
 
module_init(hello_init);
module_exit(hello_exit);

makefile

ifneq ($(KERNELRELEASE),)

obj-m := hello.o

else
    
KDIR := /home/hcx/work/boards/RPi/kernel/linux-rpi-3.6.y
all:
    make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=/home/hcx/work/boards/RPi/kernel/RpiTools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-

clean:
    rm -f *.ko *.o *.mod.o *.mod.c *.symvers  modul*

endif
4. Compile and run
 

Posted by wizkid on Sun, 31 Oct 2021 00:57:00 -0700