Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lab1/2 #59

Open
wants to merge 2 commits into
base: A111120
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Operating Systems Capstone 2022

## Author

| Student ID | GitHub account name | My name |
| --- | ----------- | --- |
|`A111120`| `Chang-Tiger` | `Teng-Wu Chang` |


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
43 changes: 43 additions & 0 deletions lab1/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# debug use CFLAGS='-g' ASMFLAGS='-g'

ARMGNU ?= aarch64-linux-gnu

COPS = $(CFLAGS) -Wall -nostdlib -nostartfiles -ffreestanding -Iinclude #-ggdb #-D__FS_DEBUG #-D__DEBUG #-D__DEBUG_MM #-D__DEBUG_MM_ALLOC #-D__DEBUG_MM_SCHED
ASMOPS = $(ASMFLAGS) -Iinclude

BUILD_DIR = build
SRC_DIR = src

all : kernel8.img

clean :
rm -rf $(BUILD_DIR) *.img

$(BUILD_DIR)/%_c.o: $(SRC_DIR)/%.c
mkdir -p $(@D)
$(ARMGNU)-gcc $(COPS) -MMD -c $< -o $@

$(BUILD_DIR)/%_s.o: $(SRC_DIR)/%.S
$(ARMGNU)-gcc $(ASMOPS) -MMD -c $< -o $@

C_FILES = $(wildcard $(SRC_DIR)/*.c)
ASM_FILES = $(wildcard $(SRC_DIR)/*.S)
OBJ_FILES = $(C_FILES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%_c.o)
OBJ_FILES += $(ASM_FILES:$(SRC_DIR)/%.S=$(BUILD_DIR)/%_s.o)

DEP_FILES = $(OBJ_FILES:%.o=%.d)
-include $(DEP_FILES)

kernel8.img: linker.ld $(OBJ_FILES)
$(ARMGNU)-ld -g -T linker.ld -o $(BUILD_DIR)/kernel8.elf $(OBJ_FILES)
$(ARMGNU)-objcopy -g $(BUILD_DIR)/kernel8.elf -O binary kernel8.img

run:
qemu-system-aarch64 -M raspi3b -kernel kernel8.img -display none -serial null -serial stdio

run_debug:
qemu-system-aarch64 -M raspi3b -kernel kernel8.img -display none -serial null -serial stdio -s -S

connect_raspi:
sudo screen /dev/ttyUSB0 115200

Binary file added lab1/build/kernel8.elf
Binary file not shown.
2 changes: 2 additions & 0 deletions lab1/build/main_c.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/main_c.o: src/main.c include/uart.h include/mbox.h include/shell.h \
include/string.h
Binary file added lab1/build/main_c.o
Binary file not shown.
1 change: 1 addition & 0 deletions lab1/build/mbox_c.d
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/mbox_c.o: src/mbox.c include/gpio.h
Binary file added lab1/build/mbox_c.o
Binary file not shown.
2 changes: 2 additions & 0 deletions lab1/build/shell_c.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/shell_c.o: src/shell.c include/uart.h include/string.h \
include/shell.h include/mbox.h include/system.h
Binary file added lab1/build/shell_c.o
Binary file not shown.
1 change: 1 addition & 0 deletions lab1/build/start_s.d
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/start_s.o: src/start.S
Binary file added lab1/build/start_s.o
Binary file not shown.
1 change: 1 addition & 0 deletions lab1/build/string_c.d
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/string_c.o: src/string.c include/string.h
Binary file added lab1/build/string_c.o
Binary file not shown.
2 changes: 2 additions & 0 deletions lab1/build/system_c.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/system_c.o: src/system.c include/system.h include/uart.h \
include/mbox.h
Binary file added lab1/build/system_c.o
Binary file not shown.
1 change: 1 addition & 0 deletions lab1/build/uart_c.d
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/uart_c.o: src/uart.c include/gpio.h include/uart.h
Binary file added lab1/build/uart_c.o
Binary file not shown.
25 changes: 25 additions & 0 deletions lab1/include/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef GPIO_H
#define GPIO_H

#define MMIO_BASE 0x3F000000

#define GPFSEL0 ((volatile unsigned int*)(MMIO_BASE+0x00200000))
#define GPFSEL1 ((volatile unsigned int*)(MMIO_BASE+0x00200004))
#define GPFSEL2 ((volatile unsigned int*)(MMIO_BASE+0x00200008))
#define GPFSEL3 ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
#define GPFSEL4 ((volatile unsigned int*)(MMIO_BASE+0x00200010))
#define GPFSEL5 ((volatile unsigned int*)(MMIO_BASE+0x00200014))
#define GPSET0 ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
#define GPSET1 ((volatile unsigned int*)(MMIO_BASE+0x00200020))
#define GPCLR0 ((volatile unsigned int*)(MMIO_BASE+0x00200028))
#define GPLEV0 ((volatile unsigned int*)(MMIO_BASE+0x00200034))
#define GPLEV1 ((volatile unsigned int*)(MMIO_BASE+0x00200038))
#define GPEDS0 ((volatile unsigned int*)(MMIO_BASE+0x00200040))
#define GPEDS1 ((volatile unsigned int*)(MMIO_BASE+0x00200044))
#define GPHEN0 ((volatile unsigned int*)(MMIO_BASE+0x00200064))
#define GPHEN1 ((volatile unsigned int*)(MMIO_BASE+0x00200068))
#define GPPUD ((volatile unsigned int*)(MMIO_BASE+0x00200094))
#define GPPUDCLK0 ((volatile unsigned int*)(MMIO_BASE+0x00200098))
#define GPPUDCLK1 ((volatile unsigned int*)(MMIO_BASE+0x0020009C))

#endif
26 changes: 26 additions & 0 deletions lab1/include/mbox.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* a properly aligned buffer */
/* use this buffer(global variable) directly and the mbox_call will use it after call*/
/* mbox format https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */
/* mbox address need to be aligned to 16 bytes */
extern volatile unsigned int mbox[36];

#define MBOX_REQUEST 0

/* channels */
#define MBOX_CH_POWER 0
#define MBOX_CH_FB 1
#define MBOX_CH_VUART 2
#define MBOX_CH_VCHIQ 3
#define MBOX_CH_LEDS 4
#define MBOX_CH_BTNS 5
#define MBOX_CH_TOUCH 6
#define MBOX_CH_COUNT 7
#define MBOX_CH_PROP 8

/* tags */
#define GET_BOARD_REVISION 0x10002
#define MBOX_TAG_GETSERIAL 0x10004
#define GET_ARM_MEMORY 0x10005
#define MBOX_TAG_LAST 0

int mbox_call(unsigned char ch);
8 changes: 8 additions & 0 deletions lab1/include/shell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef SHELL_H
#define SHELL_H

void shell();
void do_cmd(char* cmd);
void print_system_messages();

#endif
9 changes: 9 additions & 0 deletions lab1/include/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef STRING_H
#define STRING_H

int strcmp (const char * s1, const char * s2 );
char* strcat (char *dest, const char *src);
unsigned long long strlen(const char *str);
char* strcpy (char *dest, const char *src);
char* memcpy (void *dest, const void *src, unsigned long long len);
#endif
6 changes: 6 additions & 0 deletions lab1/include/system.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
int get_board_revision(unsigned int* board_revision);
int get_arm_memory_info(unsigned int* base_addr,unsigned int* size);
void set(long addr, unsigned int value);
void reboot();
void reset(int tick);
void cancel_reset();
15 changes: 15 additions & 0 deletions lab1/include/uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef UART_H
#define UART_H

#define MAX_BUF_SIZE 0x100

void uart_init();
void uart_putc(char c);
char uart_getc();
int uart_puts(char *s);
char* uart_gets(char *buf);
int uart_printf(char *s);
void uart_hex(unsigned int d);
void disable_uart();

#endif
Binary file added lab1/kernel8.img
Binary file not shown.
19 changes: 19 additions & 0 deletions lab1/linker.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
SECTIONS
{
. = 0x80000;
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
PROVIDE(_data = .);
.data : { *(.data .data.* .gnu.linkonce.d*) }
.bss (NOLOAD) : {
. = ALIGN(16);
__bss_start = .;
*(.bss .bss.*)
*(COMMON)
__bss_end = .;
}
_end = .;

/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
}
__bss_size = (__bss_end - __bss_start)>>3;
12 changes: 12 additions & 0 deletions lab1/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "uart.h"
#include "mbox.h"
#include "shell.h"
#include "string.h"

void main()
{
// set up serial console
uart_init();

shell();
}
37 changes: 37 additions & 0 deletions lab1/src/mbox.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "gpio.h"

/* mailbox message buffer */
volatile unsigned int __attribute__((aligned(16))) mbox[36];

#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
#define MBOX_READ ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
#define MBOX_POLL ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
#define MBOX_SENDER ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
#define MBOX_STATUS ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
#define MBOX_CONFIG ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
#define MBOX_WRITE ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
#define MBOX_RESPONSE 0x80000000 // mbox[1] = 0x80000000 -> request successful
#define MBOX_FULL 0x80000000
#define MBOX_EMPTY 0x40000000

/**
* Make a mailbox call. Returns 0 on failure, non-zero on success
*/
int mbox_call(unsigned char ch) // Mailbox 0 define several channels, but we only use channel 8 (CPU->GPU) for communication.
{
unsigned int r = (((unsigned int)((unsigned long)&mbox)&~0xF) | (ch&0xF));
//wait until we can write to the mailbox
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_FULL);
//write the address of our message to the mailbox with channel identifier
*MBOX_WRITE = r;
//now wait for the response
while(1) {
//is there a response?wait until empty flag unset
do{asm volatile("nop");}while(*MBOX_STATUS & MBOX_EMPTY);
//is it a response to our message?
if(r == *MBOX_READ)
//is it a valid successful response?
return mbox[1]==MBOX_RESPONSE;
}
return 0;
}
58 changes: 58 additions & 0 deletions lab1/src/shell.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "uart.h"
#include "string.h"
#include "shell.h"
#include "mbox.h"
#include "system.h"

void shell()
{
char cmd[MAX_BUF_SIZE];
print_system_messages();
while(1)
{
uart_printf("# ");
uart_gets(cmd);
do_cmd(cmd);
}
}

void do_cmd(char* cmd)
{
if(strcmp(cmd,"help")==0)
{
uart_puts("help : print this help menu");
uart_puts("hello : print Hello World!");
uart_puts("reboot : reboot the device");
}
else if((strcmp(cmd,"hello")==0))
{
uart_puts("Hello World!");
}
else if((strcmp(cmd,"reboot")==0))
{
reboot();
}else
{
uart_puts("Unknown command! again");
}
}

void print_system_messages()
{
unsigned int board_revision;
get_board_revision(&board_revision);
uart_printf("Board revision is : 0x");
uart_hex(board_revision);
uart_puts("");

unsigned int arm_mem_base_addr;
unsigned int arm_mem_size;

get_arm_memory_info(&arm_mem_base_addr,&arm_mem_size);
uart_printf("ARM memory base address in bytes : 0x");
uart_hex(arm_mem_base_addr);
uart_puts("");
uart_printf("ARM memory size in bytes : 0x");
uart_hex(arm_mem_size);
uart_puts("");
}
26 changes: 26 additions & 0 deletions lab1/src/start.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.section ".text.boot"

.globl _start
_start:
mrs x1, mpidr_el1
and x1, x1, #3
cbz x1, 2f
1: wfe
b 1b
2: // cpu id == 0
// set top of stack just before our code (stack grows to a lower address per AAPCS64)
ldr x1, =_start
mov sp, x1

// clear bss
ldr x1, =__bss_start
ldr w2, =__bss_size
3: cbz w2, 4f
str xzr, [x1], #8
sub w2, w2, #1
cbnz w2, 3b

// jump to C code, should not return
4: bl main
// for failsafe, halt this core too
b 1b
45 changes: 45 additions & 0 deletions lab1/src/string.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "string.h"
#include <stddef.h>

int strcmp (const char *p1, const char *p2)
{
const unsigned char *s1 = (const unsigned char *) p1;
const unsigned char *s2 = (const unsigned char *) p2;
unsigned char c1, c2;
do
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0')
return c1 - c2;
}
while (c1 == c2);
return c1 - c2;
}

char* strcat (char *dest, const char *src)
{
strcpy (dest + strlen (dest), src);
return dest;
}

char* strcpy (char *dest, const char *src)
{
return memcpy (dest, src, strlen (src) + 1);
}

unsigned long long strlen(const char *str)
{
size_t count = 0;
while((unsigned char)*str++)count++;
return count;
}

char* memcpy (void *dest, const void *src, unsigned long long len)
{
char *d = dest;
const char *s = src;
while (len--)
*d++ = *s++;
return dest;
}
Loading