Skip to content

new file #170

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

Open
wants to merge 24 commits into
base: 311510189
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions lab3_ADEX2/ReadMe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

22 changes: 22 additions & 0 deletions lab3_ADEX2/shell/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
CFLAGS = -Iinclude -fno-stack-protector -Wall -Wextra -Wpedantic -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
# CFLAGS += -I../../../opt/lib/gcc/aarch64-linux-gnu/12.2.0/include
CFLAGS += -I /usr/aarch64-linux-gnu/include
all: kernel8.img

start.o: start.S
aarch64-linux-gnu-gcc $(CFLAGS) -c start.S -o start.o

%.o: %.c
aarch64-linux-gnu-gcc $(CFLAGS) -c $< -o $@

kernel8.img: start.o $(OBJS)
aarch64-linux-gnu-ld start.o $(OBJS) -T linker.ld -o kernel8.elf
aarch64-linux-gnu-objcopy -O binary kernel8.elf kernel8.img

clean:
rm kernel8.elf *.o >/dev/null 2>/dev/null || true

run:
qemu-system-aarch64 -M raspi3b -serial null -serial stdio -initrd initramfs.cpio -dtb bcm2710-rpi-3-b-plus.dtb -display none -kernel kernel8.img
1 change: 1 addition & 0 deletions lab3_ADEX2/shell/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

20 changes: 20 additions & 0 deletions lab3_ADEX2/shell/allocator.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "header/allocator.h"
#include "header/utils.h"

#define SIMPLE_MALLOC_BUFFER_SIZE 8192
static unsigned char simple_malloc_buffer[SIMPLE_MALLOC_BUFFER_SIZE];
static unsigned long simple_malloc_offset = 0;

void* simple_malloc(unsigned long size){
//align to 8 bytes
utils_align(&size,8);

if(simple_malloc_offset + size > SIMPLE_MALLOC_BUFFER_SIZE) {
//Not enough space left
return (void*) 0;
}
void* allocated = (void *)&simple_malloc_buffer[simple_malloc_offset];
simple_malloc_offset += size;

return allocated;
}
Binary file added lab3_ADEX2/shell/allocator.o
Binary file not shown.
Binary file added lab3_ADEX2/shell/bcm2710-rpi-3-b-plus.dtb
Binary file not shown.
96 changes: 96 additions & 0 deletions lab3_ADEX2/shell/cpio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "header/cpio.h"
#include "header/uart.h"
#include "header/utils.h"
#include "header/allocator.h"

int file_num = 0;
struct file *f = NULL;

void allocate_file_array() {
if (f == NULL) {
f = (struct file *)simple_malloc(MAX_FILE_NUM * sizeof(struct file));
if (f == NULL) {
uart_send_string("Memory allocation error\n");
// Handle memory allocation error
}
}
}

void traverse_file()
{
allocate_file_array();
char* addr = (char *)cpio_addr;


while(utils_string_compare((char *)(addr+sizeof(struct cpio_header)),"TRAILER!!!") == 0){

struct cpio_header *header = (struct cpio_header *)addr;
unsigned long filename_size = utils_atoi(header->c_namesize, (int)sizeof(header->c_namesize));
unsigned long headerPathname_size = sizeof(struct cpio_header) + filename_size;
unsigned long file_size = utils_atoi(header->c_filesize, (int)sizeof(header->c_filesize));

utils_align(&headerPathname_size, 4);
utils_align(&file_size, 4);

f[file_num].file_header = header;
f[file_num].filename_size = filename_size;
f[file_num].headerPathname_size = headerPathname_size;
f[file_num].file_size = file_size;
f[file_num].file_content_head = (char*) header + headerPathname_size;

addr += (headerPathname_size + file_size);
file_num += 1;
}
}

int findfile(char* filename) {
for(int n=0;n<=file_num;n++) {
if ((utils_string_compare(((char *)f[n].file_header)+sizeof(struct cpio_header), filename) != 0)){
return n;
}
}
return -1;
}

void cpio_ls()
{
for(int n=0;n<=file_num;n++) {
uart_send_string(((char *)f[n].file_header)+sizeof(struct cpio_header));
uart_send_string("\n");
}
}


void cpio_cat(char *filename)
{
int targetfile_num = findfile(filename);

if(targetfile_num != -1) {
for (unsigned int i = 0; i < f[targetfile_num].file_size; i++)
{
uart_send_char(f[targetfile_num].file_content_head[i]);
}
uart_send_string("\n");

} else {
uart_send_string("Can not Find the file\n");
}

}

void cpio_exec_program(char* filename) {
int targetfile_num = findfile(filename);

char* target = (char*) 0x20000;
for(unsigned i = 0; i<f[targetfile_num].file_size; i++){
*target++ = f[targetfile_num].file_content_head[i];
}

unsigned long spsr_el1 = 0x3c0;
asm volatile ("msr spsr_el1, %0" ::"r"(spsr_el1));
unsigned long jump_addr = 0x20000;
asm volatile("msr elr_el1,%0" ::"r"(jump_addr));
unsigned long sp = (unsigned long) simple_malloc(4096);
asm volatile("msr sp_el0,%0" :: "r"(sp));
asm volatile("eret");
}
Binary file added lab3_ADEX2/shell/cpio.o
Binary file not shown.
163 changes: 163 additions & 0 deletions lab3_ADEX2/shell/dtb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#include "header/dtb.h"
#include "header/uart.h"
#include "header/utils.h"
#define UNUSED(x) (void)(x)


char* cpio_addr;
int space = 0;
//1. Define the callback function type(fdt_callback)
//2. Create a structure for holding the FDT header information(fdt_header)
//3. Implement helper functions to extract the FDT header information

uint32_t fdt_u32_le2be (const void *addr) {
const uint8_t *bytes = (const uint8_t *) addr;
uint32_t ret = (uint32_t)bytes[0] << 24 |(uint32_t)bytes[1] << 16 |(uint32_t)bytes[2] << 8 |(uint32_t)bytes[3];
return ret;
}

void send_space(int n) {
while(n--) uart_send_string(" ");
}

int parse_struct (fdt_callback cb, uintptr_t cur_ptr, uintptr_t strings_ptr,uint32_t totalsize) {
uintptr_t end_ptr = cur_ptr + totalsize;

while(cur_ptr < end_ptr) {

uint32_t token = fdt_u32_le2be((char *)cur_ptr);
cur_ptr += 4;

switch(token){
case FDT_BEGIN_NODE:
/*
Token type (4 bytes): Indicates that it's an FDT_BEGIN_NODE token.
Node name (variable length, NULL-terminated): Specifies the name of the node being opened.
*/
//uart_send_string("In FDT_BEGIN_NODE\n");
cb(token, (char*)cur_ptr,NULL,0);
cur_ptr += utils_align_up(utils_strlen((char*)cur_ptr),4);
break;
case FDT_END_NODE:
/*
Token type (4 bytes): Indicates that it's an FDT_END_NODE token.
*/
//uart_send_string("In FDT_END_NODE;\n");
cb(token,NULL,NULL,0);
break;

case FDT_PROP: {

/*
Token type (4 bytes): Indicates that it's an FDT_PROP token.
Data length (4 bytes): Specifies the length of the property data (len).
Name offset (4 bytes): Provides the offset of the property name within the strings block (nameoff).
Property data (variable length): Contains the property data itself, the size of which is determined by len.
*/
//uart_send_string("In FDT_PROP \n");
uint32_t len = fdt_u32_le2be((char*)cur_ptr);
cur_ptr += 4;
uint32_t nameoff = fdt_u32_le2be((char*)cur_ptr);
cur_ptr += 4;
//second parameter name here is property name not node name
cb(token,(char*)(strings_ptr + nameoff),(void*)cur_ptr,len);
cur_ptr += utils_align_up(len,4);
break;

}
case FDT_NOP:
//uart_send_string("In FDT_NOP\n");
cb(token,NULL,NULL,0);
break;

case FDT_END:
//uart_send_string("In FDT_END\n");
cb(token,NULL,NULL,0);
return 0;
default:;
return -1;
}
}
return -1;

}
//4. Implement the fdt_traverse function:

int fdt_traverse(fdt_callback cb,void * _dtb){
uintptr_t dtb_ptr = (uintptr_t) _dtb;
uart_send_string("\ndtb loading at: ");
uart_hex(dtb_ptr);
// uart_send_char('\n');
uart_send_string("\r\n");
struct fdt_header* header = (struct fdt_header*) dtb_ptr;

uint32_t magic = fdt_u32_le2be(&(header->magic));

if (magic != 0xd00dfeed){

uart_send_string("The header magic is wrong\n");
return -1;
}

/*
+-----------------+
| fdt_header | <- dtb_ptr
+-----------------+
| reserved memory |
+-----------------+
| structure block | <- dtb_ptr + header->off_dt_struct (struct_ptr)
+-----------------+
| strings block | <- dtb_ptr + header->off_dt_strings (strings_ptr)
+-----------------+
*/

uintptr_t struct_ptr = dtb_ptr + fdt_u32_le2be(&(header->off_dt_struct));
uintptr_t strings_ptr = dtb_ptr + fdt_u32_le2be(&(header->off_dt_strings));
uint32_t totalsize = fdt_u32_le2be(&header->totalsize);
parse_struct(cb, struct_ptr,strings_ptr,totalsize);
return 1;

}

//5. Implement the initramfs_callback function:
void get_cpio_addr(int token,const char* name,const void* data,uint32_t size){
UNUSED(size);
if(token==FDT_PROP && utils_string_compare((char *)name,"linux,initrd-start")){
cpio_addr = (char*)(uintptr_t)fdt_u32_le2be(data);
uart_send_string("cpio address is at: ");
uart_hex((uintptr_t)fdt_u32_le2be(data));
// uart_send_char('\n');
uart_send_string("\r\n");
}
}

//6. Implement print_dtb callback function:

void print_dtb(int token, const char* name, const void* data, uint32_t size) {
UNUSED(data);
UNUSED(size);

switch(token){
case FDT_BEGIN_NODE:
uart_send_string("\n");
send_space(space);
uart_send_string((char*)name);
uart_send_string("{\n ");
space++;
break;
case FDT_END_NODE:
uart_send_string("\n");
space--;
if(space >0) send_space(space);
uart_send_string("}\n");
break;
case FDT_NOP:
break;
case FDT_PROP:
send_space(space);
uart_send_string((char*)name);
break;
case FDT_END:
break;
}
}
Binary file added lab3_ADEX2/shell/dtb.o
Binary file not shown.
Loading