From 385db8fe16ff083495f18ce0d1f0c11f57a28be7 Mon Sep 17 00:00:00 2001 From: Laxiflora Date: Mon, 3 Jun 2024 04:28:03 +0800 Subject: [PATCH 01/23] update linkloader and start.S to strengthen readability --- lab_2/bootloader/kernel_uploader.py | 23 ++++++++++----- lab_2/bootloader/link.ld | 17 +++++++++-- lab_2/bootloader/main.c | 14 +++++----- lab_2/bootloader/start.S | 34 ++++++++++++++-------- lab_2/shell/Makefile | 2 +- lab_2/shell/main.c | 42 ++++++++++++++++++++++++---- lab_2/shell/shell_kernel.img | Bin 2264 -> 2352 bytes 7 files changed, 96 insertions(+), 36 deletions(-) diff --git a/lab_2/bootloader/kernel_uploader.py b/lab_2/bootloader/kernel_uploader.py index 339093955..158c616d4 100644 --- a/lab_2/bootloader/kernel_uploader.py +++ b/lab_2/bootloader/kernel_uploader.py @@ -2,8 +2,9 @@ import os import os.path import sys +import time -port = '/dev/pts/3' +port = '/dev/pts/13' s = serial.Serial(port, baudrate=115200) def read_line(s): @@ -18,7 +19,10 @@ def read_line(s): return received_string size = os.stat("../shell/shell_kernel.img").st_size +# size = os.stat("./kernel8.img").st_size + size_bytes = size.to_bytes(4,"little") +print(f"size from python: {hex(size)}") s.write(size_bytes) # get response of correctness of bytes size sent @@ -28,14 +32,19 @@ def read_line(s): with open("../shell/shell_kernel.img","rb") as f: s.write(f.read()) +# with open("./kernel8.img","rb") as f: +# s.write(f.read()) + # get response of whether kernel is loaded successfully or not received_content = read_line(s) print(received_content) while(True): - while s.in_waiting > 0: + # while s.in_waiting > 0: + for i in range(10): received_content = read_line(s) - print(received_content) - inp = input() - bytes_to_send = inp.encode('utf-8') - s.write(bytes_to_send) - print(received_content) \ No newline at end of file + print(received_content.strip().replace("\n", "").replace("\r", "")) + time.sleep(1) + # inp = input() + # bytes_to_send = inp.encode('utf-8') + # s.write(bytes_to_send) + # print(received_content) \ No newline at end of file diff --git a/lab_2/bootloader/link.ld b/lab_2/bootloader/link.ld index 9d5029b23..5d4536049 100644 --- a/lab_2/bootloader/link.ld +++ b/lab_2/bootloader/link.ld @@ -22,13 +22,24 @@ * DEALINGS IN THE SOFTWARE. * */ - SECTIONS { . = 0x60000; PROVIDE(_head = .); - .text : { KEEP(*(.text.boot)) *(.text .text.*) } - .rodata : { *(.rodata .rodata.*) } + .relocate : { + KEEP(*(.text.relocate)) + } + . = ALIGN(4096); + + .imgLoader : { + KEEP(*(.text.load_img)) + } + . = ALIGN(4096); + .text : { + KEEP(*(.text.boot)) + *(.text) + } + . = ALIGN(4096); PROVIDE(_data = .); .data : { *(.data .data.*) } .bss : { diff --git a/lab_2/bootloader/main.c b/lab_2/bootloader/main.c index c2c550fed..1bbd110ec 100644 --- a/lab_2/bootloader/main.c +++ b/lab_2/bootloader/main.c @@ -35,27 +35,27 @@ void load_img(){ size_buffer[i] = uart_getc(); uart_puts("size-check correct\n"); + uart_puts("Kernel size received: "); + uart_hex(size); + uart_puts("\n"); + char *kernel = (char *) 0x80000; while(size--) *kernel++ = uart_getc(); uart_puts("kernel-loaded\n"); - - asm volatile( - "mov x30, 0x80000;" - "ret;" - ); + return; } -void main(int argc, char* argv[]){ +void relocator(int argc, char* argv[]){ asm volatile( "mov x10, x0" ); uart_init(); load_img(); asm volatile( - "mov x30, 0x80000;" "mov x0, x10;" + "mov x30, 0x80000;" "ret;" ); } diff --git a/lab_2/bootloader/start.S b/lab_2/bootloader/start.S index ecef527bb..f4d0dfec4 100644 --- a/lab_2/bootloader/start.S +++ b/lab_2/bootloader/start.S @@ -1,31 +1,41 @@ -.section ".text.boot" - -.global _start - -_start: +.section ".text.relocate" +.global _relocate +_relocate: // relocate our code from load address to link address ldr x1, =0x80000; // src address - ldr x2, =_head // target address + ldr x2, =0x60000; // target address ldr w3, =__loader_size 1: ldr x4, [x1], #8 str x4, [x2], #8 sub w3, w3, #1 cbnz w3, 1b - // 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 +2: cbz w2, 3f str xzr, [x1], #8 sub w2, w2, #1 - cbnz w2, 3b + cbnz w2, 2b // jump to relocated C code, should not return -4: bl main-0x20000 - // for failsafe, halt this core too - b =0x80000 \ No newline at end of file +3: bl relocator-0x20000 + b _start + + +.section ".text.boot" + +.global _start + +_start: + // jump to main function in C + bl 0x80000 + // halt this core if return +1: + wfe + b 1b + diff --git a/lab_2/shell/Makefile b/lab_2/shell/Makefile index 3c685e120..ed9e406a1 100644 --- a/lab_2/shell/Makefile +++ b/lab_2/shell/Makefile @@ -46,7 +46,7 @@ clean: rm kernel8.elf *.o >/dev/null 2>/dev/null || true run: - qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none -d in_asm debug: qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none -s -S diff --git a/lab_2/shell/main.c b/lab_2/shell/main.c index 60860d053..60c75ad45 100644 --- a/lab_2/shell/main.c +++ b/lab_2/shell/main.c @@ -30,13 +30,43 @@ void main(int argc, char* argv[]){ - uart_init(); - cpio_ls(); - cpio_cat("hello2.txt"); - cpio_ls(); - cpio_cat("hello.txt"); + asm volatile( + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + "mov x0, x10;" + ); + // uart_init(); + // uart_puts("uart_not_bugged\n"); + // cpio_ls(); + // cpio_cat("hello2.txt"); + // cpio_ls(); + // cpio_cat("hello.txt"); int* data = (int *)simple_malloc((unsigned long) sizeof(int)*8); int* b = (int *)simple_malloc((unsigned long) sizeof(int)*8); - uart_puts("exit normally"); + uart_puts("exit normally\n"); + // asm volatile( + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "mov x0, x10;" + // "ret;" + // ); return; } diff --git a/lab_2/shell/shell_kernel.img b/lab_2/shell/shell_kernel.img index 43838b9b3fcedcc16d1c67f46e315868ceed7ded..15bf85c3e4ce17823c9fe24bfa6e384ffa9bcd77 100755 GIT binary patch delta 890 zcma)(PiRv?5XNVBOA}KqwJ(1ZpEYWsH3zFUND;v_Mo_F;+8hK05f6$dp-1RTSl=c(a!hY@0TZ_1mx<6P z$x{b51xYV2H*Ld|JVCNL%50;Ysr|jc?FiV-H%z`xo6;3wCyID(k13aTP;FT-*~X|G zBMJ{lX`JatFfYg%r^1LUV$OUI)vkjz;=N2>g|CaOlD1K2McY6IjahMwQ&Bgnh=`-_ zWaMIM*e7BMb+w4)E5cquE!})O8dp%q6^65Ky?27K!bssZlUz`ez^ce=u90SH#UBpO73w%KSNQZ_%ah zlGMY7n017A<@2~&F;X??OY9={=eSZ?{m2wIWeI21(LvkG%|4qEm*%u>oE1#@0CT}_ zE-&}i)*s`F5N7@Foph+B@YzEnZP#GE+`IKAt|@Q$n{1}e76_Y|>9(f%Sw7SKvQ12g zoo=SK8!vM#m|FZml;yaRj`v6+UcBsDPU~qFvX)xA_`-@64eV!=)`>trGp$>JzPt(b zudpAlDs>)~2HQIx@<(js*Uxqx>H)uCyEuoG=IVgAfIYCL)b9?v3Y W%r9#S>^WH6ckd(El&7rOVB{Zm1PXls delta 818 zcmYk4PiPZS5XR@dCnnGwv}qb`Fl~rp$w38!hzQ0Qq+X2Ojg@@6CKOv-{?{S9Vv1 z&N<;Qv9+e&S#Xt>BHbtoD|)No{uz~43~chP&~IcyJF3U-#d*2jr<)0Kn@Z>=Q8iA~ zvtR4zg?>TRx*~g;j1fo0?fOA-uYmdIw9rNDS>y+j9Mx-oXCEq{uqaPRDs!QlirE}< zM6cy82bx%iE;rE}SJno!xcFWau0h99Q9IVIoe{zqG42a36=i=xzkxiTeI>nWPK$UZ z>30$LyG-!Dt6=4c%2g@L=5_~BdyCBXB7f{7L|A}@42Ue@yglSg(i2FjUy_!~!#pO< z!>*HgLMF#=1J$BA7yV`WN&GzHc_seHkMP4N_t*2-v+cs# zV87*ggA8EIB7$fTEbEgt8vq*u8|yGu&Vp6Iu67tZ&L0L}0iW$~X4eHhq*BZCh68Yt p1;E;mxSjk2Y!+-!AnrNXGq7Njb71pe1A({?V2fbKJFMe;`F{dp>kI$@ From 342bc177a1f55e38614e4f934735151c338955f3 Mon Sep 17 00:00:00 2001 From: Laxiflora Date: Mon, 3 Jun 2024 04:41:13 +0800 Subject: [PATCH 02/23] Find the bug that makes cpio output infinity space: Missing initramfs.cpio in arguments that runs bootloader --- lab_2/bootloader/Makefile | 2 +- lab_2/bootloader/initramfs.cpio | Bin 0 -> 1024 bytes lab_2/bootloader/kernel_uploader.py | 13 ++++++------- lab_2/shell/cpio.c | 1 - lab_2/shell/main.c | 8 ++++---- lab_2/shell/shell_kernel.img | Bin 2352 -> 2416 bytes 6 files changed, 11 insertions(+), 13 deletions(-) create mode 100644 lab_2/bootloader/initramfs.cpio diff --git a/lab_2/bootloader/Makefile b/lab_2/bootloader/Makefile index 87d5b39d0..22a62f2b9 100644 --- a/lab_2/bootloader/Makefile +++ b/lab_2/bootloader/Makefile @@ -46,7 +46,7 @@ clean: rm kernel8.elf *.o >/dev/null 2>/dev/null || true run: - qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial pty -display none -d in_asm + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -d in_asm debug: qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_2/bootloader/initramfs.cpio b/lab_2/bootloader/initramfs.cpio new file mode 100644 index 0000000000000000000000000000000000000000..e9c1dda97f1391b336871a2da59e34bd241fa43f GIT binary patch literal 1024 zcmeH@K@Ng26hv8j3b+87mIiQ%u_Pw0h!HOt3;y|ZOd9-B4l9R&fn>^y@5k6kI zmbaUt8zE&!W7VrbFV(b 0: - for i in range(10): + for i in range(50): received_content = read_line(s) print(received_content.strip().replace("\n", "").replace("\r", "")) - time.sleep(1) - # inp = input() - # bytes_to_send = inp.encode('utf-8') - # s.write(bytes_to_send) - # print(received_content) \ No newline at end of file + inp = input() + bytes_to_send = inp.encode('utf-8') + s.write(bytes_to_send) + print(received_content) \ No newline at end of file diff --git a/lab_2/shell/cpio.c b/lab_2/shell/cpio.c index 77a9f6f10..a3aaeab82 100644 --- a/lab_2/shell/cpio.c +++ b/lab_2/shell/cpio.c @@ -30,7 +30,6 @@ void cpio_cat(char *filename){ utils_align(&headerPathname_size,4); utils_align(&file_size,4); - char *file_content = target + headerPathname_size; for (unsigned int i = 0; i < file_size; i++) { diff --git a/lab_2/shell/main.c b/lab_2/shell/main.c index 60c75ad45..b995ac2d4 100644 --- a/lab_2/shell/main.c +++ b/lab_2/shell/main.c @@ -46,10 +46,10 @@ void main(int argc, char* argv[]){ ); // uart_init(); // uart_puts("uart_not_bugged\n"); - // cpio_ls(); - // cpio_cat("hello2.txt"); - // cpio_ls(); - // cpio_cat("hello.txt"); + cpio_ls(); + cpio_cat("hello2.txt"); + cpio_ls(); + cpio_cat("hello.txt"); int* data = (int *)simple_malloc((unsigned long) sizeof(int)*8); int* b = (int *)simple_malloc((unsigned long) sizeof(int)*8); uart_puts("exit normally\n"); diff --git a/lab_2/shell/shell_kernel.img b/lab_2/shell/shell_kernel.img index 15bf85c3e4ce17823c9fe24bfa6e384ffa9bcd77..db6c2fc5090da8a0a1b3607c35ab21fc5c039e7d 100755 GIT binary patch delta 860 zcmYk2O=uHQ5Xa~3i)N)#YPM}6O>BY`YpF`DUsa1~8&M%rXmXHNv_%U&6dG&~#R|rH z@DLAqyokLh_2b|!9t!G3J*0XO@g&lN_>n{pf)_*47~`_e?8cIT-I@8#y#LI5OP(K| z^zjpk4JweCbI){iX_JFkjWJz&94Y@CQS>HcGf$a#^1?52ywPaJeC4iRlvhw7t#9xQkyc0l9FpnX@*ZOvw^)|05T*=(n*y4jQQHN z?}2b+@$E?JDhQJG$R4G&=NfkAwQw01?q~(}eZaEf^y;wa7YkThjrHl~+{*`9es+bt zU4wuSQYgn_XDsWcO-2JEi}CRPd@&%NQ|wB?q^{B7skZXC2!J9v4oX z&$h`rKFHc0jqrKC1&)?OcZSWhW!^A5kP45{Aj zzKUgiC5+ZUKL+p(Sv$pO#2S%-98wcbwC uvZB>0RW8v9WNHmdBRh}GSHtcjOURmjE*=CCL@zB~Ja`b%3W~A`-t=GznkMbCzPAaw1G{hD_ul;foB0)e8Z8|^ zv9Ch|T5jQ$g`wmMkhM8x>E&$W_i1kRAiMOE$>$kEIwEHGV!pc5koA6O)CH4W49anU zSV~I$WD=9A0Q(x4IY-3p>M%4eAoKHGOrFO*i8O&?uf0w&oJC_+T;Nb7ql)OUsV6Jf z(u;v1{-7=mQ9mcFb<`sB?Py#<9Y^T)NXvVaF*9dgVUi0t2*_%9&S#%NZld4+`TFby z^sCN>tONdBaewY{+IMBG3_x*Pne(FhHD3`&$P(6Sb5oXEc>Q=;oL!~p*Gxm+Qj#A_ zLdbmYVi&~?jBa72)!`WOB0dFnx7HSjhER2Bc}VRMvux;DK`eg;v=aI&-+doSA>2HK-=`Z-L%I=EQTzh?rZwqG*-^|yrpvlD>sq(K5b4X z^2pz*il$G_xSlr?s9dEJ$g}_}A-jRBFTfrmE2;e*`q&e!Bm$MUSb2dg)n@JB3;qR* CVDRVw From 73bfeade068cc49b79759b0540bdccdde2034864 Mon Sep 17 00:00:00 2001 From: Laxiflora Date: Tue, 4 Jun 2024 00:20:01 +0800 Subject: [PATCH 03/23] add ls, cat into shell command --- lab_2/bootloader/kernel_uploader.py | 16 +++-- lab_2/shell/main.c | 104 +++++++++++++++++----------- lab_2/shell/shell_kernel.img | Bin 2416 -> 0 bytes 3 files changed, 75 insertions(+), 45 deletions(-) delete mode 100755 lab_2/shell/shell_kernel.img diff --git a/lab_2/bootloader/kernel_uploader.py b/lab_2/bootloader/kernel_uploader.py index c2bb057bc..e5553fc1d 100644 --- a/lab_2/bootloader/kernel_uploader.py +++ b/lab_2/bootloader/kernel_uploader.py @@ -36,14 +36,18 @@ def read_line(s): # s.write(f.read()) # get response of whether kernel is loaded successfully or not -received_content = read_line(s) -print(received_content) +time.sleep(1) while(True): - # while s.in_waiting > 0: - for i in range(50): + while s.in_waiting > 0: received_content = read_line(s) - print(received_content.strip().replace("\n", "").replace("\r", "")) + print(received_content) inp = input() + if(inp == ""): + continue + inp += "\n" bytes_to_send = inp.encode('utf-8') s.write(bytes_to_send) - print(received_content) \ No newline at end of file + while s.in_waiting > 0: + received_content = read_line(s) + print(received_content) + time.sleep(2) \ No newline at end of file diff --git a/lab_2/shell/main.c b/lab_2/shell/main.c index b995ac2d4..c8d5d91e1 100644 --- a/lab_2/shell/main.c +++ b/lab_2/shell/main.c @@ -22,7 +22,7 @@ * DEALINGS IN THE SOFTWARE. * */ -#define MAX_BUFFER 10 +#define MAX_BUFFER 50 #include "include/uart.h" #include "include/utils.h" #include "include/mbox.h" @@ -30,43 +30,69 @@ void main(int argc, char* argv[]){ - asm volatile( - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - "mov x0, x10;" - ); - // uart_init(); - // uart_puts("uart_not_bugged\n"); - cpio_ls(); - cpio_cat("hello2.txt"); - cpio_ls(); - cpio_cat("hello.txt"); - int* data = (int *)simple_malloc((unsigned long) sizeof(int)*8); - int* b = (int *)simple_malloc((unsigned long) sizeof(int)*8); - uart_puts("exit normally\n"); - // asm volatile( - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "mov x0, x10;" - // "ret;" - // ); + uart_init(); + while(1){ + char command[MAX_BUFFER]; + char c = '\0'; + int length=0; + for(int i=0; i\t: print the content of file in root filesystem\n"); + uart_puts("hello\t: print hello world!\n"); + uart_puts("reboot\t: reboot the device\n"); + } + else if(strcmp(command, "hello") == 0){ + uart_puts("Hello World!\n"); + } + else if(strcmp(command, "ls") == 0){ + cpio_ls(); + } + else if(strcmp(command, "reboot") == 0){ + reset(); + } + // command with arguments + else{ + char arguments[3][MAX_BUFFER]; + // initialize + for(int i=0;i<3;i++){ + for(int j=0;jF7=F*amxAaBqg6VE(L#-cm`x2RY)fbnvn?UpTKmJO86|uKCliV+VdBCq zpi5eRa3>pNi;g*sYquZ%V2SJ_6m`jdY=7#_IbNt@d)!sdzk#JycocqOo&uY~sHxgsqtTOzBlzjC5T zn_okTd0A*?K_i7k7AI!utk8r|J-%N^n=PZn^T1|hiUdgY#O1=s>^e$x12gtzLhHnu zZA!+xDndMG*CP%Q+AmRv{m#fMBg|>Q8EjP;_74bc;GteMx7`)Kx2rBZzs8wJ_I>wR zRBpUdf?BX}J|ZKZ%8Y#eMogT~e6t+Bk2pAwr;x*pyb8X|k&PL?RQQr)s>}g42R-($ zB0nX?S;);A*^gLfUsb}-0q0yf$1S{GULUR_3XMoo=;&fT=7<$%Dsr%p8sq#Hb7|fh zPUn*B`!>w?@uRMfjw>|5zWHwcLLAg9wBK-_28KPy^egs@_5PH!R7|)-j$@ECj;Vmx z*>z!`potMlgv`JQF{p3&s`s1d$#-F6#_UX>4izONZg16fFZTtF7inWS<2aLj=Z#wP zY@AWCrlEdVFOFp2lo5Me&P7fCzr2oIVPu$m#aa~Wo$38}vGxtG6*ZPb96Ue3oa~!U z#Skynx-w%}K?P{@;eqH{O_)bx5=j*ze)=x=hK-z)u)T#WqcJ`s;Br3JJVPX+$tB+W z79aQ}B<*cNErwu^=!_?zI4AMe_Qnf8Ud??MpkOR}MKET+ar*8$$k4K2EGst{V_y#J z*Fpwzf-&T_$p-s6q!d^i>Mw(P82d8p>4{)$3TqqIjhHW3RnGwKrv>Y2yXujEqpv3i z3)GlGLmn6G%fK8o-W@GaJ@%Ho0y`-cE^zuGoChi7pGNG$tfCHM9sxdcOCLLza8Ag9 zeX#!~#KtkOKhALg`Ebl^lZAax>(6c$$cyvlywYzl04`%obLC)#ANSLoPwtbj*Pl-t1CMks z`@(%1gWp{(k^gs@yr!r<#BVB#`!VVW;rpvKlIgZ8kr#2*(4B)99Z_{jo zs#=a1`q8_$pg)NENkz`;bNF8q-z5E z3Fx~^Nea2h9>jSf&1FtNMz1NVN6g|qIX~|%Mcq{R#Twrmslt}C)GN#%06%~?ErHKE z1fCN*HVE65@s>pqY4$(fdCy1N5_Wu3Yjd1`a$O{x)!EANE~QWtWf^g#YmsZ*4oDu? z%MIH+b~_Y#ywcfYYwLV#UyH4$z17yXr=vB+Y;W!8=-l*7Pj63(XY7}@)Y`kJ$F{Gt z`^~0~j<=zbpQ4dC;31{=X|ZNS39Scag?w>e*AX9)EAO>qxyP4nJ(@F;UH87}gRB=v zm6q$*e!6_+;-x&I4WPUPX-Me$h5zK&k1Atw8#I1iP@zij4nnR%=S)gx!!gtGtZgIm zQN?%ZqU-v#Joq&*W6d0lBFF^9_m8gkGT_R~KPDX)JDHDRfn0(_ao)wi!r(mbK&%gR z{YD0c|7^MitULp=0HcSx&N1>}-Ev?yV7m<@<>v)p?Z9>{U_3F`3;Yc5BMUfV?ZDP2 zb-f`2JIMOLax$=CU@gG7{ybRsB(N@EnK7OPb_AG>Nf^xg0oWL@Y6DsPG0gu93}qHI From 6b95a5c0d978d6f61809432c6fe3c261f07ccebf Mon Sep 17 00:00:00 2001 From: Laxiflora Date: Thu, 6 Jun 2024 19:38:38 +0800 Subject: [PATCH 04/23] fix UART uninitialized error that read 1 garbage char ; fix kernel reload error by send the new image byte by byte --- lab_2/bootloader/kernel_uploader.py | 34 +++++++++++++++++++---------- lab_2/bootloader/uart.c | 6 +++++ lab_2/shell/main.c | 1 - 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lab_2/bootloader/kernel_uploader.py b/lab_2/bootloader/kernel_uploader.py index e5553fc1d..12abe17ba 100644 --- a/lab_2/bootloader/kernel_uploader.py +++ b/lab_2/bootloader/kernel_uploader.py @@ -4,7 +4,7 @@ import sys import time -port = '/dev/pts/14' +port = '/dev/pts/4' s = serial.Serial(port, baudrate=115200) def read_line(s): @@ -19,21 +19,32 @@ def read_line(s): return received_string size = os.stat("../shell/shell_kernel.img").st_size +print(size) # size = os.stat("./kernel8.img").st_size size_bytes = size.to_bytes(4,"little") print(f"size from python: {hex(size)}") s.write(size_bytes) +time.sleep(1) # get response of correctness of bytes size sent -received_size = read_line(s) -print(received_size) +while s.in_waiting > 0: + received_content = read_line(s) + print(received_content) -with open("../shell/shell_kernel.img","rb") as f: - s.write(f.read()) +with open("../shell/shell_kernel.img", "rb") as f: + sent_size = 0 # Initialize size counter -# with open("./kernel8.img","rb") as f: -# s.write(f.read()) + byte = f.read(1) # Read the first byte + while byte: + s.write(byte) # Send the byte over serial + # s.flush() # Flush the output buffer + sent_size += 1 # Increment size counter + byte = f.read(1) # Read the next byte + + +assert sent_size == size +print("kernel sent successfully.") # get response of whether kernel is loaded successfully or not time.sleep(1) @@ -41,13 +52,14 @@ def read_line(s): while s.in_waiting > 0: received_content = read_line(s) print(received_content) + print("#", end=" ") inp = input() if(inp == ""): continue inp += "\n" bytes_to_send = inp.encode('utf-8') s.write(bytes_to_send) - while s.in_waiting > 0: - received_content = read_line(s) - print(received_content) - time.sleep(2) \ No newline at end of file + #while s.in_waiting > 0: + # received_content = read_line(s) + # print(received_content) + time.sleep(1) \ No newline at end of file diff --git a/lab_2/bootloader/uart.c b/lab_2/bootloader/uart.c index 489c6608a..998d1509a 100644 --- a/lab_2/bootloader/uart.c +++ b/lab_2/bootloader/uart.c @@ -68,6 +68,12 @@ void uart_init() r=150; while(r--) { asm volatile("nop"); } *GPPUDCLK0 = 0; // flush GPIO setup *AUX_MU_CNTL = 3; // enable Tx, Rx + /*EXTRA: Read from AUX_MU_IO until AUX_MU_LSR indicates no more data*/ + while (*AUX_MU_LSR & 0x01) { + // Read and discard the data + volatile unsigned int data = *AUX_MU_IO; + (void)data; // Prevent unused variable warning + } } /** diff --git a/lab_2/shell/main.c b/lab_2/shell/main.c index c8d5d91e1..fa5185915 100644 --- a/lab_2/shell/main.c +++ b/lab_2/shell/main.c @@ -30,7 +30,6 @@ void main(int argc, char* argv[]){ - uart_init(); while(1){ char command[MAX_BUFFER]; char c = '\0'; From 75227e1ad9802b5c74566d67265020e39d33dcd5 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Fri, 7 Jun 2024 01:49:41 +0800 Subject: [PATCH 05/23] 1. add stdint.h for uint32_t 2. add test code reader.py and device_tree.c to parse device tree dtb 3. fix Dockerfile to install pip when building 4. download rpi3b+ dtb file --- Dockerfile | 3 + lab_2/bootloader/bcm2710-rpi-3-b-plus.dtb | Bin 0 -> 35026 bytes lab_2/bootloader/device_tree.c | 81 ++++++++++++++++++++++ lab_2/bootloader/include/device_tree.h | 34 +++++++++ lab_2/bootloader/include/stdint.h | 9 +++ lab_2/bootloader/reader.py | 9 +++ 6 files changed, 136 insertions(+) create mode 100644 lab_2/bootloader/bcm2710-rpi-3-b-plus.dtb create mode 100644 lab_2/bootloader/device_tree.c create mode 100644 lab_2/bootloader/include/device_tree.h create mode 100644 lab_2/bootloader/include/stdint.h create mode 100644 lab_2/bootloader/reader.py diff --git a/Dockerfile b/Dockerfile index 743cbf69c..a0b963125 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,6 +30,9 @@ RUN apt-get install -y \ # make gcc alia to aarch64-linux-gnu-gcc RUN echo "alias gcc='aarch64-linux-gnu-gcc'" >> ~/.bashrc +# install python dependicies +RUN apt install -y python3-pip + # clean up package caches RUN rm -rf /var/lib/apt/lists/* diff --git a/lab_2/bootloader/bcm2710-rpi-3-b-plus.dtb b/lab_2/bootloader/bcm2710-rpi-3-b-plus.dtb new file mode 100644 index 0000000000000000000000000000000000000000..a219bf3d5ca7a1e6d14618556f73a73911460911 GIT binary patch literal 35026 zcmc&-4UiniRi3@mon%?32q$rVh@G`hu@qb5+ui%o$+5`EQm{oNSy*!HBqXc7-MPC( z`({Sezkc1*-P7~b#M58#ytjSI^St{!?~xv!hjD!et^>H> z_P-wRBgU_H8>K<>%-P^5o}}S*D`96b=yo?d^&``Mvt0`s{-WP$tcKoVx7s|iSZ$W( zr;ieqX`YYk`Uf;k{(L<@oj=P&`FrkAoL%scH|E7O4CisVVe-mwuF|Mi!XSiKaG#6k z@u{#~oeG0)z0z1X8kCB&g_!~o;7E@+uSnq(iiLuUa|3YB3QlEp!xB*h(zqVi_Zk}Q z)m9B5LwgL*hX@ylf!zfEYX!H~toYS-tJiHe8bKFi3x%V}d?$fh7TkKP2eGbpdg&C4 zCCdo;cpk2r;ICJD)s83Qo6WqGvQ( zVLs2s^(Mht?$p~9NHPz~^eqw}%RMbq;=DD5ldc=``s0R|W>vCbMgYQ*55~X8iJy+y zkoe~y{xOYjQN%HZrvD|4A3*sK>ZR&}K~VZ1(0HVu zhw7!%e^BG2^u>ri%lA=@&q&Ys-<9~VQy2b{^cnw$Zaf6+)+6ITnToGEYV3 zcY^K`6T_(-|54&7U&?Vd!N)Z4{zc+lKBo}yJMC_7q3C)8^3VzZjp)A^zWGoJA>H^Ac;~Payt=Y8yNR ztzNm)Za0n>&*tY#vxPfb-STRs+Y65u^I@x2HpX)H&Y)FUYy{<%pi=9sv|B-V+*X0e zM){dV9>PyIK<;Zn&2I+Hc6U?xBHl1Nis;;T;zoHZ&Eo_%>aEp{Bh_XF0XW7VpeJ0Z zbdd|K7)wErO`E%w1Z)_O+#$zL-rYRD3t{ptyj%6~A7L>8gv(VstGIWFaSM!N{?%@s{Un{{_d{Op zw?62E-zBjo{yHT4d8VmXDhhsN>lU-`VrxZOlmm{d;ibdiAF5wIZWP zoEPG9JNsEb+zfj`(-(Y38d|KA$FF!)2T>=c%>(w^c;;}?@u`={0%77=UUDDzo^{WH z4O8Y%*6JbKN)0eNizjkDiLlVIRDNOlg-4M1N zAE$sLd{jHIge|aAjJigqXP=ei!yppOc<5&CDLg3`<>B!w2PnflE`iM;`ZLx~U8duc zY4~LR9GlSbNjRT`YaU;OpZ48`MTU@p;XQk3Ah_%^lKeL@h#=7A*ZbHO!V3rd`4cgwW9l(4fREr#+7O=T9qCdJ_+&X42bcSA+$;|xs9%Y< zaU&eZXx!~i9B7Wb4B_3l)Xl*I+}tlA?%va<$`?+Z@c1}+#=H0Y>HAA^pO*WK+-K!J zC-lnj-Up;9tbN`^|w zP$?bt?mKn%bosvXr^@HN3l~pZeDFf~%qvcn@AXbzyio8S;O*kWr{Lr5!l`2U?z}sd}D7h_LgGrG`z;ydKKMgJ?3hix=(c~#PJ=}B zbZk>>LrlxIL*3bni?(7PE{=Kj<9Ze@=!@tc_3qiYXa}fU96NDb5Bu!B02l46(@&37 z5Kgz#R{$n$Bxp9P!Z4~8j(mZR@VgVb|dEbKHcGRJXIR^GIOEEDA{Wm@i3 z8n=^_G+;45hR%%CUYw3}XlsVi z`JOB~wqTl$bolP9;Vgb$nV?gWa?y^_X*$wzbWrLzU9L00iOXf^%&?N+Tsn6+;S@iS zu2_7L`&r-%UA!6;>Py0(ZJt6G?Jm(iHLnzHp~ZLeG_8_onc-1sy$E>39Y*V12CW%K z{z{AT_fxbS9TC26c4!%mFbcu^l@9r4co$2 zarhOw->Y;x)uxa|Pen&O*hi_y8{l{Ch0rDrSCrKfdC8FOsm(o2{7g3=3X zcbhKw|3p=qx>Gr|CKzPNgys<(@0Wox8ql7N)Ch9xUkGTA%XQ|S?h{V2;xXY-UiUW0I|{L{8O5j>@z2i`4l+C)FC^bswzT>7uI zuv{$PX}5n+`l@5DJkss!`;xRA`A&-=U|OYj8~lfG4Wsuum!4JDoz^{N=9csINm>qX zvHmM>S#_VLS5DI7sB*{klBRVjNz37FXL^*T$G(v;sZ%=y5rqWIt%Jh|vpu?XkfybW zc!!q5n;F%(^t4?MqgPdW=%Ib9m*I#}+bVU|EN4f$YQ zYB-CJ6^DjxN-}!WG^CN12jyks#TM23X&eJcailEl+m)v3p-bcY`)JH?$RDL4A8DOT z^KrSKM$|8=Ow(hsG>wMRz&l~NIKNo$m8+dfZKYn0Ul7SR`V1)-yfU}p){W{CbrH5h z`gPSS?T^%!KnFA52VGe?_B3;>+yo8L$4s70uRwa|Ezkc?yozqL`gw~4c`b6>3wqb% z8YIsf5I1NX>Bv!d)4rAO|F*8lThx|!Dz9gfr%pm%bJV|typ$)P?MUx-%G&^a6FI#h zo2N)l_w7)xo(W#M{k&wh&#RHsAYIC8o5SQ34&_b6CH8D5@_MFt>M2juqV_6-37hJ) z2^kya;&`e1RZU-M^a@N2M;YM#O6(u)C+(eU>$IL-S*7jl8q$c(;(JlKQ*Tjta7=@; z3+?OR-wCZ}0WYRi4IOeq4>nln(H1-7gUs?CP+FXKfS-;$DGi1l83~Pa+17z0{D6jZ zVhFo5)cy{W&vRoMA{pX>Hz~&r@DH+aXim)l^2>Wdd;M}(@tE_DyPIQ}3+F!ehLGkvhB+ zX+*F4xBmz&@|%ARUnn1k+8) z=9P$}vw00HEA2gTPf9R7s|STAjw29)rT7$n3iALEqNe) zr_Q`Q!gQp)6Zx=yDIc}rS@OxMd%~VXx@X~{@nL?@-BHd(krv{GFZy}8JaP{2rG!Bg zwP4Ne{4z9%>lrwGLKo%CJuaarJha@v9}RYguU?4LOI^|4Xk9ViqC<07zAo>>b{&6q&Bk#4e5f(XO zY-;3)_c|#H_qPE?M;`ji0z`?8c|=*Z2>LNxOamQ?`X}l)_2-C*Qsv= z4M0trLHezHz7cpL^IB;5JeK5>Pw8tZaHgSgmy2lAHLO@K`6i<;Bfj;EAtR>y{!PXwZ??AUPr5 z(RU!8yz|nsuzj*jBD?;ryUJfmc0fcLI!h-}X6owWS8h4ac$Swqgk|X}^Jm>i{_)r- z+UCl%w2R5QL;gMoF^q`mGtUKtd1;=kKelPeFoKZ}(FY65>T3}-@}W4*z&?UwR4W5% zFNYAm_A$-qqew3FV5hHXOf#tdS;v$$Cle`aBX85Doh`4DH|dGZL;F@8J#-wYh#A9LPfQ>#f^ zMcPUE1CcN|{q zVx$|`&e>0q4&{|MPYp}EqD>dMtgLYxJU5wd(@z2sY3O1(EHHS9H-)JjRM)oCtsg*I z;luQU{8}QxM`k}*WR7v3k6-CXSo>?rUipAsipo8#4M0wbKEdq=CqV-=We)(KB})_Z zcGM3Rqkgbh)_zcYphHL54U!Y`i~2#zg1F#S>Ja^ak)0X0xt}5kUVppH8n2cpE9coY)-JS_~g^NM!~ zo~Yc6)4msVA^G4D$$LB9p)J$*A@D!4+3qbn=|}$rf#+Fzpg;QOV6EhH5M`XzfzeNs z<*>bEhYDIJkq+>k$kl-@gmXw^zlsoIjHljvfX|d>j+AE2_6VC!-dD7JQkMpm?OR4S z<9iL4-=i3_ll?*bK8?7y;L0^I?L|a5mC3-eXr7e0^PLEFjqh(N54N{|vSF1q$$vf0 zV;AxmdDsabhM#(=JdnS;EsXH=l^gPz7-_H!$u0;92!mrhc!VB%9eDYQE3hrVRDY?| zERV{9c7tJ#{rF_xz$e=qpVV7Esh@np_Q~@F_R0OJgmX@J*i-vC?1LEnG*~WpxD|QB z(7#!k=52EP&JIdQUZ^wAU_GjKDO;HkI?=vBi%(vgCRLm5k%6r#6mM<&+U1vS- z2WA0t>x25mddO}6*`1`L4BR@H^D)_3?R6V|y~-%39zKj9NehgA$BvD#zh(_J)|B>9(e3}r}fh=Q4W-s$f5t!MoH7(R)B~!bmY;rl>-Y5vt$aR+)0=G5~lh2 z7M_#W`L#-8Es!DaoE?@Bm+c}YXTJLja)EJhnh(akmk?xiMlj7==OzdB{mRo1BCW_E z#gl$ox*bnNW)A1@M44yuwBO=w$I}l1Pk74y{7>?tPPlS9>VEWP^D*^vOCCYd7v)j) ziZ+KZ$YR&~hy=%Q);qAui+l-hIxf1V`K+z;AVZajh50VlnF{Rbl8bc{Fh-MR#CqAcW_ddv<)@w9v@^Fh3VW;7mw zU6AxD`$rKLeiOPnAAJVRyoR-(65{EUr^l~s4b;`W7H<%r%F_=6Pk36XH96UK%vl&= zKI|V|J)QN5NTA^Zf`eUrcOJoU@5ALjoXQPyk$k|9%4FB?!_PWoKEzeI6Nhq8 z8zA$DW(qON+{(bb8zKSgnlN}rZD9X`p6tGjuG>6j1WIj$(+%B|Oz>O9iGv* zP4Gu^e79SAti$&^YhuJvebRbG+4|Ovw=3s6KwrvPl{FSQ>45c4$8xaGPPUQN7C!H8 z63lqW7xLd?a1ZQ$o*w0gWz%|4xf5T@>jRheUGZU4M>ZQBZ_St}m1ES8vhCQq+)jTJ z^Hkf(fHp57gVZ@FJCp%cO=Q6GXqj9Y=s3WY!JWXp8X2(vc!p)L>+7J&@+)1o{b>u! zImc2kK5f5eeFwqPFgoEqhG5RS^0_T}+BnE1u`gk}x+x-^)D6a|JSqf1;giDl0P_L! zv3ZKGof=2kZ)4xaIHuEg@j*O*#>nq6UuINB11VzymYKj=S;-nY?UfCWaU64V92Psu zHk<SGy)Iw0;z{R35qj?$UE@`Zh8UdOv3A2~D-JfYFieVS3#2jqLFpkv-Of z8JbHqqFP=uncT<=2l9RTfV%Juc;k zG}+FioNLv@oEYVlpqq-PJ~91|D-k(So{~@UyoAL0Q@1g5XY4iSuT@v-Z*W1g7DP

U$hr3TY@oC(ht=J?kb%$+qhq#&{vf-hWqY@#YptPV<#w+_R!#Y&PjlNf z$5quC9hXNln_i&>%ljyBn78B~n+DpG z%YHkoB1&j*JmD>2TB>FYh{9R+rx<{R%ot9`9bW{@n)yhfcBA;)=)ETx-=&6i{B%joIIMPN)6xSLi zzj(S1&@<`fEj`9l$Ego|YTl%;VR*-)cX6C$`C7o0H1_FGQ)XH)pUhPVYM{-Z{u5xq|!?v^-S^yOBBDQ78n5gs_r|7y#v z{qs)B{W&L}Z%4T&k$+U~5(047T5i%|+MSg9%T7Muj&dJF{!zL4QUG_Y%wRF2*ZV4(xMJN8wk^MODh9Miy! zeFHc8v-(l?S8u`v{bam2m#?1!B<3mkt-((Fy6wg;?{V@dTw}QlL(08f{y&|_|65bW zpK% zQ>WDLyrYf3)PZx1MVyC$zkuhhGS2dsy1^S(gI0C(E@>~5nb3oo(3fOFm5re*#R{=lV4)Z;!pE%*^WpxbAQw$S2|G zL$l!HugicVuW|PB!}20dgE*PeG5ipR_T`RkaNf299P0gcbVNQw@}eAQgpOp$hc8%u z3XbvOIOTSyjJc?mhWKp3Xc1+LcZTs#L^w_EH+_; z_0W7?UdETfomCuB+d>j47j%60CHUu3bxt_j^b1pP=)&$d5UT)6UJ(ii^*x&@QJov6RpW-tQK0ZQtv$Elbogk>0CV4CsrmkRqZTBbejOyf# z?bh)_!_NfHJ~J3g)5nX4j?u~T+3wSTJ+t9_@-=0Ij zySrJhcH5X*>l_J!z&D2~*J3@n33zuT@p>D61Cv4WDxR>PDAOJ?;?TsQvvS@&j13~- zC==qHz%vt1BxmsQ!26ygUah^}3Rmh&J-@Pqqu&ix(mVj%*9&e^k7OJwquyu`T%KMt zFDf=2=4N%+oE#s6+#dF=#KZV#&z4tu&3m2jW6AK?S1n zXWg9}+Verokuw4Dl@9Es!MAYMtIGr8_k2=YV_VF*@-FrHGMirVESJMg9OK)tBV^`t z9n$~(l=H&{n-65V=krtXq3FcLJkp+jp2|3w+@@h0{c1XXDtYiY=@9R0Q;9>ur+7TK zb3C||;TGUMJs5AwIqqBV52HByhTx}<>?SX?N$Gz(JO^}MAVV9m8CcRU6!dUxrnv#} zx0(39L#P>#v0KiZfuC_WG~$Va{_~suKLhmZy4&p#%=v%A6uxeh!?awzd@*omGH|0~ zSk2Lo!W(fHhT)pyVk6u$!*K1viY#*;bRW*ZO&{5+xWOP?b8yuxND2?olk2*}arNlc z2!CrEd~4PPpM1Y_5WaJiD)}Zazc3tEk4uec|7He0mucN&P?h#ahU4lnr%^ed7>=(; znF{{R;Qi0C@r}ewl(>;Ob>!2-a4lu>P24YJ;6_KZIl4z4{w)JnkN&hriAMbX&k$S{ zhLzpku?*adBS4k*-e+gwCy(_MT$FF`&BJibah(xvR-45%xjl}JZx@k__s(V0b&u8* zx_R($PX=y$oMZew2*y!+?;nWk9PMY0L=^f=ga7Z~A3W?tVG?=HM4>Qc=sRi5QH2pt z>jTq}jyWok^+Wz29gZu4Auf6OiGjE-FEY%Gc=`1KX{_L-$t(R255#roJMtm_e>^Zv zvaIC)F9+f}^i#6@r-5lmKRyeP^v!=z`s=FbJM^tpWSI|Qx@S)Yeb}MC;~9yMc6z<( zBa?YVZQ2@8;-YNrKIC*l@{;>LAK+`EV2+7)``;l6BKTmA7En{+P@#XW{n zMQ!x@OT%!@v4&CE8bfiVOA}n|vAKRD12;apuJ0JMDBZhun$EH3lgQ8f11VXbaejoy z?*PO%|1=tgZ!)0#iJ#RzgnshaJ1Gb8|7K7*BK(*><@KeZ_=Dy3jh&`*l}qfy3Bh%1D9h9L`VE( z^&7yE)lkyG`}w}CF`k~1qh)w7Bd;)VN|nizvNQifOX`k$cou2G#_U_ppecP$d}NoD zgSc5^K;k;bdkHSaX#3tgfG)nGXGu1y8c*S{1j9> zK52)163>iP5hcS5?zC4tvoNpa`4d~7^uaY6{}&Pu%OZ5*!(cSt^u6Ze^HL!`gvG`W z{YN0{cf0@Hp?>%MttoTze}x0;_nZ8;+rH0AUi}9(XnEcv@tCN9Jlw+&R32t*J~;lL zC4K*)0h<0R65szZzl|S%oy5bUAb(l^zxAkp!~R`|UVGoygg!P3fxh{-o%^G> z_(SO_{T|ra|9>yifBovyPw_M4h+gXZV$S<~JO2#{dp$8KWy=1LROLSG|B+aGnHU!u ziI2KUh19ob#JeF2Pd`+IESMkXJGT3GAnSVA{{ay{VcxU)Ka67@f05}OHZ5@Jl&w%{{f1Y$MntpAAe}PvElt6O=$etOMgG%oy5@kNXnrImmr6 zAwMu?d4rvwFz=%(+bLP;3Jr?t(S)(B5l*zznsR~8PyAeh{*<%R+UN}CZzq05aN^C$ zn%4B&*_)1ugE`v1e{^!bIO`v_SSz0REy*Xjd6skzAntdZINjW;aerisjz?m@DbxL_ z8wXPhav~edt4@4sDtXq$IADLrnO-YI(#Jga#6Jj(H#60*@Gr#hXe>(nFURnb=12Hf zV)(Se$>Y}yJhAgh%l4mB{Tq=OhxLMqr%hb6S;nT>znk#XCLWt+|BWUtkp{Bg|6;;Z zn_`%Tafb)Q!A|U-o624cVp_)Ela6=RQy}lY|GGlw_n(u0z4E539j4A0_o_I~u1=Ws z2d*DnS8X>tm0q2DIpwF&-lScG^?3wr=uL+8M*{1Q&s^x>%eYq0Gh^L?ed737eEecI zfb-XwIPk%f&nC6Y!UqVgTD$34^_R69Pe%T7FM9SIQSCKb<*b?&N7Wu-ZNFPp@ zz?~;JB4^C8@mAudVo%nAuz_7y9n^LKz2xagq2R@5zjju@5sDu6YIwu*A&C`FSKG<$ zGX8Z+0bqGMgd)ghqe%ld zm1oVHnlf*aKYX;6$@etpm(|{+0Z64s*(4Ags9;F~%bfTjhQM!Cnh=_7MUexe#kaJI zub=8z%QEm)ocv+=>ZLLlL_z$ZF`X*K5=Z{wCes`J;uj z`*_e)$e>@V)UAlC<_|KX(HItLobFo%kB=;U1WE_sr7Gfk~(ViO++L?w5t~W zFb`Q?2A59BEaoJa9P!I^Q6y-#W!wIc)+C7k!0t`z%A#pNHeIb&^;SAHTf6R;B9X=? zww{;@i{gaa)@l7!(ain@K<*7x3ZYY9Pi{h~Tz@jUJZ3 z*C21RlB1E5OG8a60R?7ABSPxndMFJ}OTP zM~L4Il&RJxn=)A}OL3s{lx7(S@?5L(fwM$0#X{|62s1NIC>bE(MC@8M4u>__8Y*oA zy+&C!+hO{s%>W+Y13T*&Fk9$k$|`ER9yYs`vDvMR^9`)O==e+GN6Cv=TW?iaa^u5s z0oeH06PaSLppnKGM}}C$u9{6*HBZiKKv7HO`sG%8eSHO;ZL`)!hd}|9;v&T#A(gx9 z;9N?APNdv!RReFa#%|fW+->1Va=FJTWzNb&C6-Yk@~e?3U~0C}UXLKUy9XnI7+nJ~ zx=ku&mR0X_0#f!r*B3)YMY6eTe02C!HocqR(Vs}d>+ z;+z}6`m!`0lYivJYG~v~YWNMMQtSno>o>|S)?CGlHCOe5h#7ZD1XxGQEr|bU?8R~? zz=k@O$ly0zVmZc4-I6mbN1A|Hk1`p}^~10R7AL}bp%ci$o)-k0x5=Vd?$5#?SaJyj zo1a0j948P^50G71{#mBtiKI5;aZ$^FOO78BR5)nDZ#kTH{KsNH7L6jD8JwIJ{jVso zh>;1#32G6x(ST&w#z#viIDL)yQP_>|&rQ%AFm=)_c*uf=XoHO8#HZ^KqIUuot+PJ+ z-w^Kl;+peuv0RS`TY~=+2PkArE z<_Z>Ej;F?WrB#QigvhDg)w;)XPcfeb4Lt3KI>y5nTlVwLCoB?l h;Y4s=b=PV&Zef&fLFmUDs`%Lfp%dYYSQ%Z2_kW@oE9d|K literal 0 HcmV?d00001 diff --git a/lab_2/bootloader/device_tree.c b/lab_2/bootloader/device_tree.c new file mode 100644 index 000000000..1b079ae2a --- /dev/null +++ b/lab_2/bootloader/device_tree.c @@ -0,0 +1,81 @@ +#include "include/device_tree.h" +#include +#include + + +void header_parser(){ + +} + +#include +#include + +unsigned long* mock_load_file() { + FILE *file = fopen("bcm2710-rpi-3-b-plus.dtb", "rb"); + if (!file) { + perror("Failed to open file"); + return 1; + } + + // Get the size of the file + fseek(file, 0, SEEK_END); + long fileSize = ftell(file); + rewind(file); + + // Allocate memory to hold the entire file + unsigned char *buffer = (unsigned char *)malloc(fileSize); + if (!buffer) { + perror("Failed to allocate memory"); + fclose(file); + return 1; + } + + // Read the entire file into the buffer + size_t bytesRead = fread(buffer, 1, fileSize, file); + if (bytesRead != fileSize) { + perror("Failed to read file"); + free(buffer); + fclose(file); + return 1; + } + + return (unsigned long*)buffer; +} +device_tree_header myHeader; + +int main(){ + uint32_t* start; + uint32_t* dtb = mock_load_file(); + start = dtb; + // __builtin_bswap32() is a GCC built-in function to convert to the system's endianness.(RPi uses little-endian) + myHeader.magic = __builtin_bswap32(*dtb++); + if ((myHeader.magic - 0xd00dfeed) != 0) { + printf("DTB magic number doesn't match!\r\n"); + return 1; + } + myHeader.totalsize = __builtin_bswap32(*dtb++); + myHeader.off_dt_struct = __builtin_bswap32(*dtb++); + myHeader.off_dt_strings = __builtin_bswap32(*dtb++); + myHeader.off_mem_rsvmap = __builtin_bswap32(*dtb++); + myHeader.version = __builtin_bswap32(*dtb++); + myHeader.last_comp_version = __builtin_bswap32(*dtb++); + myHeader.boot_cpuid_phys = __builtin_bswap32(*dtb++); + myHeader.size_dt_strings = __builtin_bswap32(*dtb++); + myHeader.size_dt_struct = __builtin_bswap32(*dtb++); + printf("%lu\n", myHeader.off_dt_struct); + printf("%lu\n", myHeader.totalsize); + + // jump to structure + uint32_t* structure_ptr = (uint32_t *)(start + myHeader.off_dt_struct); + while(1){ + uint32_t token = __builtin_bswap32(*structure_ptr++); + if(token == FDT_BEGIN_NODE){ + printf("begin"); + } + } + + //The node’s name as a null-terminated string + + + +} diff --git a/lab_2/bootloader/include/device_tree.h b/lab_2/bootloader/include/device_tree.h new file mode 100644 index 000000000..6846d0cba --- /dev/null +++ b/lab_2/bootloader/include/device_tree.h @@ -0,0 +1,34 @@ +#include "stdint.h" + + +typedef struct fdt_header { + // 0xd00dfeed (big-endian) + uint32_t magic; + uint32_t totalsize; + // offsets of each block from start + uint32_t off_dt_struct; + uint32_t off_dt_strings; + uint32_t off_mem_rsvmap; + + uint32_t version; + uint32_t last_comp_version; + // physical ID of the system’s boot CPU + uint32_t boot_cpuid_phys; + uint32_t size_dt_strings; + uint32_t size_dt_struct; +} device_tree_header; + +#define ALIGN_MEMORY_BLOCK 8 + +/* All tokens shall be aligned on a 32-bit boundary */ +#define ALIGN_STRUCT_BLOCK 4 + +/* tokens used for structure block */ +#define FDT_BEGIN_NODE 0x00000001 +#define FDT_END_NODE 0x00000002 +#define FDT_PROP 0x00000003 +#define FDT_NOP 0x00000004 +#define FDT_END 0x00000009 + + +void header_parser(); diff --git a/lab_2/bootloader/include/stdint.h b/lab_2/bootloader/include/stdint.h new file mode 100644 index 000000000..de06b2895 --- /dev/null +++ b/lab_2/bootloader/include/stdint.h @@ -0,0 +1,9 @@ + +typedef unsigned int uint16_t; + +typedef unsigned long uint32_t; + +typedef unsigned long long uint64_t; + +typedef float float32; +typedef double float64; \ No newline at end of file diff --git a/lab_2/bootloader/reader.py b/lab_2/bootloader/reader.py new file mode 100644 index 000000000..19a5e759a --- /dev/null +++ b/lab_2/bootloader/reader.py @@ -0,0 +1,9 @@ +with open("./bcm2710-rpi-3-b-plus.dtb", "rb") as f: + data = f.read() +# Filter out the 0x00 bytes +filtered_data = bytes(b for b in data if b != 0x00) + +# Print the filtered binary data +print(filtered_data) + +#print(data) \ No newline at end of file From 25dbcd2d6aaa54c39b851fb92787bda3efd7b397 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Wed, 12 Jun 2024 21:06:26 +0800 Subject: [PATCH 06/23] modify code to accept device tree dtb (unfinished) --- lab_2/README.md | 40 ++----------- lab_2/bootloader/Makefile | 9 ++- lab_2/bootloader/device_tree.c | 87 +++++++++++++---------------- lab_2/bootloader/include/stdint.h | 2 +- lab_2/bootloader/kernel_uploader.py | 2 +- lab_2/bootloader/main.c | 9 ++- lab_2/bootloader/start.S | 6 +- 7 files changed, 64 insertions(+), 91 deletions(-) diff --git a/lab_2/README.md b/lab_2/README.md index cdb3a5992..ff2c23e3f 100644 --- a/lab_2/README.md +++ b/lab_2/README.md @@ -1,34 +1,6 @@ -Tutorial 03 - UART1, Auxilary mini UART -======================================= - -It is time for the famous Hello World example. We're going to write on the UART1 first, as it's easier to program -as it has a fixed clocked frequency. - -NOTE: qemu does not redirect UART1 to terminal by default, only UART0, so you have to use `-serial null -serial stdio`. - -Gpio.h ------- - -We have a new header file. This defines the base MMIO address, and the GPIO controller's addresses. This file -going to be very popular, as many devices need it. - -Uart.h, uart.c --------------- - -A very minimal implementation. - -`uart_init()` initializes the device and maps it to the GPIO ports. - -`uart_send(c)` sends a character over the serial line. - -`uart_getc()` receives a character. The carrige return character (13) will be converted into a newline character (10). - -`uart_puts(s)` prints out a string. On newline, a carrige return character will also be sent (13 + 10). - -Main ----- - -First, we have to call the uart initialization code. Then, it'll return "Hello World!". If you've purchased an USB -serial cable, you should see it on minicom's screen. After that every character typed in minicom will be -echoed back. If you haven't turned off local echo, that means you'll see every pressed key twice. - +1. python UART transfer data loss +2. init UART register to avoid garbage pending +3. link loader can arrange the .text section freely + - why align +4. wze is for halting CPU that is not id 0 +5. \ No newline at end of file diff --git a/lab_2/bootloader/Makefile b/lab_2/bootloader/Makefile index 22a62f2b9..2a00a5890 100644 --- a/lab_2/bootloader/Makefile +++ b/lab_2/bootloader/Makefile @@ -46,7 +46,14 @@ clean: rm kernel8.elf *.o >/dev/null 2>/dev/null || true run: - qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -d in_asm + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -dtb bcm2710-rpi-3-b-plus.dtb + +run_asm: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -dtb bcm2710-rpi-3-b-plus.dtb -d in_asm + + +run_stdio: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial stdio -display none -dtb bcm2710-rpi-3-b-plus.dtb debug: qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_2/bootloader/device_tree.c b/lab_2/bootloader/device_tree.c index 1b079ae2a..6370eb7b7 100644 --- a/lab_2/bootloader/device_tree.c +++ b/lab_2/bootloader/device_tree.c @@ -1,56 +1,19 @@ #include "include/device_tree.h" -#include -#include +#include "include/uart.h" +// #include +// #include - -void header_parser(){ - -} - -#include -#include - -unsigned long* mock_load_file() { - FILE *file = fopen("bcm2710-rpi-3-b-plus.dtb", "rb"); - if (!file) { - perror("Failed to open file"); - return 1; - } - - // Get the size of the file - fseek(file, 0, SEEK_END); - long fileSize = ftell(file); - rewind(file); - - // Allocate memory to hold the entire file - unsigned char *buffer = (unsigned char *)malloc(fileSize); - if (!buffer) { - perror("Failed to allocate memory"); - fclose(file); - return 1; - } - - // Read the entire file into the buffer - size_t bytesRead = fread(buffer, 1, fileSize, file); - if (bytesRead != fileSize) { - perror("Failed to read file"); - free(buffer); - fclose(file); - return 1; - } - - return (unsigned long*)buffer; -} device_tree_header myHeader; -int main(){ +void header_parser(uintptr_t dtb_address){ uint32_t* start; - uint32_t* dtb = mock_load_file(); + //uint32_t* dtb = mock_load_file(); + uint32_t* dtb = dtb_address; start = dtb; // __builtin_bswap32() is a GCC built-in function to convert to the system's endianness.(RPi uses little-endian) myHeader.magic = __builtin_bswap32(*dtb++); if ((myHeader.magic - 0xd00dfeed) != 0) { - printf("DTB magic number doesn't match!\r\n"); + uart_puts("DTB magic number doesn't match!\r\n"); return 1; } myHeader.totalsize = __builtin_bswap32(*dtb++); @@ -62,15 +25,13 @@ int main(){ myHeader.boot_cpuid_phys = __builtin_bswap32(*dtb++); myHeader.size_dt_strings = __builtin_bswap32(*dtb++); myHeader.size_dt_struct = __builtin_bswap32(*dtb++); - printf("%lu\n", myHeader.off_dt_struct); - printf("%lu\n", myHeader.totalsize); // jump to structure uint32_t* structure_ptr = (uint32_t *)(start + myHeader.off_dt_struct); while(1){ uint32_t token = __builtin_bswap32(*structure_ptr++); if(token == FDT_BEGIN_NODE){ - printf("begin"); + uart_puts("Start\n"); } } @@ -79,3 +40,35 @@ int main(){ } + +// unsigned long* mock_load_file() { +// FILE *file = fopen("bcm2710-rpi-3-b-plus.dtb", "rb"); +// if (!file) { +// perror("Failed to open file"); +// return 1; +// } + +// // Get the size of the file +// fseek(file, 0, SEEK_END); +// long fileSize = ftell(file); +// rewind(file); + +// // Allocate memory to hold the entire file +// unsigned char *buffer = (unsigned char *)malloc(fileSize); +// if (!buffer) { +// perror("Failed to allocate memory"); +// fclose(file); +// return 1; +// } + +// // Read the entire file into the buffer +// size_t bytesRead = fread(buffer, 1, fileSize, file); +// if (bytesRead != fileSize) { +// perror("Failed to read file"); +// free(buffer); +// fclose(file); +// return 1; +// } + +// return (unsigned long*)buffer; +// } \ No newline at end of file diff --git a/lab_2/bootloader/include/stdint.h b/lab_2/bootloader/include/stdint.h index de06b2895..3ddcc9b17 100644 --- a/lab_2/bootloader/include/stdint.h +++ b/lab_2/bootloader/include/stdint.h @@ -4,6 +4,6 @@ typedef unsigned int uint16_t; typedef unsigned long uint32_t; typedef unsigned long long uint64_t; - +typedef unsigned long uintptr_t; typedef float float32; typedef double float64; \ No newline at end of file diff --git a/lab_2/bootloader/kernel_uploader.py b/lab_2/bootloader/kernel_uploader.py index 12abe17ba..852ad9d26 100644 --- a/lab_2/bootloader/kernel_uploader.py +++ b/lab_2/bootloader/kernel_uploader.py @@ -4,7 +4,7 @@ import sys import time -port = '/dev/pts/4' +port = '/dev/pts/2' s = serial.Serial(port, baudrate=115200) def read_line(s): diff --git a/lab_2/bootloader/main.c b/lab_2/bootloader/main.c index 1bbd110ec..e8be04b8c 100644 --- a/lab_2/bootloader/main.c +++ b/lab_2/bootloader/main.c @@ -26,6 +26,8 @@ #include "include/uart.h" #include "include/utils.h" #include "include/mbox.h" +#include "include/stdint.h" +#include "include/device_tree.h" void load_img(){ unsigned int size = 0; @@ -47,14 +49,11 @@ void load_img(){ } -void relocator(int argc, char* argv[]){ - asm volatile( - "mov x10, x0" - ); +void relocator(uintptr_t dtb_address){ uart_init(); + // header_parser(dtb_address); load_img(); asm volatile( - "mov x0, x10;" "mov x30, 0x80000;" "ret;" ); diff --git a/lab_2/bootloader/start.S b/lab_2/bootloader/start.S index f4d0dfec4..b086305c4 100644 --- a/lab_2/bootloader/start.S +++ b/lab_2/bootloader/start.S @@ -22,8 +22,10 @@ _relocate: sub w2, w2, #1 cbnz w2, 2b - // jump to relocated C code, should not return -3: bl relocator-0x20000 + +3: // Device tree address has been moved from x0 to x10 within the bootloader. + mov x0, x10 + bl relocator-0x20000 b _start From 3a400204f0f34e6c1293648123c634618f5d3560 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Thu, 13 Jun 2024 03:47:31 +0800 Subject: [PATCH 07/23] add lab3 and finish basic exercise 1 --- lab_3/Makefile | 52 +++++++++ lab_3/Makefile.gcc | 52 +++++++++ lab_3/README.md | 6 + lab_3/bootloader/Makefile | 59 ++++++++++ lab_3/bootloader/bcm2710-rpi-3-b-plus.dtb | Bin 0 -> 35026 bytes lab_3/bootloader/device_tree.c | 74 +++++++++++++ lab_3/bootloader/include/device_tree.h | 34 ++++++ lab_3/bootloader/include/gpio.h | 45 ++++++++ lab_3/bootloader/include/mbox.h | 48 ++++++++ lab_3/bootloader/include/stdint.h | 9 ++ lab_3/bootloader/include/uart.h | 30 +++++ lab_3/bootloader/include/utils.h | 4 + lab_3/bootloader/initramfs.cpio | Bin 0 -> 1024 bytes lab_3/bootloader/kernel_uploader.py | 65 +++++++++++ lab_3/bootloader/link.ld | 55 ++++++++++ lab_3/bootloader/main.c | 60 ++++++++++ lab_3/bootloader/mbox.c | 64 +++++++++++ lab_3/bootloader/reader.py | 9 ++ lab_3/bootloader/start.S | 43 ++++++++ lab_3/bootloader/uart.c | 127 ++++++++++++++++++++++ lab_3/bootloader/utils.c | 61 +++++++++++ lab_3/config.txt | 2 + lab_3/rootfs/hello.txt | 1 + lab_3/rootfs/link.ld | 44 ++++++++ lab_3/rootfs/makefile | 36 ++++++ lab_3/rootfs/user_program | Bin 0 -> 5704 bytes lab_3/rootfs/user_program.S | 13 +++ lab_3/rootfs/user_program.elf | Bin 0 -> 928 bytes lab_3/rootfs/user_program.img | Bin 0 -> 24 bytes lab_3/shell/Makefile | 60 ++++++++++ lab_3/shell/cpio.c | 102 +++++++++++++++++ lab_3/shell/exception_vector.S | 101 +++++++++++++++++ lab_3/shell/exceptions.c | 25 +++++ lab_3/shell/include/cpio.h | 21 ++++ lab_3/shell/include/gpio.h | 45 ++++++++ lab_3/shell/include/mbox.h | 48 ++++++++ lab_3/shell/include/stdint.h | 9 ++ lab_3/shell/include/uart.h | 30 +++++ lab_3/shell/include/utils.h | 7 ++ lab_3/shell/initramfs.cpio | Bin 0 -> 12288 bytes lab_3/shell/link.ld | 44 ++++++++ lab_3/shell/main.c | 107 ++++++++++++++++++ lab_3/shell/mbox.c | 64 +++++++++++ lab_3/shell/start.S | 44 ++++++++ lab_3/shell/uart.c | 121 +++++++++++++++++++++ lab_3/shell/utils.c | 105 ++++++++++++++++++ 46 files changed, 1926 insertions(+) create mode 100644 lab_3/Makefile create mode 100644 lab_3/Makefile.gcc create mode 100644 lab_3/README.md create mode 100644 lab_3/bootloader/Makefile create mode 100644 lab_3/bootloader/bcm2710-rpi-3-b-plus.dtb create mode 100644 lab_3/bootloader/device_tree.c create mode 100644 lab_3/bootloader/include/device_tree.h create mode 100644 lab_3/bootloader/include/gpio.h create mode 100644 lab_3/bootloader/include/mbox.h create mode 100644 lab_3/bootloader/include/stdint.h create mode 100644 lab_3/bootloader/include/uart.h create mode 100644 lab_3/bootloader/include/utils.h create mode 100644 lab_3/bootloader/initramfs.cpio create mode 100644 lab_3/bootloader/kernel_uploader.py create mode 100644 lab_3/bootloader/link.ld create mode 100644 lab_3/bootloader/main.c create mode 100644 lab_3/bootloader/mbox.c create mode 100644 lab_3/bootloader/reader.py create mode 100644 lab_3/bootloader/start.S create mode 100644 lab_3/bootloader/uart.c create mode 100644 lab_3/bootloader/utils.c create mode 100644 lab_3/config.txt create mode 100644 lab_3/rootfs/hello.txt create mode 100644 lab_3/rootfs/link.ld create mode 100644 lab_3/rootfs/makefile create mode 100755 lab_3/rootfs/user_program create mode 100644 lab_3/rootfs/user_program.S create mode 100755 lab_3/rootfs/user_program.elf create mode 100755 lab_3/rootfs/user_program.img create mode 100644 lab_3/shell/Makefile create mode 100644 lab_3/shell/cpio.c create mode 100644 lab_3/shell/exception_vector.S create mode 100644 lab_3/shell/exceptions.c create mode 100644 lab_3/shell/include/cpio.h create mode 100644 lab_3/shell/include/gpio.h create mode 100644 lab_3/shell/include/mbox.h create mode 100644 lab_3/shell/include/stdint.h create mode 100644 lab_3/shell/include/uart.h create mode 100644 lab_3/shell/include/utils.h create mode 100644 lab_3/shell/initramfs.cpio create mode 100644 lab_3/shell/link.ld create mode 100644 lab_3/shell/main.c create mode 100644 lab_3/shell/mbox.c create mode 100644 lab_3/shell/start.S create mode 100644 lab_3/shell/uart.c create mode 100644 lab_3/shell/utils.c diff --git a/lab_3/Makefile b/lab_3/Makefile new file mode 100644 index 000000000..015d9ea3d --- /dev/null +++ b/lab_3/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles +BOOTLOADER_BIN = kernel8.img +all: clean kernel8.img + +start.o: start.S + $(GCC) $(CFLAGS) -c start.S -o start.o + +%.o: %.c + $(GCC) $(CFLAGS) -c $< -o $@ -g + +kernel8.img: start.o $(OBJS) + $(LD) -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + $(OBJCPY) -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -d in_asm + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_3/Makefile.gcc b/lab_3/Makefile.gcc new file mode 100644 index 000000000..77366f3cf --- /dev/null +++ b/lab_3/Makefile.gcc @@ -0,0 +1,52 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles + +all: clean kernel8.img + +start.o: start.S + $(GCC) $(CFLAGS) -c start.S -o start.o + +%.o: %.c + $(GCC) $(CFLAGS) -c $< -o $@ -g + +kernel8.img: start.o $(OBJS) + $(LD) -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + $(OBJCPY) -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_3/README.md b/lab_3/README.md new file mode 100644 index 000000000..ff2c23e3f --- /dev/null +++ b/lab_3/README.md @@ -0,0 +1,6 @@ +1. python UART transfer data loss +2. init UART register to avoid garbage pending +3. link loader can arrange the .text section freely + - why align +4. wze is for halting CPU that is not id 0 +5. \ No newline at end of file diff --git a/lab_3/bootloader/Makefile b/lab_3/bootloader/Makefile new file mode 100644 index 000000000..2a00a5890 --- /dev/null +++ b/lab_3/bootloader/Makefile @@ -0,0 +1,59 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles +BOOTLOADER_BIN = kernel8.img +all: clean kernel8.img + +start.o: start.S + $(GCC) $(CFLAGS) -c start.S -o start.o + +%.o: %.c + $(GCC) $(CFLAGS) -c $< -o $@ -g + +kernel8.img: start.o $(OBJS) + $(LD) -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + $(OBJCPY) -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -dtb bcm2710-rpi-3-b-plus.dtb + +run_asm: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -dtb bcm2710-rpi-3-b-plus.dtb -d in_asm + + +run_stdio: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial stdio -display none -dtb bcm2710-rpi-3-b-plus.dtb + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_3/bootloader/bcm2710-rpi-3-b-plus.dtb b/lab_3/bootloader/bcm2710-rpi-3-b-plus.dtb new file mode 100644 index 0000000000000000000000000000000000000000..a219bf3d5ca7a1e6d14618556f73a73911460911 GIT binary patch literal 35026 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 literal 0 HcmV?d00001 diff --git a/lab_3/bootloader/device_tree.c b/lab_3/bootloader/device_tree.c new file mode 100644 index 000000000..6370eb7b7 --- /dev/null +++ b/lab_3/bootloader/device_tree.c @@ -0,0 +1,74 @@ +#include "include/device_tree.h" +#include "include/uart.h" +// #include +// #include + +device_tree_header myHeader; + +void header_parser(uintptr_t dtb_address){ + uint32_t* start; + //uint32_t* dtb = mock_load_file(); + uint32_t* dtb = dtb_address; + start = dtb; + // __builtin_bswap32() is a GCC built-in function to convert to the system's endianness.(RPi uses little-endian) + myHeader.magic = __builtin_bswap32(*dtb++); + if ((myHeader.magic - 0xd00dfeed) != 0) { + uart_puts("DTB magic number doesn't match!\r\n"); + return 1; + } + myHeader.totalsize = __builtin_bswap32(*dtb++); + myHeader.off_dt_struct = __builtin_bswap32(*dtb++); + myHeader.off_dt_strings = __builtin_bswap32(*dtb++); + myHeader.off_mem_rsvmap = __builtin_bswap32(*dtb++); + myHeader.version = __builtin_bswap32(*dtb++); + myHeader.last_comp_version = __builtin_bswap32(*dtb++); + myHeader.boot_cpuid_phys = __builtin_bswap32(*dtb++); + myHeader.size_dt_strings = __builtin_bswap32(*dtb++); + myHeader.size_dt_struct = __builtin_bswap32(*dtb++); + + // jump to structure + uint32_t* structure_ptr = (uint32_t *)(start + myHeader.off_dt_struct); + while(1){ + uint32_t token = __builtin_bswap32(*structure_ptr++); + if(token == FDT_BEGIN_NODE){ + uart_puts("Start\n"); + } + } + + //The node’s name as a null-terminated string + + + +} + +// unsigned long* mock_load_file() { +// FILE *file = fopen("bcm2710-rpi-3-b-plus.dtb", "rb"); +// if (!file) { +// perror("Failed to open file"); +// return 1; +// } + +// // Get the size of the file +// fseek(file, 0, SEEK_END); +// long fileSize = ftell(file); +// rewind(file); + +// // Allocate memory to hold the entire file +// unsigned char *buffer = (unsigned char *)malloc(fileSize); +// if (!buffer) { +// perror("Failed to allocate memory"); +// fclose(file); +// return 1; +// } + +// // Read the entire file into the buffer +// size_t bytesRead = fread(buffer, 1, fileSize, file); +// if (bytesRead != fileSize) { +// perror("Failed to read file"); +// free(buffer); +// fclose(file); +// return 1; +// } + +// return (unsigned long*)buffer; +// } \ No newline at end of file diff --git a/lab_3/bootloader/include/device_tree.h b/lab_3/bootloader/include/device_tree.h new file mode 100644 index 000000000..6846d0cba --- /dev/null +++ b/lab_3/bootloader/include/device_tree.h @@ -0,0 +1,34 @@ +#include "stdint.h" + + +typedef struct fdt_header { + // 0xd00dfeed (big-endian) + uint32_t magic; + uint32_t totalsize; + // offsets of each block from start + uint32_t off_dt_struct; + uint32_t off_dt_strings; + uint32_t off_mem_rsvmap; + + uint32_t version; + uint32_t last_comp_version; + // physical ID of the system’s boot CPU + uint32_t boot_cpuid_phys; + uint32_t size_dt_strings; + uint32_t size_dt_struct; +} device_tree_header; + +#define ALIGN_MEMORY_BLOCK 8 + +/* All tokens shall be aligned on a 32-bit boundary */ +#define ALIGN_STRUCT_BLOCK 4 + +/* tokens used for structure block */ +#define FDT_BEGIN_NODE 0x00000001 +#define FDT_END_NODE 0x00000002 +#define FDT_PROP 0x00000003 +#define FDT_NOP 0x00000004 +#define FDT_END 0x00000009 + + +void header_parser(); diff --git a/lab_3/bootloader/include/gpio.h b/lab_3/bootloader/include/gpio.h new file mode 100644 index 000000000..52fa671d0 --- /dev/null +++ b/lab_3/bootloader/include/gpio.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#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)) diff --git a/lab_3/bootloader/include/mbox.h b/lab_3/bootloader/include/mbox.h new file mode 100644 index 000000000..e0e2e41f1 --- /dev/null +++ b/lab_3/bootloader/include/mbox.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/* a properly aligned buffer */ +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 MBOX_TAG_GETSERIAL 0x10004 +#define MBOX_TAG_REVISION 0x00010002 +#define MBOX_TAG_MEMORY 0x00010005 +#define MBOX_TAG_LAST 0 + +int mbox_call(unsigned char ch); diff --git a/lab_3/bootloader/include/stdint.h b/lab_3/bootloader/include/stdint.h new file mode 100644 index 000000000..3ddcc9b17 --- /dev/null +++ b/lab_3/bootloader/include/stdint.h @@ -0,0 +1,9 @@ + +typedef unsigned int uint16_t; + +typedef unsigned long uint32_t; + +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +typedef float float32; +typedef double float64; \ No newline at end of file diff --git a/lab_3/bootloader/include/uart.h b/lab_3/bootloader/include/uart.h new file mode 100644 index 000000000..245c358c8 --- /dev/null +++ b/lab_3/bootloader/include/uart.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +void uart_init(); +void uart_send(unsigned int c); +char uart_getc(); +void uart_puts(char *s); +void uart_hex(unsigned int d); \ No newline at end of file diff --git a/lab_3/bootloader/include/utils.h b/lab_3/bootloader/include/utils.h new file mode 100644 index 000000000..b993a5b68 --- /dev/null +++ b/lab_3/bootloader/include/utils.h @@ -0,0 +1,4 @@ +void set(long addr, unsigned int value); +void reset(); +int strcmp(char* a, char* b); +void cancel_reset(); \ No newline at end of file diff --git a/lab_3/bootloader/initramfs.cpio b/lab_3/bootloader/initramfs.cpio new file mode 100644 index 0000000000000000000000000000000000000000..e9c1dda97f1391b336871a2da59e34bd241fa43f GIT binary patch literal 1024 zcmeH@K@Ng26hv8j3b+87mIiQ%u_Pw0h!HOt3;y|ZOd9-B4l9R&fn>^y@5k6kI zmbaUt8zE&!W7VrbFV(b 0: + received_content = read_line(s) + print(received_content) + +with open("../shell/shell_kernel.img", "rb") as f: + sent_size = 0 # Initialize size counter + + byte = f.read(1) # Read the first byte + while byte: + s.write(byte) # Send the byte over serial + # s.flush() # Flush the output buffer + sent_size += 1 # Increment size counter + byte = f.read(1) # Read the next byte + + +assert sent_size == size +print("kernel sent successfully.") + +# get response of whether kernel is loaded successfully or not +time.sleep(1) +while(True): + while s.in_waiting > 0: + received_content = read_line(s) + print(received_content) + print("#", end=" ") + inp = input() + if(inp == ""): + continue + inp += "\n" + bytes_to_send = inp.encode('utf-8') + s.write(bytes_to_send) + #while s.in_waiting > 0: + # received_content = read_line(s) + # print(received_content) + time.sleep(1) \ No newline at end of file diff --git a/lab_3/bootloader/link.ld b/lab_3/bootloader/link.ld new file mode 100644 index 000000000..5d4536049 --- /dev/null +++ b/lab_3/bootloader/link.ld @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +SECTIONS +{ + . = 0x60000; + PROVIDE(_head = .); + .relocate : { + KEEP(*(.text.relocate)) + } + . = ALIGN(4096); + + .imgLoader : { + KEEP(*(.text.load_img)) + } + . = ALIGN(4096); + .text : { + KEEP(*(.text.boot)) + *(.text) + } + . = ALIGN(4096); + PROVIDE(_data = .); + .data : { *(.data .data.*) } + .bss : { + . = ALIGN(16); + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + _end = .; +} +__bss_size = (__bss_end - __bss_start)>>3; +__loader_size = (_end - _head)>>3; \ No newline at end of file diff --git a/lab_3/bootloader/main.c b/lab_3/bootloader/main.c new file mode 100644 index 000000000..e8be04b8c --- /dev/null +++ b/lab_3/bootloader/main.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#define MAX_BUFFER 10 +#include "include/uart.h" +#include "include/utils.h" +#include "include/mbox.h" +#include "include/stdint.h" +#include "include/device_tree.h" + +void load_img(){ + unsigned int size = 0; + unsigned char *size_buffer = (unsigned char *) &size; + uart_puts("enter kernel size now:"); + for(int i=0; i<4; i++) + size_buffer[i] = uart_getc(); + uart_puts("size-check correct\n"); + + uart_puts("Kernel size received: "); + uart_hex(size); + uart_puts("\n"); + + char *kernel = (char *) 0x80000; + while(size--) *kernel++ = uart_getc(); + + uart_puts("kernel-loaded\n"); + return; + +} + +void relocator(uintptr_t dtb_address){ + uart_init(); + // header_parser(dtb_address); + load_img(); + asm volatile( + "mov x30, 0x80000;" + "ret;" + ); +} diff --git a/lab_3/bootloader/mbox.c b/lab_3/bootloader/mbox.c new file mode 100644 index 000000000..b5b47c2f2 --- /dev/null +++ b/lab_3/bootloader/mbox.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "include/gpio.h" + +/* mailbox message buffer +* The buffer itself is 16-byte aligned as only the upper 28 bits of the address can be passed via the mailbox. +*/ +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 +#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) +{ + 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? */ + 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; +} diff --git a/lab_3/bootloader/reader.py b/lab_3/bootloader/reader.py new file mode 100644 index 000000000..19a5e759a --- /dev/null +++ b/lab_3/bootloader/reader.py @@ -0,0 +1,9 @@ +with open("./bcm2710-rpi-3-b-plus.dtb", "rb") as f: + data = f.read() +# Filter out the 0x00 bytes +filtered_data = bytes(b for b in data if b != 0x00) + +# Print the filtered binary data +print(filtered_data) + +#print(data) \ No newline at end of file diff --git a/lab_3/bootloader/start.S b/lab_3/bootloader/start.S new file mode 100644 index 000000000..b086305c4 --- /dev/null +++ b/lab_3/bootloader/start.S @@ -0,0 +1,43 @@ +.section ".text.relocate" +.global _relocate + +_relocate: + // relocate our code from load address to link address + ldr x1, =0x80000; // src address + ldr x2, =0x60000; // target address + ldr w3, =__loader_size +1: ldr x4, [x1], #8 + str x4, [x2], #8 + sub w3, w3, #1 + cbnz w3, 1b + + ldr x1, =_start + mov sp, x1 + + // clear bss + ldr x1, =__bss_start + ldr w2, =__bss_size +2: cbz w2, 3f + str xzr, [x1], #8 + sub w2, w2, #1 + cbnz w2, 2b + + +3: // Device tree address has been moved from x0 to x10 within the bootloader. + mov x0, x10 + bl relocator-0x20000 + b _start + + +.section ".text.boot" + +.global _start + +_start: + // jump to main function in C + bl 0x80000 + // halt this core if return +1: + wfe + b 1b + diff --git a/lab_3/bootloader/uart.c b/lab_3/bootloader/uart.c new file mode 100644 index 000000000..998d1509a --- /dev/null +++ b/lab_3/bootloader/uart.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "include/gpio.h" + +/** Auxilary mini UART registers + * Address & Description refer: https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf Page.8 + */ + +#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004)) +#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040)) +#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044)) +#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048)) +#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C)) +#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050)) +#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054)) +#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058)) +#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C)) +#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060)) +#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064)) +#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068)) + +/** + * Set baud rate and characteristics (115200 8N1) and map to GPIO + */ +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *AUX_ENABLE |=1; // enable UART1, AUX mini uart + *AUX_MU_CNTL = 0; + *AUX_MU_LCR = 3; // 8 bits + *AUX_MU_MCR = 0; + *AUX_MU_IER = 0; + *AUX_MU_IIR = 0xc6; // disable interrupts + *AUX_MU_BAUD = 270; // 115200 baud + /* map UART1 to GPIO pins */ + r=*GPFSEL1; + r&=~((7<<12)|(7<<15)); // gpio14, gpio15 + r|=(2<<12)|(2<<15); // alt5 + *GPFSEL1 = r; + *GPPUD = 0; // enable pins 14 and 15 + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; // flush GPIO setup + *AUX_MU_CNTL = 3; // enable Tx, Rx + /*EXTRA: Read from AUX_MU_IO until AUX_MU_LSR indicates no more data*/ + while (*AUX_MU_LSR & 0x01) { + // Read and discard the data + volatile unsigned int data = *AUX_MU_IO; + (void)data; // Prevent unused variable warning + } +} + +/** + * Send a character + */ +void uart_send(unsigned int c) { + /* wait until we can send */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20)); + /* write the character to the buffer */ + *AUX_MU_IO=c; +} + +/** + * Receive a character + */ +char uart_getc() { + char r; + /* wait until something is in the buffer */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01)); + /* read it and return */ + r=(char)(*AUX_MU_IO); + /* convert carriage return to newline */ + return r=='\r'?'\n':r; +} + +/** + * Display a string + */ +void uart_puts(char *s) { + while(*s) { + /* convert newline to carriage return + newline */ + if(*s=='\n') + uart_send('\r'); + uart_send(*s++); + } +} + +/** + * Display a binary value in hexadecimal + */ +void uart_hex(unsigned int d) { + unsigned int n; + int c; + for(c=28;c>=0;c-=4) { + // get highest tetrad + n=(d>>c)&0xF; + // 0-9 => '0'-'9', 10-15 => 'A'-'F' + n+=n>9?0x37:0x30; + uart_send(n); + } +} \ No newline at end of file diff --git a/lab_3/bootloader/utils.c b/lab_3/bootloader/utils.c new file mode 100644 index 000000000..d31e58159 --- /dev/null +++ b/lab_3/bootloader/utils.c @@ -0,0 +1,61 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC 0x3F10001c +#define PM_WDOG 0x3F100024 + +/** + * compare two string, given s1 and s2 + * return 0 if the both string are equal; + * return -1 if s1 is less than s2; + * return 1 if s1 is greater than s2 + */ +int strcmp(char* a, char* b){ + int value = 0; + while(*a != '\0' && *b != '\0'){ + if(*a < *b){ + return -1; + } + else if(*a > *b){ + return 1; + } + else{ + a++; + b++; + } + } + if(*a == '\0'){ + value++; + } + if(*b == '\0'){ + value--; + } + return value; +} + +/** + * set up given value to given address + */ +void set(long addr, unsigned int value) { + volatile unsigned int* point = (unsigned int*)addr; + *point = value; +} + + +/** + * reboot respberry pi + * if tick=0, reboot instantly; + * otherwise, wait for tick seconds to reboot + */ +void reset(int tick) { // reboot after watchdog timer expire + set(PM_RSTC, PM_PASSWORD | 0x20); // full reset + if(tick != 0){ + set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick + } +} + +/** + * clear reboot register + */ +void cancel_reset() { + set(PM_RSTC, PM_PASSWORD | 0); // full reset + set(PM_WDOG, PM_PASSWORD | 0); // number of watchdog tick +} \ No newline at end of file diff --git a/lab_3/config.txt b/lab_3/config.txt new file mode 100644 index 000000000..7e9ff304c --- /dev/null +++ b/lab_3/config.txt @@ -0,0 +1,2 @@ +initramfs initramfs.cpio 0x80000000 +kernel=bootloader.img \ No newline at end of file diff --git a/lab_3/rootfs/hello.txt b/lab_3/rootfs/hello.txt new file mode 100644 index 000000000..ca9e3b5cc --- /dev/null +++ b/lab_3/rootfs/hello.txt @@ -0,0 +1 @@ +this is a example file. diff --git a/lab_3/rootfs/link.ld b/lab_3/rootfs/link.ld new file mode 100644 index 000000000..bd0d89847 --- /dev/null +++ b/lab_3/rootfs/link.ld @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +SECTIONS +{ + . = 0x30000; + PROVIDE(_head = .); + .text : { KEEP(*(.text.boot)) *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + PROVIDE(_data = .); + .data : { *(.data .data.*) } + .bss : { + . = ALIGN(16); + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + _end = .; +} +__bss_size = (__bss_end - __bss_start)>>3; +__loader_size = (_end - _head)>>3; \ No newline at end of file diff --git a/lab_3/rootfs/makefile b/lab_3/rootfs/makefile new file mode 100644 index 000000000..1f075562f --- /dev/null +++ b/lab_3/rootfs/makefile @@ -0,0 +1,36 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.S=.o) +CFLAGS = -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles +BOOTLOADER_BIN = kernel8.img +all: user_program.S + "aarch64-linux-gnu-gcc" -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles -c user_program.S -o user_program.o + "aarch64-linux-gnu-ld" -nostdlib -nostartfiles user_program.o -T link.ld -o user_program.elf + "aarch64-linux-gnu-objcopy" -O binary user_program.elf user_program.img diff --git a/lab_3/rootfs/user_program b/lab_3/rootfs/user_program new file mode 100755 index 0000000000000000000000000000000000000000..e235f8e5dca3944e2e14158775cca560bee208ea GIT binary patch literal 5704 zcmeHLJ!lkB5T4}n>km0Kg5Y0aiZt0nlxSgbmtU1jA~6aPVcEMqyp#J0cN<7-Oc}vO z(B59KwYIYqv9U{`lF}3kB6!a1n{RWw-boY%i+ynWy_q-Pym_;?1M}`rXJ@**x(Fjd zFG!@RZlg)-!oU%oFr?`s_4D%}9iTpzdwiW)PaEJ>Gd9&Va6t75M&Z5E^(Y=!J0Kzy z?A5h)a9iUBl7AZWlvtBPhLs#L9)X|K84x^i_bc9O#wBF#D98&(7bVm$&Yn+I(7g_-^Cl z^N*Jj4<6tBdO`f)$J5^&8*liqkC^}V^f2u_Yc`kIfovI%I0JD8;ta$Yh%*ppAkILX zfj9$k2I36-w;A~Sy;+ms2DFbvubEa^dO;bZD(^F*c9}%`RX(P8R1xs4Y5cQ{RuN18 z1kvCAiSq=X3VnGiKSA9=UmMmZg1m+GJwd+0`d&g_!}`A9{voXI=e`&n@9qlkN?UF9 zgR~vd3%iGQn!9W>JLE(AecRbfbKAv!qVb$meKej4)+cF@AL01VbJJ)E~4bQ22Hl#w;4d(s|TdA(#I-Wx!5m}A(is$4Qy}H37W~HiEsIQP!t$79O zPIcAFt(N%SqvVn=6`e+rEO))i9t?VQvb@5Y=SxndlxM>lOZ>1_${wHhZw$Gok~gbm zA^2|a{oo!8dxif6L}z%RzlGoFz6gBW7eOB9$rr9I*dO%^ctQ=qix!_WuS@L$AN380 zdM5QyVh11k%dC_8CGhcG1Ec4S%GcB{>MQOaf!K%5{DE^ozR45eN(?gaUE&@M_j9P{ zh(Bq}$!3(8z{mHyrT2xfSM%Wf(DR=*#7EuPR(>>o@PM*6a)&*9)By1wE~?zygl|&%wgRdmvsU zTeoojIX8qv3|O-7{QcY|wx3Qf&YWHkJRE#L?_33ihVUI$03nV^6JmhA(ykFzSX%o4 z9mni9(X+bePk4BxUSE?D%D1YzBx+>omc&)vxc*Au!ok?|V^scwhqB^5$Dv9j`?Jm# zA;T8^j=~-I4gI0Qf7dzcz=MuDdmZ?R!pmxPUIfT-pC?&#m!(%(ya-b47l@*1o=5rh zV`9?ec7|x4#I$Nk#F?P{CXHugR!Ri$t_Q5V5{hJ z=l8(1lW&Xf`NbF{S0A!heaL<7=~{~YzA?zYeVSa4ziWdq?rqJKyc^$n T9i+V3f0M8_|I!E#{_uYTAnra7 literal 0 HcmV?d00001 diff --git a/lab_3/rootfs/user_program.img b/lab_3/rootfs/user_program.img new file mode 100755 index 0000000000000000000000000000000000000000..1adf648a4c1b9d2d1b5e9fa08b84e52ef2fafc78 GIT binary patch literal 24 gcmZQzXt>0{!Z4AMf#Hh02*bzK|Nn/dev/null 2>/dev/null || true + +run_asm: + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none -d in_asm + +run: + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none + +debug: + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none -s -S diff --git a/lab_3/shell/cpio.c b/lab_3/shell/cpio.c new file mode 100644 index 000000000..53f870e6a --- /dev/null +++ b/lab_3/shell/cpio.c @@ -0,0 +1,102 @@ +#include "include/cpio.h" +#include "include/uart.h" +#include "include/stdint.h" +#include "include/utils.h" + +char* cpio_addr = (char *)0x8000000;; + +void cpio_ls(){ + char* addr = (char*) cpio_addr; + uart_puts((char *)(addr+sizeof(struct cpio_header))); + while(strcmp((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); + uart_puts(addr+sizeof(struct cpio_header)); + uart_puts("\n"); + addr += (headerPathname_size + file_size); + } +} + +void cpio_exec(char *filename){ + char *target = findFile(filename); + if (target){ + struct cpio_header *header = (struct cpio_header *)target; + unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize)); + unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; + + utils_align(&headerPathname_size,4); + utils_align(&file_size,4); + char *file_content = target + headerPathname_size; + + char *program_ptr = (char *) 0x30000; // load the user program into 0x30000 + char* start_point = (char*) 0x30000; + char* stack_pointer = (char *) (0x30000 + 0x3000); // Stack pointer for the user program, base address+0x3000 + for (unsigned int i = 0; i < file_size; i++){ + *program_ptr ++ = *file_content++; + } + asm volatile( + // 0x3c0 + "mov x0, 0x3c0;\n\t" + "msr spsr_el1, x0;\n\t" + // start address of user program + "mov x1, 0x30000;\n\t" + "msr elr_el1, x1;\n\t" + // sp for user program + "mov x2, %0;\n\t" + "msr sp_el0, x2;\n\t" + "eret;" + : // No output operands + : "r" (start_point), "r" (stack_pointer) + : "x0", "x1", "x2" // tell compiler x0~x2 has been used + ); + } + uart_puts("completed.\n"); +} + + + +void cpio_cat(char *filename){ + char *target = findFile(filename); + if (target){ + struct cpio_header *header = (struct cpio_header *)target; + unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize)); + unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; + + utils_align(&headerPathname_size,4); + utils_align(&file_size,4); + char *file_content = target + headerPathname_size; + for (unsigned int i = 0; i < file_size; i++) + { + uart_send(file_content[i]); + } + uart_puts("\n"); + } + else + { + uart_puts("Not found the file\n"); + } +} + +char *findFile(char *name){ + char *addr = (char *)cpio_addr; + while (strcmp((char *)(addr + sizeof(struct cpio_header)), "TRAILER!!!") != 0){ + if ((strcmp((char *)(addr + sizeof(struct cpio_header)), name) == 0)){ + return addr; + } + struct cpio_header* header = (struct cpio_header *)addr; + unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize));; + unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; + + utils_align(&headerPathname_size,4); + utils_align(&file_size,4); + addr += (headerPathname_size + file_size); + } + return 0; +} \ No newline at end of file diff --git a/lab_3/shell/exception_vector.S b/lab_3/shell/exception_vector.S new file mode 100644 index 000000000..5428ffb74 --- /dev/null +++ b/lab_3/shell/exception_vector.S @@ -0,0 +1,101 @@ +.align 11 // vector table should be aligned to 0x800 +.global exception_vector_table + +exception_vector_table: + b exception_handler // branch to a handler function. +.align 7 // entry size is 0x80, .align will pad 0 + b exception_handler +.align 7 + b exception_handler // reserved for FIQ(Fast Interrupt) +.align 7 + b exception_handler // reserved for SError +.align 7 + + b exception_handler // synchronous: caused by current excution instr. +.align 7 + b exception_handler +.align 7 + b exception_handler // reserved for FIQ; for prioritizing exception +.align 7 + b exception_handler // reserved for SError +.align 7 + + b exception_handler +.align 7 + b exception_handler +.align 7 + b exception_handler // reserved for FIQ +.align 7 + b exception_handler // reserved for SError +.align 7 + + b exception_handler +.align 7 + b exception_handler +.align 7 + b exception_handler // reserved for FIQ +.align 7 + b exception_handler // reserved for SError +.align 7 + + + +.global set_exception_vector_table +set_exception_vector_table: + adr x4, exception_vector_table + msr vbar_el1, x4 + ret + +// save general registers to stack +.macro save_all + sub sp, sp, 32*9 + stp x0, x1, [sp, 16*0] + stp x2, x3, [sp, 16*1] + stp x4, x5, [sp, 16*2] + stp x6, x7, [sp, 16*3] + stp x8, x9, [sp, 16*4] + stp x10, x11, [sp, 16*5] + stp x12, x13, [sp, 16*6] + stp x14, x15, [sp, 16*7] + stp x16, x17, [sp, 16*8] + stp x18, x19, [sp, 16*9] + stp x20, x21, [sp, 16*10] + stp x22, x23, [sp, 16*11] + stp x24, x25, [sp, 16*12] + stp x26, x27, [sp, 16*13] + stp x28, x29, [sp, 16*14] + str x30, [sp, 16*15] + mrs x0, spsr_el1 + mrs x1, elr_el1 + stp x0, x1, [sp, 16*16] +.endm + +// load general registers from stack +.macro load_all + ldp x0, x1, [sp, 16*16] + msr spsr_el1, x0 + msr elr_el1, x1 + ldp x0, x1, [sp, 16*0] + ldp x2, x3, [sp, 16*1] + ldp x4, x5, [sp, 16*2] + ldp x6, x7, [sp, 16*3] + ldp x8, x9, [sp, 16*4] + ldp x10, x11, [sp, 16*5] + ldp x12, x13, [sp, 16*6] + ldp x14, x15, [sp, 16*7] + ldp x16, x17, [sp, 16*8] + ldp x18, x19, [sp, 16*9] + ldp x20, x21, [sp, 16*10] + ldp x22, x23, [sp, 16*11] + ldp x24, x25, [sp, 16*12] + ldp x26, x27, [sp, 16*13] + ldp x28, x29, [sp, 16*14] + ldr x30, [sp, 16*15] + add sp, sp, 32*9 +.endm + +exception_handler: + save_all + bl exception_entry + load_all + eret \ No newline at end of file diff --git a/lab_3/shell/exceptions.c b/lab_3/shell/exceptions.c new file mode 100644 index 000000000..60434e8c2 --- /dev/null +++ b/lab_3/shell/exceptions.c @@ -0,0 +1,25 @@ +#include "include/uart.h" + +int exception_entry(){ + uart_puts("exception entry!\n"); + + unsigned long long spsr_el1, elr_el1, esr_el1; + + asm volatile( + "mrs %0, spsr_el1;" + "mrs %1, elr_el1;" + "mrs %2, esr_el1;" + : "=r" (spsr_el1), "=r" (elr_el1), "=r" (esr_el1) + ); + uart_puts("spsr_el1: "); + uart_hex(spsr_el1); + uart_send('\n'); + uart_puts("elr_el1: "); + uart_hex(elr_el1); + uart_send('\n'); + uart_puts("esr_el1: "); + uart_hex(esr_el1); + uart_send('\n'); + + return 0; +} \ No newline at end of file diff --git a/lab_3/shell/include/cpio.h b/lab_3/shell/include/cpio.h new file mode 100644 index 000000000..52c6da00e --- /dev/null +++ b/lab_3/shell/include/cpio.h @@ -0,0 +1,21 @@ +struct cpio_header { + char c_magic[6]; + char c_ino[8]; + char c_mode[8]; + char c_uid[8]; + char c_gid[8]; + char c_nlink[8]; + char c_mtime[8]; + char c_filesize[8]; + char c_devmajor[8]; + char c_devminor[8]; + char c_rdevmajor[8]; + char c_rdevminor[8]; + char c_namesize[8]; + char c_check[8]; +}; + +void cpio_ls(); +void cpio_cat(char *filename); +void cpio_exec(char* filename); +char *findFile(char *name); \ No newline at end of file diff --git a/lab_3/shell/include/gpio.h b/lab_3/shell/include/gpio.h new file mode 100644 index 000000000..52fa671d0 --- /dev/null +++ b/lab_3/shell/include/gpio.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#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)) diff --git a/lab_3/shell/include/mbox.h b/lab_3/shell/include/mbox.h new file mode 100644 index 000000000..e0e2e41f1 --- /dev/null +++ b/lab_3/shell/include/mbox.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/* a properly aligned buffer */ +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 MBOX_TAG_GETSERIAL 0x10004 +#define MBOX_TAG_REVISION 0x00010002 +#define MBOX_TAG_MEMORY 0x00010005 +#define MBOX_TAG_LAST 0 + +int mbox_call(unsigned char ch); diff --git a/lab_3/shell/include/stdint.h b/lab_3/shell/include/stdint.h new file mode 100644 index 000000000..3ddcc9b17 --- /dev/null +++ b/lab_3/shell/include/stdint.h @@ -0,0 +1,9 @@ + +typedef unsigned int uint16_t; + +typedef unsigned long uint32_t; + +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +typedef float float32; +typedef double float64; \ No newline at end of file diff --git a/lab_3/shell/include/uart.h b/lab_3/shell/include/uart.h new file mode 100644 index 000000000..245c358c8 --- /dev/null +++ b/lab_3/shell/include/uart.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +void uart_init(); +void uart_send(unsigned int c); +char uart_getc(); +void uart_puts(char *s); +void uart_hex(unsigned int d); \ No newline at end of file diff --git a/lab_3/shell/include/utils.h b/lab_3/shell/include/utils.h new file mode 100644 index 000000000..8f28d9205 --- /dev/null +++ b/lab_3/shell/include/utils.h @@ -0,0 +1,7 @@ +void set(long addr, unsigned int value); +void reset(); +int strcmp(char* a, char* b); +void cancel_reset(); +void utils_align(void *size, unsigned int s); +unsigned long utils_atoi(const char *s, int char_size); +void* simple_malloc(unsigned long size); \ No newline at end of file diff --git a/lab_3/shell/initramfs.cpio b/lab_3/shell/initramfs.cpio new file mode 100644 index 0000000000000000000000000000000000000000..0b64417ccc1b259e1e0880523f255f6a8c51908a GIT binary patch literal 12288 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 +__loader_size = (_end - _head)>>3; \ No newline at end of file diff --git a/lab_3/shell/main.c b/lab_3/shell/main.c new file mode 100644 index 000000000..67d429c78 --- /dev/null +++ b/lab_3/shell/main.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#define MAX_BUFFER 50 +#include "include/uart.h" +#include "include/utils.h" +#include "include/mbox.h" +#include "include/cpio.h" + + +extern void set_exception_vector_table(); + +void main(int argc, char* argv[]){ + uart_init(); + set_exception_vector_table(); + cpio_exec("user_program.img"); + while(1){ + char command[MAX_BUFFER]; + char c = '\0'; + int length=0; + for(int i=0; i\t: print the content of file in root filesystem\n"); + uart_puts("hello\t: print hello world!\n"); + uart_puts("reboot\t: reboot the device\n"); + } + else if(strcmp(command, "hello") == 0){ + uart_puts("Hello World!\n"); + } + else if(strcmp(command, "ls") == 0){ + cpio_ls(); + } + else if(strcmp(command, "reboot") == 0){ + reset(); + } + else if(strcmp(command, "exec") == 0){ + uart_puts("executing...\n"); + // execute a dedicated user program + cpio_exec("user_program"); + } + // command with arguments + else{ + char arguments[3][MAX_BUFFER]; + // initialize + for(int i=0;i<3;i++){ + for(int j=0;j 0, stop +1: wfe + b 1b + + +2: // cpu id == 0 + + // el2 to el1 + bl from_el2_to_el1 + + // 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 + +from_el2_to_el1: + mov x0, (1 << 31) // EL1 uses aarch64 + // move system register to register (write x0 into hcr_el2) + msr hcr_el2, x0 + mov x0, 0x3c5 // EL1h (SPSel = 1) with interrupt disabled + msr spsr_el2, x0 + msr elr_el2, lr + eret // return to EL1 diff --git a/lab_3/shell/uart.c b/lab_3/shell/uart.c new file mode 100644 index 000000000..489c6608a --- /dev/null +++ b/lab_3/shell/uart.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "include/gpio.h" + +/** Auxilary mini UART registers + * Address & Description refer: https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf Page.8 + */ + +#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004)) +#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040)) +#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044)) +#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048)) +#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C)) +#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050)) +#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054)) +#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058)) +#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C)) +#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060)) +#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064)) +#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068)) + +/** + * Set baud rate and characteristics (115200 8N1) and map to GPIO + */ +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *AUX_ENABLE |=1; // enable UART1, AUX mini uart + *AUX_MU_CNTL = 0; + *AUX_MU_LCR = 3; // 8 bits + *AUX_MU_MCR = 0; + *AUX_MU_IER = 0; + *AUX_MU_IIR = 0xc6; // disable interrupts + *AUX_MU_BAUD = 270; // 115200 baud + /* map UART1 to GPIO pins */ + r=*GPFSEL1; + r&=~((7<<12)|(7<<15)); // gpio14, gpio15 + r|=(2<<12)|(2<<15); // alt5 + *GPFSEL1 = r; + *GPPUD = 0; // enable pins 14 and 15 + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; // flush GPIO setup + *AUX_MU_CNTL = 3; // enable Tx, Rx +} + +/** + * Send a character + */ +void uart_send(unsigned int c) { + /* wait until we can send */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20)); + /* write the character to the buffer */ + *AUX_MU_IO=c; +} + +/** + * Receive a character + */ +char uart_getc() { + char r; + /* wait until something is in the buffer */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01)); + /* read it and return */ + r=(char)(*AUX_MU_IO); + /* convert carriage return to newline */ + return r=='\r'?'\n':r; +} + +/** + * Display a string + */ +void uart_puts(char *s) { + while(*s) { + /* convert newline to carriage return + newline */ + if(*s=='\n') + uart_send('\r'); + uart_send(*s++); + } +} + +/** + * Display a binary value in hexadecimal + */ +void uart_hex(unsigned int d) { + unsigned int n; + int c; + for(c=28;c>=0;c-=4) { + // get highest tetrad + n=(d>>c)&0xF; + // 0-9 => '0'-'9', 10-15 => 'A'-'F' + n+=n>9?0x37:0x30; + uart_send(n); + } +} \ No newline at end of file diff --git a/lab_3/shell/utils.c b/lab_3/shell/utils.c new file mode 100644 index 000000000..79223d30c --- /dev/null +++ b/lab_3/shell/utils.c @@ -0,0 +1,105 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC 0x3F10001c +#define PM_WDOG 0x3F100024 +#define SIMPLE_MALLOC_BUFFER_SIZE 8192 + +unsigned long utils_atoi(const char *s, int char_size) { + unsigned long num = 0; + for (int i = 0; i < char_size; i++) { + num = num * 16; + if (*s >= '0' && *s <= '9') { + num += (*s - '0'); + } else if (*s >= 'A' && *s <= 'F') { + num += (*s - 'A' + 10); + } else if (*s >= 'a' && *s <= 'f') { + num += (*s - 'a' + 10); + } + s++; + } + return num; +} + + + + +/** + * compare two string, given s1 and s2 + * return 0 if the both string are equal; + * return -1 if s1 is less than s2; + * return 1 if s1 is greater than s2 + */ +int strcmp(char* a, char* b){ + int value = 0; + while(*a != '\0' && *b != '\0'){ + if(*a < *b){ + return -1; + } + else if(*a > *b){ + return 1; + } + else{ + a++; + b++; + } + } + if(*a == '\0'){ + value++; + } + if(*b == '\0'){ + value--; + } + return value; +} + +/** + * set up given value to given address + */ +void set(long addr, unsigned int value) { + volatile unsigned int* point = (unsigned int*)addr; + *point = value; +} + + +void utils_align(void *size, unsigned int s) { + unsigned long* x = (unsigned long*) size; + unsigned long mask = s-1; + *x = ((*x) + mask) & (~mask); +} + +/** + * reboot respberry pi + * if tick=0, reboot instantly; + * otherwise, wait for tick seconds to reboot + */ +void reset(int tick) { // reboot after watchdog timer expire + set(PM_RSTC, PM_PASSWORD | 0x20); // full reset + if(tick != 0){ + set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick + } +} + +/** + * clear reboot register + */ +void cancel_reset() { + set(PM_RSTC, PM_PASSWORD | 0); // full reset + set(PM_WDOG, PM_PASSWORD | 0); // number of watchdog tick +} + + +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; +} \ No newline at end of file From 1df7ef413a89f835bfe9725b648ff6937bda626e Mon Sep 17 00:00:00 2001 From: laxiflora Date: Thu, 13 Jun 2024 17:25:03 +0800 Subject: [PATCH 08/23] an attemption to finish interrupt but can not normally return --- lab_3/rootfs/hello2.txt | 1 + lab_3/shell/Makefile | 3 +- lab_3/shell/exception_vector.S | 17 +++++---- lab_3/shell/exceptions.c | 21 +++++++++++ lab_3/shell/interrupts.S | 69 ++++++++++++++++++++++++++++++++++ lab_3/shell/main.c | 8 +++- 6 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 lab_3/rootfs/hello2.txt create mode 100644 lab_3/shell/interrupts.S diff --git a/lab_3/rootfs/hello2.txt b/lab_3/rootfs/hello2.txt new file mode 100644 index 000000000..d90bb747c --- /dev/null +++ b/lab_3/rootfs/hello2.txt @@ -0,0 +1 @@ +this is another example file. diff --git a/lab_3/shell/Makefile b/lab_3/shell/Makefile index bf5c300e0..8591b8f74 100644 --- a/lab_3/shell/Makefile +++ b/lab_3/shell/Makefile @@ -38,13 +38,14 @@ all: clean kernel8.img %.o: %.S $(GCC) $(CFLAGS) -c $< -o $@ -g "aarch64-linux-gnu-gcc" -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles -c exception_vector.S -o exception_vector.o -g + "aarch64-linux-gnu-gcc" -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles -c interrupts.S -o interrupts.o -g %.o: %.c $(GCC) $(CFLAGS) -c $< -o $@ -g kernel8.img: start.o $(OBJS) - $(LD) -nostdlib -nostartfiles start.o $(OBJS) exception_vector.o -T link.ld -o kernel8.elf + $(LD) -nostdlib -nostartfiles start.o $(OBJS) exception_vector.o interrupts.o -T link.ld -o kernel8.elf $(OBJCPY) -O binary kernel8.elf shell_kernel.img clean: diff --git a/lab_3/shell/exception_vector.S b/lab_3/shell/exception_vector.S index 5428ffb74..6a4d1b5ad 100644 --- a/lab_3/shell/exception_vector.S +++ b/lab_3/shell/exception_vector.S @@ -15,27 +15,26 @@ exception_vector_table: .align 7 b exception_handler .align 7 - b exception_handler // reserved for FIQ; for prioritizing exception -.align 7 - b exception_handler // reserved for SError + b exception_handler .align 7 - b exception_handler .align 7 + b exception_handler .align 7 - b exception_handler // reserved for FIQ + b core_timer_handler .align 7 - b exception_handler // reserved for SError + b exception_handler .align 7 + b exception_handler b exception_handler .align 7 b exception_handler .align 7 - b exception_handler // reserved for FIQ + b exception_handler .align 7 - b exception_handler // reserved for SError + b exception_handler .align 7 @@ -70,7 +69,9 @@ set_exception_vector_table: stp x0, x1, [sp, 16*16] .endm + // load general registers from stack + .macro load_all ldp x0, x1, [sp, 16*16] msr spsr_el1, x0 diff --git a/lab_3/shell/exceptions.c b/lab_3/shell/exceptions.c index 60434e8c2..6c2aece09 100644 --- a/lab_3/shell/exceptions.c +++ b/lab_3/shell/exceptions.c @@ -22,4 +22,25 @@ int exception_entry(){ uart_send('\n'); return 0; +} + +// cntfrq_el0 = 62500000 +int print_boot_timer(){ + uart_puts("Interrupt occurs!\n"); + unsigned long long freq, ticks; + asm volatile( + "mrs %0, cntfrq_el0;" + "mrs %1, cntpct_el0;" + : "=r" (freq), "=r" (ticks) + ); + // set up the next timer + asm volatile ( + "msr cntp_tval_el0, %0" + : + : "r" (freq * 2) + ); + unsigned int time = (unsigned int)(ticks/freq); + uart_hex(time); + uart_puts(" seconds elapsed\n"); + return 0; } \ No newline at end of file diff --git a/lab_3/shell/interrupts.S b/lab_3/shell/interrupts.S new file mode 100644 index 000000000..b64f670fb --- /dev/null +++ b/lab_3/shell/interrupts.S @@ -0,0 +1,69 @@ +#define CORE0_TIMER_IRQ_CTRL 0x40000040 + +// save general registers to stack +.macro save_all + sub sp, sp, 32*9 + stp x0, x1, [sp, 16*0] + stp x2, x3, [sp, 16*1] + stp x4, x5, [sp, 16*2] + stp x6, x7, [sp, 16*3] + stp x8, x9, [sp, 16*4] + stp x10, x11, [sp, 16*5] + stp x12, x13, [sp, 16*6] + stp x14, x15, [sp, 16*7] + stp x16, x17, [sp, 16*8] + stp x18, x19, [sp, 16*9] + stp x20, x21, [sp, 16*10] + stp x22, x23, [sp, 16*11] + stp x24, x25, [sp, 16*12] + stp x26, x27, [sp, 16*13] + stp x28, x29, [sp, 16*14] + str x30, [sp, 16*15] + mrs x0, spsr_el1 + mrs x1, elr_el1 + stp x0, x1, [sp, 16*16] +.endm + + +// load general registers from stack + +.macro load_all + ldp x0, x1, [sp, 16*16] + msr spsr_el1, x0 + msr elr_el1, x1 + ldp x0, x1, [sp, 16*0] + ldp x2, x3, [sp, 16*1] + ldp x4, x5, [sp, 16*2] + ldp x6, x7, [sp, 16*3] + ldp x8, x9, [sp, 16*4] + ldp x10, x11, [sp, 16*5] + ldp x12, x13, [sp, 16*6] + ldp x14, x15, [sp, 16*7] + ldp x16, x17, [sp, 16*8] + ldp x18, x19, [sp, 16*9] + ldp x20, x21, [sp, 16*10] + ldp x22, x23, [sp, 16*11] + ldp x24, x25, [sp, 16*12] + ldp x26, x27, [sp, 16*13] + ldp x28, x29, [sp, 16*14] + ldr x30, [sp, 16*15] + add sp, sp, 32*9 +.endm + + +.global core_timer_enable +core_timer_enable: + mov x0, 1 + msr cntp_ctl_el0, x0 // enable + mrs x0, cntfrq_el0 + msr cntp_tval_el0, x0 // set expired time + mov x0, 2 + ldr x1, =CORE0_TIMER_IRQ_CTRL + str w0, [x1] // unmask timer interrupt + +.global core_timer_handler +core_timer_handler: + save_all + bl print_boot_timer + load_all + eret \ No newline at end of file diff --git a/lab_3/shell/main.c b/lab_3/shell/main.c index 67d429c78..0d0ce2bda 100644 --- a/lab_3/shell/main.c +++ b/lab_3/shell/main.c @@ -30,11 +30,15 @@ extern void set_exception_vector_table(); +extern void core_timer_enable(); + + void main(int argc, char* argv[]){ uart_init(); set_exception_vector_table(); - cpio_exec("user_program.img"); + //cpio_exec("user_program.img"); + core_timer_enable(); while(1){ char command[MAX_BUFFER]; char c = '\0'; @@ -68,7 +72,7 @@ void main(int argc, char* argv[]){ else if(strcmp(command, "exec") == 0){ uart_puts("executing...\n"); // execute a dedicated user program - cpio_exec("user_program"); + cpio_exec("user_program.img"); } // command with arguments else{ From b16f3cd7baa082c1122607fa821ac3ca0fbd1d21 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Thu, 13 Jun 2024 18:42:58 +0800 Subject: [PATCH 09/23] add some testing malloc and modify kernel uploader so it can take /dev pathname --- lab_2/bootloader/kernel_uploader.py | 6 +++++- lab_2/shell/cpio.c | 3 ++- lab_2/shell/main.c | 9 +++++++++ lab_2/shell/utils.c | 4 ++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lab_2/bootloader/kernel_uploader.py b/lab_2/bootloader/kernel_uploader.py index 852ad9d26..5f93a1747 100644 --- a/lab_2/bootloader/kernel_uploader.py +++ b/lab_2/bootloader/kernel_uploader.py @@ -4,7 +4,11 @@ import sys import time -port = '/dev/pts/2' + +print("please enter the serial port: ", end="") +port = input() +port = "/dev/"+port +# port = '/dev/pts/1' s = serial.Serial(port, baudrate=115200) def read_line(s): diff --git a/lab_2/shell/cpio.c b/lab_2/shell/cpio.c index a3aaeab82..3fdbd10c2 100644 --- a/lab_2/shell/cpio.c +++ b/lab_2/shell/cpio.c @@ -6,7 +6,6 @@ char* cpio_addr = (char *)0x8000000;; void cpio_ls(){ char* addr = (char*) cpio_addr; - uart_puts((char *)(addr+sizeof(struct cpio_header))); while(strcmp((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)); @@ -26,6 +25,7 @@ void cpio_cat(char *filename){ struct cpio_header *header = (struct cpio_header *)target; unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize)); unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + //The header is followed by the pathname of the entry, then is content of file unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; utils_align(&headerPathname_size,4); @@ -46,6 +46,7 @@ void cpio_cat(char *filename){ char *findFile(char *name){ char *addr = (char *)cpio_addr; while (strcmp((char *)(addr + sizeof(struct cpio_header)), "TRAILER!!!") != 0){ + //The header is followed by the pathname of the entry if ((strcmp((char *)(addr + sizeof(struct cpio_header)), name) == 0)){ return addr; } diff --git a/lab_2/shell/main.c b/lab_2/shell/main.c index fa5185915..65e22a961 100644 --- a/lab_2/shell/main.c +++ b/lab_2/shell/main.c @@ -30,6 +30,15 @@ void main(int argc, char* argv[]){ + unsigned int* a = (unsigned int*) simple_malloc(4); + *a = 32; + unsigned int* b = (unsigned int*) simple_malloc(4); + *b = 70; + uart_puts("a = 0x"); + uart_hex(*a); + uart_puts("\nb = 0x"); + uart_hex(*b); + uart_send('\n'); while(1){ char command[MAX_BUFFER]; char c = '\0'; diff --git a/lab_2/shell/utils.c b/lab_2/shell/utils.c index 79223d30c..ff3a19369 100644 --- a/lab_2/shell/utils.c +++ b/lab_2/shell/utils.c @@ -63,6 +63,7 @@ void set(long addr, unsigned int value) { void utils_align(void *size, unsigned int s) { unsigned long* x = (unsigned long*) size; unsigned long mask = s-1; + // ceil(a/k) = (a+(k-1))/k *x = ((*x) + mask) & (~mask); } @@ -90,9 +91,8 @@ void cancel_reset() { static unsigned char simple_malloc_buffer[SIMPLE_MALLOC_BUFFER_SIZE]; static unsigned long simple_malloc_offset = 0; +// the size is calculated in byte format 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 From b5099881de01cb790dd0982cd32bd02d89f717a0 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Wed, 19 Jun 2024 23:57:35 +0800 Subject: [PATCH 10/23] 1. update docker file so multiarch gdb is installed 2. update kernel_uploader in lab3 3. resolve the issue that can not interrupt properly (misconfiguration in el2 to el1) --- Dockerfile | 4 +++- lab_3/bootloader/kernel_uploader.py | 6 +++++- lab_3/shell/exception_vector.S | 12 ++++++------ lab_3/shell/interrupts.S | 1 + lab_3/shell/main.c | 13 ++++++++++++- lab_3/shell/start.S | 2 +- 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index a0b963125..6a5ece06b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ RUN apt-get update # Install QEMU for emulation RUN apt-get install -y \ qemu-system-arm \ - gdb \ + gdb-multiarch \ sudo # Install the AArch64 cross-compiler toolchain @@ -33,6 +33,8 @@ RUN echo "alias gcc='aarch64-linux-gnu-gcc'" >> ~/.bashrc # install python dependicies RUN apt install -y python3-pip +RUN pip install pyserial + # clean up package caches RUN rm -rf /var/lib/apt/lists/* diff --git a/lab_3/bootloader/kernel_uploader.py b/lab_3/bootloader/kernel_uploader.py index 852ad9d26..5f93a1747 100644 --- a/lab_3/bootloader/kernel_uploader.py +++ b/lab_3/bootloader/kernel_uploader.py @@ -4,7 +4,11 @@ import sys import time -port = '/dev/pts/2' + +print("please enter the serial port: ", end="") +port = input() +port = "/dev/"+port +# port = '/dev/pts/1' s = serial.Serial(port, baudrate=115200) def read_line(s): diff --git a/lab_3/shell/exception_vector.S b/lab_3/shell/exception_vector.S index 6a4d1b5ad..743025a77 100644 --- a/lab_3/shell/exception_vector.S +++ b/lab_3/shell/exception_vector.S @@ -11,18 +11,18 @@ exception_vector_table: b exception_handler // reserved for SError .align 7 - b exception_handler // synchronous: caused by current excution instr. + b core_timer_handler // synchronous: caused by current excution instr. .align 7 - b exception_handler + b core_timer_handler .align 7 - b exception_handler + b core_timer_handler .align 7 - b exception_handler + b core_timer_handler .align 7 - b exception_handler + b exception_handler // time interrupt .align 7 - b core_timer_handler + b exception_handler .align 7 b exception_handler .align 7 diff --git a/lab_3/shell/interrupts.S b/lab_3/shell/interrupts.S index b64f670fb..2527491c6 100644 --- a/lab_3/shell/interrupts.S +++ b/lab_3/shell/interrupts.S @@ -60,6 +60,7 @@ core_timer_enable: mov x0, 2 ldr x1, =CORE0_TIMER_IRQ_CTRL str w0, [x1] // unmask timer interrupt + ret .global core_timer_handler core_timer_handler: diff --git a/lab_3/shell/main.c b/lab_3/shell/main.c index 0d0ce2bda..6003babb8 100644 --- a/lab_3/shell/main.c +++ b/lab_3/shell/main.c @@ -37,6 +37,17 @@ extern void core_timer_enable(); void main(int argc, char* argv[]){ uart_init(); set_exception_vector_table(); + + // show el + unsigned long el; + asm volatile ("mrs %0, CurrentEL" : "=r" (el)); + el = el >> 2; // CurrentEL的值在高两位 + + // print current exception level + uart_puts("Booted! Current EL: "); + uart_send('0' + el); + uart_puts("\n"); + //cpio_exec("user_program.img"); core_timer_enable(); while(1){ @@ -50,7 +61,7 @@ void main(int argc, char* argv[]){ c = uart_getc(); command[length] = c; // print what user input to screen - // uart_send(c); + //uart_send(c); } command[length==MAX_BUFFER?length-2:length-1] = '\0'; if(strcmp(command, "help") == 0){ diff --git a/lab_3/shell/start.S b/lab_3/shell/start.S index 879b6689f..b47e442ee 100644 --- a/lab_3/shell/start.S +++ b/lab_3/shell/start.S @@ -38,7 +38,7 @@ from_el2_to_el1: mov x0, (1 << 31) // EL1 uses aarch64 // move system register to register (write x0 into hcr_el2) msr hcr_el2, x0 - mov x0, 0x3c5 // EL1h (SPSel = 1) with interrupt disabled + mov x0, 0x345 // 3c5 EL1h (SPSel = 1) with interrupt disabled, 345 enable interrupt msr spsr_el2, x0 msr elr_el2, lr eret // return to EL1 From f29afe57bb1a44cf3db63c8f04038db1b39e7c4d Mon Sep 17 00:00:00 2001 From: laxiflora Date: Thu, 20 Jun 2024 04:58:00 +0800 Subject: [PATCH 11/23] Finish lab3 basic 1. finish lab3 basic 2. update kernel uploader so that it can do input with interrupt 3. update readme in lab2 --- lab_2/README.md | 8 +++ lab_3/bootloader/kernel_uploader.py | 81 +++++++++++++++++++---------- lab_3/bootloader/uart.c | 7 +++ lab_3/shell/exception_vector.S | 8 +-- lab_3/shell/exceptions.c | 21 -------- lab_3/shell/include/interrupt.h | 13 +++++ lab_3/shell/include/uart.h | 21 +++++++- lab_3/shell/interrupt.c | 48 +++++++++++++++++ lab_3/shell/interrupts.S | 10 ++-- lab_3/shell/main.c | 10 ++-- lab_3/shell/uart.c | 69 +++++++++++++++++++----- 11 files changed, 221 insertions(+), 75 deletions(-) create mode 100644 lab_3/shell/include/interrupt.h create mode 100644 lab_3/shell/interrupt.c diff --git a/lab_2/README.md b/lab_2/README.md index ff2c23e3f..30115f485 100644 --- a/lab_2/README.md +++ b/lab_2/README.md @@ -1,4 +1,12 @@ 1. python UART transfer data loss +- AUX_MU_LSR_REG bit 1: This bit is set if there was a receiver overrun. That is: +one or more characters arrived whilst the receive +FIFO was full. The newly arrived charters have been +discarded. This bit is cleared each time this register is +read. To do a non-destructive read of this overrun bit +use the Mini Uart Extra Status register. +[reference: P15](https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf) + 2. init UART register to avoid garbage pending 3. link loader can arrange the .text section freely - why align diff --git a/lab_3/bootloader/kernel_uploader.py b/lab_3/bootloader/kernel_uploader.py index 5f93a1747..80ec98938 100644 --- a/lab_3/bootloader/kernel_uploader.py +++ b/lab_3/bootloader/kernel_uploader.py @@ -3,6 +3,20 @@ import os.path import sys import time +import signal + + +def tstp_handler(signum, frame): + print("SIGTSTP received (Ctrl+Z), enter your command now:") + inp = input() + inp += "\n" + bytes_to_send = inp.encode('utf-8') + s.write(bytes_to_send) + + +def cont_handler(signum, frame): + print("SIGCONT received, resuming normal operation.") + print("please enter the serial port: ", end="") @@ -29,41 +43,52 @@ def read_line(s): size_bytes = size.to_bytes(4,"little") print(f"size from python: {hex(size)}") s.write(size_bytes) +p = s time.sleep(1) # get response of correctness of bytes size sent while s.in_waiting > 0: - received_content = read_line(s) - print(received_content) + received_content = read_line(s) + print(received_content) with open("../shell/shell_kernel.img", "rb") as f: - sent_size = 0 # Initialize size counter - - byte = f.read(1) # Read the first byte - while byte: - s.write(byte) # Send the byte over serial - # s.flush() # Flush the output buffer - sent_size += 1 # Increment size counter - byte = f.read(1) # Read the next byte - + sent_size = 0 # Initialize size counter + + byte = f.read(1) # Read the first byte + while byte: + s.write(byte) # Send the byte over serial + # s.flush() # Flush the output buffer + sent_size += 1 # Increment size counter + byte = f.read(1) # Read the next byte + assert sent_size == size print("kernel sent successfully.") +# Register signal handlers +signal.signal(signal.SIGTSTP, tstp_handler) +signal.signal(signal.SIGCONT, cont_handler) -# get response of whether kernel is loaded successfully or not -time.sleep(1) -while(True): - while s.in_waiting > 0: - received_content = read_line(s) - print(received_content) - print("#", end=" ") - inp = input() - if(inp == ""): - continue - inp += "\n" - bytes_to_send = inp.encode('utf-8') - s.write(bytes_to_send) - #while s.in_waiting > 0: - # received_content = read_line(s) - # print(received_content) - time.sleep(1) \ No newline at end of file +print(f"Process ID: {os.getpid()}") + +# Run a loop to keep the program alive and responsive to signals +while True: + received_content = read_line(s) + print(received_content) + +# # get response of whether kernel is loaded successfully or not +# time.sleep(1) +# while(True): +# while s.in_waiting > 0: +# received_content = read_line(s) +# print(received_content) +# print("#", end=" ") +# inp = input() +# if(inp == ""): +# continue +# inp += "\n" +# bytes_to_send = inp.encode('utf-8') +# s.write(bytes_to_send) +# #while s.in_waiting > 0: +# # received_content = read_line(s) +# # print(received_content) +# time.sleep(1) \ No newline at end of file diff --git a/lab_3/bootloader/uart.c b/lab_3/bootloader/uart.c index 998d1509a..5e63f2d3a 100644 --- a/lab_3/bootloader/uart.c +++ b/lab_3/bootloader/uart.c @@ -76,6 +76,13 @@ void uart_init() } } +void uart_enable_interrupt(){ + // enable tx rx interrupt in uart + *AUX_MU_IER |= 0x02; + *IRQS1 |= 1 << 29; +} + + /** * Send a character */ diff --git a/lab_3/shell/exception_vector.S b/lab_3/shell/exception_vector.S index 743025a77..6e5ea29a7 100644 --- a/lab_3/shell/exception_vector.S +++ b/lab_3/shell/exception_vector.S @@ -11,13 +11,13 @@ exception_vector_table: b exception_handler // reserved for SError .align 7 - b core_timer_handler // synchronous: caused by current excution instr. + b interrupt_handler // synchronous: caused by current excution instr. .align 7 - b core_timer_handler + b interrupt_handler .align 7 - b core_timer_handler + b interrupt_handler .align 7 - b core_timer_handler + b interrupt_handler .align 7 b exception_handler // time interrupt diff --git a/lab_3/shell/exceptions.c b/lab_3/shell/exceptions.c index 6c2aece09..60434e8c2 100644 --- a/lab_3/shell/exceptions.c +++ b/lab_3/shell/exceptions.c @@ -22,25 +22,4 @@ int exception_entry(){ uart_send('\n'); return 0; -} - -// cntfrq_el0 = 62500000 -int print_boot_timer(){ - uart_puts("Interrupt occurs!\n"); - unsigned long long freq, ticks; - asm volatile( - "mrs %0, cntfrq_el0;" - "mrs %1, cntpct_el0;" - : "=r" (freq), "=r" (ticks) - ); - // set up the next timer - asm volatile ( - "msr cntp_tval_el0, %0" - : - : "r" (freq * 2) - ); - unsigned int time = (unsigned int)(ticks/freq); - uart_hex(time); - uart_puts(" seconds elapsed\n"); - return 0; } \ No newline at end of file diff --git a/lab_3/shell/include/interrupt.h b/lab_3/shell/include/interrupt.h new file mode 100644 index 000000000..4683019db --- /dev/null +++ b/lab_3/shell/include/interrupt.h @@ -0,0 +1,13 @@ +#define BASE_INTERRUPT_REGISTER 0x7E00B000 + + +#define IRQ_BASIC_PENDING ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000200)) +#define IRQ_PENDING_1 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000204)) +#define IRQ_PENDING_2 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000208)) +#define FIQ_CONTROL ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x0000020C)) +#define ENABLE_IRQS_1 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000210)) +#define ENABLE_IRQS_2 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000214)) +#define ENABLE_BASIC_IRQS ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000218)) +#define DISABLE_IRQS_1 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x0000021C)) +#define DISABLE_IRQS_2 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000220)) +#define DISABLE_BASIC_IRQS ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000224)) \ No newline at end of file diff --git a/lab_3/shell/include/uart.h b/lab_3/shell/include/uart.h index 245c358c8..e2751a08a 100644 --- a/lab_3/shell/include/uart.h +++ b/lab_3/shell/include/uart.h @@ -23,8 +23,27 @@ * */ +#include "gpio.h" + +#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004)) +#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040)) +#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044)) +#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048)) +#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C)) +#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050)) +#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054)) +#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058)) +#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C)) +#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060)) +#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064)) +#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068)) + void uart_init(); void uart_send(unsigned int c); char uart_getc(); void uart_puts(char *s); -void uart_hex(unsigned int d); \ No newline at end of file +void uart_hex(unsigned int d); +void uart_read_handler(); +void uart_write_handler(); +void uart_enable_interrupt(); +void demo_async_uart(); \ No newline at end of file diff --git a/lab_3/shell/interrupt.c b/lab_3/shell/interrupt.c new file mode 100644 index 000000000..f2203f3b0 --- /dev/null +++ b/lab_3/shell/interrupt.c @@ -0,0 +1,48 @@ +#include "include/interrupt.h" +#include "include/uart.h" + +#define CORE0_INTERRUPT_SOURCE ((volatile unsigned int*)(0x40000060)) +// print_boot_timer +// cntfrq_el0 = 62500000 +int print_boot_timer(){ + uart_puts("Interrupt occurs!\n"); + unsigned long long freq, ticks; + asm volatile( + "mrs %0, cntfrq_el0;" + "mrs %1, cntpct_el0;" + : "=r" (freq), "=r" (ticks) + ); + // set up the next timer + asm volatile ( + "msr cntp_tval_el0, %0" + : + : "r" (freq * 2) + ); + unsigned int time = (unsigned int)(ticks/freq); + uart_hex(time); + uart_puts(" seconds elapsed\n"); + return 0; +} + + +void interrupt_entry(){ + //asm volatile("msr DAIFSet, 0xf"); + // int irq_pending1 = *IRQ_PENDING_1; + int core0_irq = *CORE0_INTERRUPT_SOURCE; + int iir = *AUX_MU_IIR; + if (core0_irq & (1 << 1)){ + print_boot_timer(); + } + else{ + // P13, Receiver holds valid byte + if ((iir & 0x06) == 0x04){ + uart_read_handler(); + } + // P13, Transmit holding register empty + //else if((iir & 0x06) == 0x02){ + else{ + uart_write_handler(); + } + } + return; +} diff --git a/lab_3/shell/interrupts.S b/lab_3/shell/interrupts.S index 2527491c6..a4e530822 100644 --- a/lab_3/shell/interrupts.S +++ b/lab_3/shell/interrupts.S @@ -62,9 +62,11 @@ core_timer_enable: str w0, [x1] // unmask timer interrupt ret -.global core_timer_handler -core_timer_handler: +.global interrupt_handler +interrupt_handler: save_all - bl print_boot_timer + bl interrupt_entry load_all - eret \ No newline at end of file + eret + + \ No newline at end of file diff --git a/lab_3/shell/main.c b/lab_3/shell/main.c index 6003babb8..43d8e9d68 100644 --- a/lab_3/shell/main.c +++ b/lab_3/shell/main.c @@ -47,7 +47,6 @@ void main(int argc, char* argv[]){ uart_puts("Booted! Current EL: "); uart_send('0' + el); uart_puts("\n"); - //cpio_exec("user_program.img"); core_timer_enable(); while(1){ @@ -66,9 +65,11 @@ void main(int argc, char* argv[]){ command[length==MAX_BUFFER?length-2:length-1] = '\0'; if(strcmp(command, "help") == 0){ uart_puts("help\t: print this help menu\n"); - uart_puts("ls\t: list all files in the root filesystem\n"); - uart_puts("cat \t: print the content of file in root filesystem\n"); + uart_puts("ls\t: list all files in initfs\n"); + uart_puts("cat \t: print the content of file in initfs\n"); uart_puts("hello\t: print hello world!\n"); + uart_puts("exec: execute user program in initfs"); + uart_puts("async_uart: switch to async uart mode (currently for demo only)"); uart_puts("reboot\t: reboot the device\n"); } else if(strcmp(command, "hello") == 0){ @@ -77,6 +78,9 @@ void main(int argc, char* argv[]){ else if(strcmp(command, "ls") == 0){ cpio_ls(); } + else if(strcmp(command, "async_uart") == 0){ + demo_async_uart(); + } else if(strcmp(command, "reboot") == 0){ reset(); } diff --git a/lab_3/shell/uart.c b/lab_3/shell/uart.c index 489c6608a..dee6592ce 100644 --- a/lab_3/shell/uart.c +++ b/lab_3/shell/uart.c @@ -24,23 +24,26 @@ */ #include "include/gpio.h" - +#include "include/uart.h" /** Auxilary mini UART registers * Address & Description refer: https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf Page.8 */ -#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004)) -#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040)) -#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044)) -#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048)) -#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C)) -#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050)) -#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054)) -#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058)) -#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C)) -#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060)) -#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064)) -#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068)) + +/* + The definition below is for async uart IO +*/ + +#define BUFFER_SIZE 1024 +#define IRQS1 ((volatile unsigned int *)(0x3f00b210)) +char uart_read_buffer[BUFFER_SIZE]; +unsigned int read_idx = 0; + +char uart_write_buffer[BUFFER_SIZE]; +unsigned int write_idx = 0; +unsigned int write_cur = 0; +int async; + /** * Set baud rate and characteristics (115200 8N1) and map to GPIO @@ -74,7 +77,7 @@ void uart_init() * Send a character */ void uart_send(unsigned int c) { - /* wait until we can send */ + /* This bit is set if the transmit FIFO can accept at least one byte*/ do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20)); /* write the character to the buffer */ *AUX_MU_IO=c; @@ -118,4 +121,42 @@ void uart_hex(unsigned int d) { n+=n>9?0x37:0x30; uart_send(n); } +} + +void uart_enable_interrupt(){ + *AUX_MU_IER |= 0x02; + *IRQS1 |= 1 << 29; +} + +void uart_load_buffer(){ + while(write_cur < write_idx){ + uart_send(uart_write_buffer[write_cur]); + } +} + +void demo_async_uart(){ + uart_puts("turning to async mode...\n"); + uart_enable_interrupt(); + while(1){ + asm volatile("nop"); + } +} + +void uart_read_handler() { + char ch = (char)(*AUX_MU_IO); + uart_read_buffer[write_idx] = ch; + write_idx++; + uart_write_buffer[write_idx] = ch; + read_idx++; + write_idx++; + if(ch == '\r'){ + uart_puts(uart_write_buffer); + } +} + +void uart_write_handler(){ + if(write_cur < write_idx){ + *AUX_MU_IO=uart_read_buffer[write_cur]; + write_cur++; + } } \ No newline at end of file From 1c49259819ad7eb299dd5e4a88ea81dbcc34a05e Mon Sep 17 00:00:00 2001 From: laxiflora Date: Thu, 20 Jun 2024 15:44:25 +0800 Subject: [PATCH 12/23] Finish lab4 allocation (free function to be implemented) --- lab_4/Makefile | 52 +++++++ lab_4/Makefile.gcc | 52 +++++++ lab_4/README.md | 6 + lab_4/bootloader/Makefile | 59 ++++++++ lab_4/bootloader/bcm2710-rpi-3-b-plus.dtb | Bin 0 -> 35026 bytes lab_4/bootloader/device_tree.c | 74 ++++++++++ lab_4/bootloader/include/device_tree.h | 34 +++++ lab_4/bootloader/include/gpio.h | 45 ++++++ lab_4/bootloader/include/mbox.h | 48 +++++++ lab_4/bootloader/include/stdint.h | 9 ++ lab_4/bootloader/include/uart.h | 30 ++++ lab_4/bootloader/include/utils.h | 4 + lab_4/bootloader/initramfs.cpio | Bin 0 -> 1024 bytes lab_4/bootloader/kernel_uploader.py | 94 +++++++++++++ lab_4/bootloader/link.ld | 55 ++++++++ lab_4/bootloader/main.c | 60 ++++++++ lab_4/bootloader/mbox.c | 64 +++++++++ lab_4/bootloader/reader.py | 9 ++ lab_4/bootloader/start.S | 43 ++++++ lab_4/bootloader/uart.c | 134 ++++++++++++++++++ lab_4/bootloader/utils.c | 61 ++++++++ lab_4/config.txt | 2 + lab_4/rootfs/hello.txt | 1 + lab_4/rootfs/hello2.txt | 1 + lab_4/rootfs/link.ld | 44 ++++++ lab_4/rootfs/makefile | 36 +++++ lab_4/rootfs/user_program | Bin 0 -> 5704 bytes lab_4/rootfs/user_program.S | 13 ++ lab_4/rootfs/user_program.elf | Bin 0 -> 928 bytes lab_4/rootfs/user_program.img | Bin 0 -> 24 bytes lab_4/shell/Makefile | 61 ++++++++ lab_4/shell/allocator.c | 158 +++++++++++++++++++++ lab_4/shell/cpio.c | 102 ++++++++++++++ lab_4/shell/exception_vector.S | 102 ++++++++++++++ lab_4/shell/exceptions.c | 25 ++++ lab_4/shell/include/allocator.h | 27 ++++ lab_4/shell/include/cpio.h | 21 +++ lab_4/shell/include/gpio.h | 45 ++++++ lab_4/shell/include/interrupt.h | 13 ++ lab_4/shell/include/mbox.h | 48 +++++++ lab_4/shell/include/stdint.h | 9 ++ lab_4/shell/include/uart.h | 49 +++++++ lab_4/shell/include/utils.h | 8 ++ lab_4/shell/initramfs.cpio | Bin 0 -> 12288 bytes lab_4/shell/interrupt.c | 48 +++++++ lab_4/shell/interrupts.S | 72 ++++++++++ lab_4/shell/link.ld | 44 ++++++ lab_4/shell/main.c | 135 ++++++++++++++++++ lab_4/shell/mbox.c | 64 +++++++++ lab_4/shell/start.S | 44 ++++++ lab_4/shell/uart.c | 162 ++++++++++++++++++++++ lab_4/shell/utils.c | 111 +++++++++++++++ 52 files changed, 2378 insertions(+) create mode 100644 lab_4/Makefile create mode 100644 lab_4/Makefile.gcc create mode 100644 lab_4/README.md create mode 100644 lab_4/bootloader/Makefile create mode 100644 lab_4/bootloader/bcm2710-rpi-3-b-plus.dtb create mode 100644 lab_4/bootloader/device_tree.c create mode 100644 lab_4/bootloader/include/device_tree.h create mode 100644 lab_4/bootloader/include/gpio.h create mode 100644 lab_4/bootloader/include/mbox.h create mode 100644 lab_4/bootloader/include/stdint.h create mode 100644 lab_4/bootloader/include/uart.h create mode 100644 lab_4/bootloader/include/utils.h create mode 100644 lab_4/bootloader/initramfs.cpio create mode 100644 lab_4/bootloader/kernel_uploader.py create mode 100644 lab_4/bootloader/link.ld create mode 100644 lab_4/bootloader/main.c create mode 100644 lab_4/bootloader/mbox.c create mode 100644 lab_4/bootloader/reader.py create mode 100644 lab_4/bootloader/start.S create mode 100644 lab_4/bootloader/uart.c create mode 100644 lab_4/bootloader/utils.c create mode 100644 lab_4/config.txt create mode 100644 lab_4/rootfs/hello.txt create mode 100644 lab_4/rootfs/hello2.txt create mode 100644 lab_4/rootfs/link.ld create mode 100644 lab_4/rootfs/makefile create mode 100755 lab_4/rootfs/user_program create mode 100644 lab_4/rootfs/user_program.S create mode 100755 lab_4/rootfs/user_program.elf create mode 100755 lab_4/rootfs/user_program.img create mode 100644 lab_4/shell/Makefile create mode 100644 lab_4/shell/allocator.c create mode 100644 lab_4/shell/cpio.c create mode 100644 lab_4/shell/exception_vector.S create mode 100644 lab_4/shell/exceptions.c create mode 100644 lab_4/shell/include/allocator.h create mode 100644 lab_4/shell/include/cpio.h create mode 100644 lab_4/shell/include/gpio.h create mode 100644 lab_4/shell/include/interrupt.h create mode 100644 lab_4/shell/include/mbox.h create mode 100644 lab_4/shell/include/stdint.h create mode 100644 lab_4/shell/include/uart.h create mode 100644 lab_4/shell/include/utils.h create mode 100644 lab_4/shell/initramfs.cpio create mode 100644 lab_4/shell/interrupt.c create mode 100644 lab_4/shell/interrupts.S create mode 100644 lab_4/shell/link.ld create mode 100644 lab_4/shell/main.c create mode 100644 lab_4/shell/mbox.c create mode 100644 lab_4/shell/start.S create mode 100644 lab_4/shell/uart.c create mode 100644 lab_4/shell/utils.c diff --git a/lab_4/Makefile b/lab_4/Makefile new file mode 100644 index 000000000..015d9ea3d --- /dev/null +++ b/lab_4/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles +BOOTLOADER_BIN = kernel8.img +all: clean kernel8.img + +start.o: start.S + $(GCC) $(CFLAGS) -c start.S -o start.o + +%.o: %.c + $(GCC) $(CFLAGS) -c $< -o $@ -g + +kernel8.img: start.o $(OBJS) + $(LD) -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + $(OBJCPY) -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -d in_asm + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_4/Makefile.gcc b/lab_4/Makefile.gcc new file mode 100644 index 000000000..77366f3cf --- /dev/null +++ b/lab_4/Makefile.gcc @@ -0,0 +1,52 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles + +all: clean kernel8.img + +start.o: start.S + $(GCC) $(CFLAGS) -c start.S -o start.o + +%.o: %.c + $(GCC) $(CFLAGS) -c $< -o $@ -g + +kernel8.img: start.o $(OBJS) + $(LD) -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + $(OBJCPY) -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_4/README.md b/lab_4/README.md new file mode 100644 index 000000000..ff2c23e3f --- /dev/null +++ b/lab_4/README.md @@ -0,0 +1,6 @@ +1. python UART transfer data loss +2. init UART register to avoid garbage pending +3. link loader can arrange the .text section freely + - why align +4. wze is for halting CPU that is not id 0 +5. \ No newline at end of file diff --git a/lab_4/bootloader/Makefile b/lab_4/bootloader/Makefile new file mode 100644 index 000000000..2a00a5890 --- /dev/null +++ b/lab_4/bootloader/Makefile @@ -0,0 +1,59 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles +BOOTLOADER_BIN = kernel8.img +all: clean kernel8.img + +start.o: start.S + $(GCC) $(CFLAGS) -c start.S -o start.o + +%.o: %.c + $(GCC) $(CFLAGS) -c $< -o $@ -g + +kernel8.img: start.o $(OBJS) + $(LD) -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + $(OBJCPY) -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -dtb bcm2710-rpi-3-b-plus.dtb + +run_asm: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -dtb bcm2710-rpi-3-b-plus.dtb -d in_asm + + +run_stdio: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial stdio -display none -dtb bcm2710-rpi-3-b-plus.dtb + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_4/bootloader/bcm2710-rpi-3-b-plus.dtb b/lab_4/bootloader/bcm2710-rpi-3-b-plus.dtb new file mode 100644 index 0000000000000000000000000000000000000000..a219bf3d5ca7a1e6d14618556f73a73911460911 GIT binary patch literal 35026 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 literal 0 HcmV?d00001 diff --git a/lab_4/bootloader/device_tree.c b/lab_4/bootloader/device_tree.c new file mode 100644 index 000000000..6370eb7b7 --- /dev/null +++ b/lab_4/bootloader/device_tree.c @@ -0,0 +1,74 @@ +#include "include/device_tree.h" +#include "include/uart.h" +// #include +// #include + +device_tree_header myHeader; + +void header_parser(uintptr_t dtb_address){ + uint32_t* start; + //uint32_t* dtb = mock_load_file(); + uint32_t* dtb = dtb_address; + start = dtb; + // __builtin_bswap32() is a GCC built-in function to convert to the system's endianness.(RPi uses little-endian) + myHeader.magic = __builtin_bswap32(*dtb++); + if ((myHeader.magic - 0xd00dfeed) != 0) { + uart_puts("DTB magic number doesn't match!\r\n"); + return 1; + } + myHeader.totalsize = __builtin_bswap32(*dtb++); + myHeader.off_dt_struct = __builtin_bswap32(*dtb++); + myHeader.off_dt_strings = __builtin_bswap32(*dtb++); + myHeader.off_mem_rsvmap = __builtin_bswap32(*dtb++); + myHeader.version = __builtin_bswap32(*dtb++); + myHeader.last_comp_version = __builtin_bswap32(*dtb++); + myHeader.boot_cpuid_phys = __builtin_bswap32(*dtb++); + myHeader.size_dt_strings = __builtin_bswap32(*dtb++); + myHeader.size_dt_struct = __builtin_bswap32(*dtb++); + + // jump to structure + uint32_t* structure_ptr = (uint32_t *)(start + myHeader.off_dt_struct); + while(1){ + uint32_t token = __builtin_bswap32(*structure_ptr++); + if(token == FDT_BEGIN_NODE){ + uart_puts("Start\n"); + } + } + + //The node’s name as a null-terminated string + + + +} + +// unsigned long* mock_load_file() { +// FILE *file = fopen("bcm2710-rpi-3-b-plus.dtb", "rb"); +// if (!file) { +// perror("Failed to open file"); +// return 1; +// } + +// // Get the size of the file +// fseek(file, 0, SEEK_END); +// long fileSize = ftell(file); +// rewind(file); + +// // Allocate memory to hold the entire file +// unsigned char *buffer = (unsigned char *)malloc(fileSize); +// if (!buffer) { +// perror("Failed to allocate memory"); +// fclose(file); +// return 1; +// } + +// // Read the entire file into the buffer +// size_t bytesRead = fread(buffer, 1, fileSize, file); +// if (bytesRead != fileSize) { +// perror("Failed to read file"); +// free(buffer); +// fclose(file); +// return 1; +// } + +// return (unsigned long*)buffer; +// } \ No newline at end of file diff --git a/lab_4/bootloader/include/device_tree.h b/lab_4/bootloader/include/device_tree.h new file mode 100644 index 000000000..6846d0cba --- /dev/null +++ b/lab_4/bootloader/include/device_tree.h @@ -0,0 +1,34 @@ +#include "stdint.h" + + +typedef struct fdt_header { + // 0xd00dfeed (big-endian) + uint32_t magic; + uint32_t totalsize; + // offsets of each block from start + uint32_t off_dt_struct; + uint32_t off_dt_strings; + uint32_t off_mem_rsvmap; + + uint32_t version; + uint32_t last_comp_version; + // physical ID of the system’s boot CPU + uint32_t boot_cpuid_phys; + uint32_t size_dt_strings; + uint32_t size_dt_struct; +} device_tree_header; + +#define ALIGN_MEMORY_BLOCK 8 + +/* All tokens shall be aligned on a 32-bit boundary */ +#define ALIGN_STRUCT_BLOCK 4 + +/* tokens used for structure block */ +#define FDT_BEGIN_NODE 0x00000001 +#define FDT_END_NODE 0x00000002 +#define FDT_PROP 0x00000003 +#define FDT_NOP 0x00000004 +#define FDT_END 0x00000009 + + +void header_parser(); diff --git a/lab_4/bootloader/include/gpio.h b/lab_4/bootloader/include/gpio.h new file mode 100644 index 000000000..52fa671d0 --- /dev/null +++ b/lab_4/bootloader/include/gpio.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#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)) diff --git a/lab_4/bootloader/include/mbox.h b/lab_4/bootloader/include/mbox.h new file mode 100644 index 000000000..e0e2e41f1 --- /dev/null +++ b/lab_4/bootloader/include/mbox.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/* a properly aligned buffer */ +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 MBOX_TAG_GETSERIAL 0x10004 +#define MBOX_TAG_REVISION 0x00010002 +#define MBOX_TAG_MEMORY 0x00010005 +#define MBOX_TAG_LAST 0 + +int mbox_call(unsigned char ch); diff --git a/lab_4/bootloader/include/stdint.h b/lab_4/bootloader/include/stdint.h new file mode 100644 index 000000000..3ddcc9b17 --- /dev/null +++ b/lab_4/bootloader/include/stdint.h @@ -0,0 +1,9 @@ + +typedef unsigned int uint16_t; + +typedef unsigned long uint32_t; + +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +typedef float float32; +typedef double float64; \ No newline at end of file diff --git a/lab_4/bootloader/include/uart.h b/lab_4/bootloader/include/uart.h new file mode 100644 index 000000000..245c358c8 --- /dev/null +++ b/lab_4/bootloader/include/uart.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +void uart_init(); +void uart_send(unsigned int c); +char uart_getc(); +void uart_puts(char *s); +void uart_hex(unsigned int d); \ No newline at end of file diff --git a/lab_4/bootloader/include/utils.h b/lab_4/bootloader/include/utils.h new file mode 100644 index 000000000..b993a5b68 --- /dev/null +++ b/lab_4/bootloader/include/utils.h @@ -0,0 +1,4 @@ +void set(long addr, unsigned int value); +void reset(); +int strcmp(char* a, char* b); +void cancel_reset(); \ No newline at end of file diff --git a/lab_4/bootloader/initramfs.cpio b/lab_4/bootloader/initramfs.cpio new file mode 100644 index 0000000000000000000000000000000000000000..e9c1dda97f1391b336871a2da59e34bd241fa43f GIT binary patch literal 1024 zcmeH@K@Ng26hv8j3b+87mIiQ%u_Pw0h!HOt3;y|ZOd9-B4l9R&fn>^y@5k6kI zmbaUt8zE&!W7VrbFV(b 0: + received_content = read_line(s) + print(received_content) + +with open("../shell/shell_kernel.img", "rb") as f: + sent_size = 0 # Initialize size counter + + byte = f.read(1) # Read the first byte + while byte: + s.write(byte) # Send the byte over serial + # s.flush() # Flush the output buffer + sent_size += 1 # Increment size counter + byte = f.read(1) # Read the next byte + + +assert sent_size == size +print("kernel sent successfully.") +# Register signal handlers +signal.signal(signal.SIGTSTP, tstp_handler) +signal.signal(signal.SIGCONT, cont_handler) + +print(f"Process ID: {os.getpid()}") + +# Run a loop to keep the program alive and responsive to signals +while True: + received_content = read_line(s) + print(received_content) + +# # get response of whether kernel is loaded successfully or not +# time.sleep(1) +# while(True): +# while s.in_waiting > 0: +# received_content = read_line(s) +# print(received_content) +# print("#", end=" ") +# inp = input() +# if(inp == ""): +# continue +# inp += "\n" +# bytes_to_send = inp.encode('utf-8') +# s.write(bytes_to_send) +# #while s.in_waiting > 0: +# # received_content = read_line(s) +# # print(received_content) +# time.sleep(1) \ No newline at end of file diff --git a/lab_4/bootloader/link.ld b/lab_4/bootloader/link.ld new file mode 100644 index 000000000..5d4536049 --- /dev/null +++ b/lab_4/bootloader/link.ld @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +SECTIONS +{ + . = 0x60000; + PROVIDE(_head = .); + .relocate : { + KEEP(*(.text.relocate)) + } + . = ALIGN(4096); + + .imgLoader : { + KEEP(*(.text.load_img)) + } + . = ALIGN(4096); + .text : { + KEEP(*(.text.boot)) + *(.text) + } + . = ALIGN(4096); + PROVIDE(_data = .); + .data : { *(.data .data.*) } + .bss : { + . = ALIGN(16); + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + _end = .; +} +__bss_size = (__bss_end - __bss_start)>>3; +__loader_size = (_end - _head)>>3; \ No newline at end of file diff --git a/lab_4/bootloader/main.c b/lab_4/bootloader/main.c new file mode 100644 index 000000000..e8be04b8c --- /dev/null +++ b/lab_4/bootloader/main.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#define MAX_BUFFER 10 +#include "include/uart.h" +#include "include/utils.h" +#include "include/mbox.h" +#include "include/stdint.h" +#include "include/device_tree.h" + +void load_img(){ + unsigned int size = 0; + unsigned char *size_buffer = (unsigned char *) &size; + uart_puts("enter kernel size now:"); + for(int i=0; i<4; i++) + size_buffer[i] = uart_getc(); + uart_puts("size-check correct\n"); + + uart_puts("Kernel size received: "); + uart_hex(size); + uart_puts("\n"); + + char *kernel = (char *) 0x80000; + while(size--) *kernel++ = uart_getc(); + + uart_puts("kernel-loaded\n"); + return; + +} + +void relocator(uintptr_t dtb_address){ + uart_init(); + // header_parser(dtb_address); + load_img(); + asm volatile( + "mov x30, 0x80000;" + "ret;" + ); +} diff --git a/lab_4/bootloader/mbox.c b/lab_4/bootloader/mbox.c new file mode 100644 index 000000000..b5b47c2f2 --- /dev/null +++ b/lab_4/bootloader/mbox.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "include/gpio.h" + +/* mailbox message buffer +* The buffer itself is 16-byte aligned as only the upper 28 bits of the address can be passed via the mailbox. +*/ +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 +#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) +{ + 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? */ + 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; +} diff --git a/lab_4/bootloader/reader.py b/lab_4/bootloader/reader.py new file mode 100644 index 000000000..19a5e759a --- /dev/null +++ b/lab_4/bootloader/reader.py @@ -0,0 +1,9 @@ +with open("./bcm2710-rpi-3-b-plus.dtb", "rb") as f: + data = f.read() +# Filter out the 0x00 bytes +filtered_data = bytes(b for b in data if b != 0x00) + +# Print the filtered binary data +print(filtered_data) + +#print(data) \ No newline at end of file diff --git a/lab_4/bootloader/start.S b/lab_4/bootloader/start.S new file mode 100644 index 000000000..b086305c4 --- /dev/null +++ b/lab_4/bootloader/start.S @@ -0,0 +1,43 @@ +.section ".text.relocate" +.global _relocate + +_relocate: + // relocate our code from load address to link address + ldr x1, =0x80000; // src address + ldr x2, =0x60000; // target address + ldr w3, =__loader_size +1: ldr x4, [x1], #8 + str x4, [x2], #8 + sub w3, w3, #1 + cbnz w3, 1b + + ldr x1, =_start + mov sp, x1 + + // clear bss + ldr x1, =__bss_start + ldr w2, =__bss_size +2: cbz w2, 3f + str xzr, [x1], #8 + sub w2, w2, #1 + cbnz w2, 2b + + +3: // Device tree address has been moved from x0 to x10 within the bootloader. + mov x0, x10 + bl relocator-0x20000 + b _start + + +.section ".text.boot" + +.global _start + +_start: + // jump to main function in C + bl 0x80000 + // halt this core if return +1: + wfe + b 1b + diff --git a/lab_4/bootloader/uart.c b/lab_4/bootloader/uart.c new file mode 100644 index 000000000..5e63f2d3a --- /dev/null +++ b/lab_4/bootloader/uart.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "include/gpio.h" + +/** Auxilary mini UART registers + * Address & Description refer: https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf Page.8 + */ + +#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004)) +#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040)) +#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044)) +#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048)) +#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C)) +#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050)) +#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054)) +#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058)) +#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C)) +#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060)) +#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064)) +#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068)) + +/** + * Set baud rate and characteristics (115200 8N1) and map to GPIO + */ +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *AUX_ENABLE |=1; // enable UART1, AUX mini uart + *AUX_MU_CNTL = 0; + *AUX_MU_LCR = 3; // 8 bits + *AUX_MU_MCR = 0; + *AUX_MU_IER = 0; + *AUX_MU_IIR = 0xc6; // disable interrupts + *AUX_MU_BAUD = 270; // 115200 baud + /* map UART1 to GPIO pins */ + r=*GPFSEL1; + r&=~((7<<12)|(7<<15)); // gpio14, gpio15 + r|=(2<<12)|(2<<15); // alt5 + *GPFSEL1 = r; + *GPPUD = 0; // enable pins 14 and 15 + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; // flush GPIO setup + *AUX_MU_CNTL = 3; // enable Tx, Rx + /*EXTRA: Read from AUX_MU_IO until AUX_MU_LSR indicates no more data*/ + while (*AUX_MU_LSR & 0x01) { + // Read and discard the data + volatile unsigned int data = *AUX_MU_IO; + (void)data; // Prevent unused variable warning + } +} + +void uart_enable_interrupt(){ + // enable tx rx interrupt in uart + *AUX_MU_IER |= 0x02; + *IRQS1 |= 1 << 29; +} + + +/** + * Send a character + */ +void uart_send(unsigned int c) { + /* wait until we can send */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20)); + /* write the character to the buffer */ + *AUX_MU_IO=c; +} + +/** + * Receive a character + */ +char uart_getc() { + char r; + /* wait until something is in the buffer */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01)); + /* read it and return */ + r=(char)(*AUX_MU_IO); + /* convert carriage return to newline */ + return r=='\r'?'\n':r; +} + +/** + * Display a string + */ +void uart_puts(char *s) { + while(*s) { + /* convert newline to carriage return + newline */ + if(*s=='\n') + uart_send('\r'); + uart_send(*s++); + } +} + +/** + * Display a binary value in hexadecimal + */ +void uart_hex(unsigned int d) { + unsigned int n; + int c; + for(c=28;c>=0;c-=4) { + // get highest tetrad + n=(d>>c)&0xF; + // 0-9 => '0'-'9', 10-15 => 'A'-'F' + n+=n>9?0x37:0x30; + uart_send(n); + } +} \ No newline at end of file diff --git a/lab_4/bootloader/utils.c b/lab_4/bootloader/utils.c new file mode 100644 index 000000000..d31e58159 --- /dev/null +++ b/lab_4/bootloader/utils.c @@ -0,0 +1,61 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC 0x3F10001c +#define PM_WDOG 0x3F100024 + +/** + * compare two string, given s1 and s2 + * return 0 if the both string are equal; + * return -1 if s1 is less than s2; + * return 1 if s1 is greater than s2 + */ +int strcmp(char* a, char* b){ + int value = 0; + while(*a != '\0' && *b != '\0'){ + if(*a < *b){ + return -1; + } + else if(*a > *b){ + return 1; + } + else{ + a++; + b++; + } + } + if(*a == '\0'){ + value++; + } + if(*b == '\0'){ + value--; + } + return value; +} + +/** + * set up given value to given address + */ +void set(long addr, unsigned int value) { + volatile unsigned int* point = (unsigned int*)addr; + *point = value; +} + + +/** + * reboot respberry pi + * if tick=0, reboot instantly; + * otherwise, wait for tick seconds to reboot + */ +void reset(int tick) { // reboot after watchdog timer expire + set(PM_RSTC, PM_PASSWORD | 0x20); // full reset + if(tick != 0){ + set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick + } +} + +/** + * clear reboot register + */ +void cancel_reset() { + set(PM_RSTC, PM_PASSWORD | 0); // full reset + set(PM_WDOG, PM_PASSWORD | 0); // number of watchdog tick +} \ No newline at end of file diff --git a/lab_4/config.txt b/lab_4/config.txt new file mode 100644 index 000000000..7e9ff304c --- /dev/null +++ b/lab_4/config.txt @@ -0,0 +1,2 @@ +initramfs initramfs.cpio 0x80000000 +kernel=bootloader.img \ No newline at end of file diff --git a/lab_4/rootfs/hello.txt b/lab_4/rootfs/hello.txt new file mode 100644 index 000000000..ca9e3b5cc --- /dev/null +++ b/lab_4/rootfs/hello.txt @@ -0,0 +1 @@ +this is a example file. diff --git a/lab_4/rootfs/hello2.txt b/lab_4/rootfs/hello2.txt new file mode 100644 index 000000000..d90bb747c --- /dev/null +++ b/lab_4/rootfs/hello2.txt @@ -0,0 +1 @@ +this is another example file. diff --git a/lab_4/rootfs/link.ld b/lab_4/rootfs/link.ld new file mode 100644 index 000000000..bd0d89847 --- /dev/null +++ b/lab_4/rootfs/link.ld @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +SECTIONS +{ + . = 0x30000; + PROVIDE(_head = .); + .text : { KEEP(*(.text.boot)) *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + PROVIDE(_data = .); + .data : { *(.data .data.*) } + .bss : { + . = ALIGN(16); + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + _end = .; +} +__bss_size = (__bss_end - __bss_start)>>3; +__loader_size = (_end - _head)>>3; \ No newline at end of file diff --git a/lab_4/rootfs/makefile b/lab_4/rootfs/makefile new file mode 100644 index 000000000..1f075562f --- /dev/null +++ b/lab_4/rootfs/makefile @@ -0,0 +1,36 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.S=.o) +CFLAGS = -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles +BOOTLOADER_BIN = kernel8.img +all: user_program.S + "aarch64-linux-gnu-gcc" -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles -c user_program.S -o user_program.o + "aarch64-linux-gnu-ld" -nostdlib -nostartfiles user_program.o -T link.ld -o user_program.elf + "aarch64-linux-gnu-objcopy" -O binary user_program.elf user_program.img diff --git a/lab_4/rootfs/user_program b/lab_4/rootfs/user_program new file mode 100755 index 0000000000000000000000000000000000000000..e235f8e5dca3944e2e14158775cca560bee208ea GIT binary patch literal 5704 zcmeHLJ!lkB5T4}n>km0Kg5Y0aiZt0nlxSgbmtU1jA~6aPVcEMqyp#J0cN<7-Oc}vO z(B59KwYIYqv9U{`lF}3kB6!a1n{RWw-boY%i+ynWy_q-Pym_;?1M}`rXJ@**x(Fjd zFG!@RZlg)-!oU%oFr?`s_4D%}9iTpzdwiW)PaEJ>Gd9&Va6t75M&Z5E^(Y=!J0Kzy z?A5h)a9iUBl7AZWlvtBPhLs#L9)X|K84x^i_bc9O#wBF#D98&(7bVm$&Yn+I(7g_-^Cl z^N*Jj4<6tBdO`f)$J5^&8*liqkC^}V^f2u_Yc`kIfovI%I0JD8;ta$Yh%*ppAkILX zfj9$k2I36-w;A~Sy;+ms2DFbvubEa^dO;bZD(^F*c9}%`RX(P8R1xs4Y5cQ{RuN18 z1kvCAiSq=X3VnGiKSA9=UmMmZg1m+GJwd+0`d&g_!}`A9{voXI=e`&n@9qlkN?UF9 zgR~vd3%iGQn!9W>JLE(AecRbfbKAv!qVb$meKej4)+cF@AL01VbJJ)E~4bQ22Hl#w;4d(s|TdA(#I-Wx!5m}A(is$4Qy}H37W~HiEsIQP!t$79O zPIcAFt(N%SqvVn=6`e+rEO))i9t?VQvb@5Y=SxndlxM>lOZ>1_${wHhZw$Gok~gbm zA^2|a{oo!8dxif6L}z%RzlGoFz6gBW7eOB9$rr9I*dO%^ctQ=qix!_WuS@L$AN380 zdM5QyVh11k%dC_8CGhcG1Ec4S%GcB{>MQOaf!K%5{DE^ozR45eN(?gaUE&@M_j9P{ zh(Bq}$!3(8z{mHyrT2xfSM%Wf(DR=*#7EuPR(>>o@PM*6a)&*9)By1wE~?zygl|&%wgRdmvsU zTeoojIX8qv3|O-7{QcY|wx3Qf&YWHkJRE#L?_33ihVUI$03nV^6JmhA(ykFzSX%o4 z9mni9(X+bePk4BxUSE?D%D1YzBx+>omc&)vxc*Au!ok?|V^scwhqB^5$Dv9j`?Jm# zA;T8^j=~-I4gI0Qf7dzcz=MuDdmZ?R!pmxPUIfT-pC?&#m!(%(ya-b47l@*1o=5rh zV`9?ec7|x4#I$Nk#F?P{CXHugR!Ri$t_Q5V5{hJ z=l8(1lW&Xf`NbF{S0A!heaL<7=~{~YzA?zYeVSa4ziWdq?rqJKyc^$n T9i+V3f0M8_|I!E#{_uYTAnra7 literal 0 HcmV?d00001 diff --git a/lab_4/rootfs/user_program.img b/lab_4/rootfs/user_program.img new file mode 100755 index 0000000000000000000000000000000000000000..1adf648a4c1b9d2d1b5e9fa08b84e52ef2fafc78 GIT binary patch literal 24 gcmZQzXt>0{!Z4AMf#Hh02*bzK|Nn/dev/null 2>/dev/null || true + +run_asm: + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none -d in_asm + +run: + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none + +debug: + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none -s -S diff --git a/lab_4/shell/allocator.c b/lab_4/shell/allocator.c new file mode 100644 index 000000000..df8b3a21c --- /dev/null +++ b/lab_4/shell/allocator.c @@ -0,0 +1,158 @@ +#include "include/allocator.h" +#include "include/utils.h" +#include "include/uart.h" + +int the_array[AVAILABLE_PAGE_NUM]; +OrderList order_list[MAX_ORDER]; + + +/*Pop the top element in linked list, note I assume there EXIST AT LEAST ONE AVAILABLE NODE*/ +struct Node* list_pop(OrderList* target){ + Node* to_ret = target->root; + while(to_ret -> next != NULL){ + to_ret = to_ret->next; + } + target->root = target->root->next; + return to_ret; +} + +void init_order_list(){ + int current_order = MAX_ORDER-1; + int current_page_index = 0; + + // initialize order_list + for(int i=0;i= 0){ + while((current_page_index+_pow(2, current_order)-1) < AVAILABLE_PAGE_NUM){ + unsigned int allocated_size = _pow(2, current_order)*PAGE_SIZE; + // record the grouped block at The Array + the_array[current_page_index] = _pow(2, current_order); + // malloc a struct node to record the meta data of this block + Node* new_node = simple_malloc(sizeof(Node)); + // push into order list + new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*current_page_index); + new_node->page_index = current_page_index; + list_push_back(new_node, current_order); + + uart_puts("[Init] grouping block at address 0x"); + uart_hex(new_node->address); + uart_puts(" with 0x"); + uart_hex((unsigned int)allocated_size/PAGE_SIZE); + uart_puts(" pages and start at index "); + uart_hex((unsigned int)new_node->page_index); + uart_puts(" in The Array"); + uart_puts("\n"); + + current_page_index = current_page_index+_pow(2, current_order)+1; + } + current_order--; + } + // for(int i=0;iroot; + while(cur != NULL){ + uart_puts("address "); + uart_hex(cur->address); + uart_puts("\n"); + uart_hex(cur->page_index); + uart_puts("\n"); + cur = cur->next; + + } +} + +void init_buddy_system(){ + init_order_list(); +} + +int check_list_has_element(OrderList* target){ + return target->root != NULL; +} + +unsigned char* malloc_page(int request_page_num){ + //determine the minimum list order that this request needs + int current_order = 0; + int cut_freg = 0; + // start from allocating the smallest block until is can satisfy needs + + while(current_order _pow(2, current_order)){ + current_order++; + } + else{ + if(check_list_has_element(&order_list[current_order])){ + struct Node* allocated_address = list_pop(&order_list[current_order]); + // mark the block as OCCUPIED + // the_array[(unsigned int)allocated_address->page_index] = OCCUPIED; + //uart_hex((unsigned int)allocated_address->address-HEAP_START_ADDRESS); + // print the log + uart_puts("[Malloc] block that contains "); + uart_hex(_pow(2, current_order)); + uart_puts(" pages started from address 0x"); + uart_hex((unsigned int)allocated_address->address); + uart_puts(" to address 0x"); + uart_hex((unsigned int)((allocated_address->address)+_pow(2, current_order)*PAGE_SIZE)); + uart_puts(" with index starts from "); + uart_hex((unsigned int)allocated_address->page_index); + uart_puts("\n"); + int cutter_count = 1; + while(cut_freg > 0){ + int mid_page_index = allocated_address->page_index+(_pow(2, current_order-cutter_count)); + unsigned char* end_address = mid_page_index+_pow(2, current_order-cutter_count); + the_array[mid_page_index+1] = _pow(2, current_order-cutter_count); + Node* new_node = simple_malloc(sizeof(Node)); + // push into order list + new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*(mid_page_index+1)); + new_node->page_index = mid_page_index+1; + uart_puts("[Release redundant memory] block that contains "); + uart_hex(_pow(2, current_order-cutter_count)); + uart_puts(" pages started from address 0x"); + uart_hex(new_node->address); + uart_puts(" to address 0x"); + uart_hex(end_address); + uart_puts(" is freed \n"); + list_push_back(new_node, current_order-cutter_count); + cut_freg--; + cutter_count++; + } + + return allocated_address->address; + } + else{ + cut_freg++; // we may allocate more then 2 times more memory than needed + current_order++; + } + } + } + uart_puts("[Warning] malloc failed, returning 0x00\n"); + return 0x0; +} + + + +void list_push_back(Node* to_push, int order){ + OrderList* target_list = &(order_list[order]); + if(target_list->root == NULL){ + target_list->root = to_push; + } + else{ + Node* current = target_list->root; + while(current->next != NULL){ + current = current->next; + } + current->next = to_push; + } +} \ No newline at end of file diff --git a/lab_4/shell/cpio.c b/lab_4/shell/cpio.c new file mode 100644 index 000000000..53f870e6a --- /dev/null +++ b/lab_4/shell/cpio.c @@ -0,0 +1,102 @@ +#include "include/cpio.h" +#include "include/uart.h" +#include "include/stdint.h" +#include "include/utils.h" + +char* cpio_addr = (char *)0x8000000;; + +void cpio_ls(){ + char* addr = (char*) cpio_addr; + uart_puts((char *)(addr+sizeof(struct cpio_header))); + while(strcmp((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); + uart_puts(addr+sizeof(struct cpio_header)); + uart_puts("\n"); + addr += (headerPathname_size + file_size); + } +} + +void cpio_exec(char *filename){ + char *target = findFile(filename); + if (target){ + struct cpio_header *header = (struct cpio_header *)target; + unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize)); + unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; + + utils_align(&headerPathname_size,4); + utils_align(&file_size,4); + char *file_content = target + headerPathname_size; + + char *program_ptr = (char *) 0x30000; // load the user program into 0x30000 + char* start_point = (char*) 0x30000; + char* stack_pointer = (char *) (0x30000 + 0x3000); // Stack pointer for the user program, base address+0x3000 + for (unsigned int i = 0; i < file_size; i++){ + *program_ptr ++ = *file_content++; + } + asm volatile( + // 0x3c0 + "mov x0, 0x3c0;\n\t" + "msr spsr_el1, x0;\n\t" + // start address of user program + "mov x1, 0x30000;\n\t" + "msr elr_el1, x1;\n\t" + // sp for user program + "mov x2, %0;\n\t" + "msr sp_el0, x2;\n\t" + "eret;" + : // No output operands + : "r" (start_point), "r" (stack_pointer) + : "x0", "x1", "x2" // tell compiler x0~x2 has been used + ); + } + uart_puts("completed.\n"); +} + + + +void cpio_cat(char *filename){ + char *target = findFile(filename); + if (target){ + struct cpio_header *header = (struct cpio_header *)target; + unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize)); + unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; + + utils_align(&headerPathname_size,4); + utils_align(&file_size,4); + char *file_content = target + headerPathname_size; + for (unsigned int i = 0; i < file_size; i++) + { + uart_send(file_content[i]); + } + uart_puts("\n"); + } + else + { + uart_puts("Not found the file\n"); + } +} + +char *findFile(char *name){ + char *addr = (char *)cpio_addr; + while (strcmp((char *)(addr + sizeof(struct cpio_header)), "TRAILER!!!") != 0){ + if ((strcmp((char *)(addr + sizeof(struct cpio_header)), name) == 0)){ + return addr; + } + struct cpio_header* header = (struct cpio_header *)addr; + unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize));; + unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; + + utils_align(&headerPathname_size,4); + utils_align(&file_size,4); + addr += (headerPathname_size + file_size); + } + return 0; +} \ No newline at end of file diff --git a/lab_4/shell/exception_vector.S b/lab_4/shell/exception_vector.S new file mode 100644 index 000000000..6e5ea29a7 --- /dev/null +++ b/lab_4/shell/exception_vector.S @@ -0,0 +1,102 @@ +.align 11 // vector table should be aligned to 0x800 +.global exception_vector_table + +exception_vector_table: + b exception_handler // branch to a handler function. +.align 7 // entry size is 0x80, .align will pad 0 + b exception_handler +.align 7 + b exception_handler // reserved for FIQ(Fast Interrupt) +.align 7 + b exception_handler // reserved for SError +.align 7 + + b interrupt_handler // synchronous: caused by current excution instr. +.align 7 + b interrupt_handler +.align 7 + b interrupt_handler +.align 7 + b interrupt_handler +.align 7 + + b exception_handler // time interrupt +.align 7 + b exception_handler +.align 7 + b exception_handler +.align 7 + b exception_handler + + b exception_handler +.align 7 + b exception_handler +.align 7 + b exception_handler +.align 7 + b exception_handler +.align 7 + + + +.global set_exception_vector_table +set_exception_vector_table: + adr x4, exception_vector_table + msr vbar_el1, x4 + ret + +// save general registers to stack +.macro save_all + sub sp, sp, 32*9 + stp x0, x1, [sp, 16*0] + stp x2, x3, [sp, 16*1] + stp x4, x5, [sp, 16*2] + stp x6, x7, [sp, 16*3] + stp x8, x9, [sp, 16*4] + stp x10, x11, [sp, 16*5] + stp x12, x13, [sp, 16*6] + stp x14, x15, [sp, 16*7] + stp x16, x17, [sp, 16*8] + stp x18, x19, [sp, 16*9] + stp x20, x21, [sp, 16*10] + stp x22, x23, [sp, 16*11] + stp x24, x25, [sp, 16*12] + stp x26, x27, [sp, 16*13] + stp x28, x29, [sp, 16*14] + str x30, [sp, 16*15] + mrs x0, spsr_el1 + mrs x1, elr_el1 + stp x0, x1, [sp, 16*16] +.endm + + +// load general registers from stack + +.macro load_all + ldp x0, x1, [sp, 16*16] + msr spsr_el1, x0 + msr elr_el1, x1 + ldp x0, x1, [sp, 16*0] + ldp x2, x3, [sp, 16*1] + ldp x4, x5, [sp, 16*2] + ldp x6, x7, [sp, 16*3] + ldp x8, x9, [sp, 16*4] + ldp x10, x11, [sp, 16*5] + ldp x12, x13, [sp, 16*6] + ldp x14, x15, [sp, 16*7] + ldp x16, x17, [sp, 16*8] + ldp x18, x19, [sp, 16*9] + ldp x20, x21, [sp, 16*10] + ldp x22, x23, [sp, 16*11] + ldp x24, x25, [sp, 16*12] + ldp x26, x27, [sp, 16*13] + ldp x28, x29, [sp, 16*14] + ldr x30, [sp, 16*15] + add sp, sp, 32*9 +.endm + +exception_handler: + save_all + bl exception_entry + load_all + eret \ No newline at end of file diff --git a/lab_4/shell/exceptions.c b/lab_4/shell/exceptions.c new file mode 100644 index 000000000..60434e8c2 --- /dev/null +++ b/lab_4/shell/exceptions.c @@ -0,0 +1,25 @@ +#include "include/uart.h" + +int exception_entry(){ + uart_puts("exception entry!\n"); + + unsigned long long spsr_el1, elr_el1, esr_el1; + + asm volatile( + "mrs %0, spsr_el1;" + "mrs %1, elr_el1;" + "mrs %2, esr_el1;" + : "=r" (spsr_el1), "=r" (elr_el1), "=r" (esr_el1) + ); + uart_puts("spsr_el1: "); + uart_hex(spsr_el1); + uart_send('\n'); + uart_puts("elr_el1: "); + uart_hex(elr_el1); + uart_send('\n'); + uart_puts("esr_el1: "); + uart_hex(esr_el1); + uart_send('\n'); + + return 0; +} \ No newline at end of file diff --git a/lab_4/shell/include/allocator.h b/lab_4/shell/include/allocator.h new file mode 100644 index 000000000..1fcd626f3 --- /dev/null +++ b/lab_4/shell/include/allocator.h @@ -0,0 +1,27 @@ +#define HEAP_START_ADDRESS 0x10000000 +#define HEAP_END_ADDRESS 0x20000000 +#define PAGE_SIZE 0x1000 +#define AVAILABLE_PAGE_NUM (HEAP_END_ADDRESS-HEAP_START_ADDRESS)/PAGE_SIZE +#define MAX_ORDER 11 +#define FREE -1 +#define OCCUPIED -2 +#define NULL 0 + +typedef struct Node{ + unsigned char* address; + int page_index; // the index of node in The Array + struct Node* next; +}Node; + +typedef struct OrderList{ + int chain_length; + struct Node* root; +}OrderList; + +void init_buddy_system(); +void print_order_list(OrderList* list); +struct Node* list_pop(OrderList* target); +void init_order_list(); +unsigned char* malloc_page(int request_page_num); +int check_list_has_element(OrderList* target); +void list_push_back(Node* to_push, int order); \ No newline at end of file diff --git a/lab_4/shell/include/cpio.h b/lab_4/shell/include/cpio.h new file mode 100644 index 000000000..52c6da00e --- /dev/null +++ b/lab_4/shell/include/cpio.h @@ -0,0 +1,21 @@ +struct cpio_header { + char c_magic[6]; + char c_ino[8]; + char c_mode[8]; + char c_uid[8]; + char c_gid[8]; + char c_nlink[8]; + char c_mtime[8]; + char c_filesize[8]; + char c_devmajor[8]; + char c_devminor[8]; + char c_rdevmajor[8]; + char c_rdevminor[8]; + char c_namesize[8]; + char c_check[8]; +}; + +void cpio_ls(); +void cpio_cat(char *filename); +void cpio_exec(char* filename); +char *findFile(char *name); \ No newline at end of file diff --git a/lab_4/shell/include/gpio.h b/lab_4/shell/include/gpio.h new file mode 100644 index 000000000..52fa671d0 --- /dev/null +++ b/lab_4/shell/include/gpio.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#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)) diff --git a/lab_4/shell/include/interrupt.h b/lab_4/shell/include/interrupt.h new file mode 100644 index 000000000..4683019db --- /dev/null +++ b/lab_4/shell/include/interrupt.h @@ -0,0 +1,13 @@ +#define BASE_INTERRUPT_REGISTER 0x7E00B000 + + +#define IRQ_BASIC_PENDING ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000200)) +#define IRQ_PENDING_1 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000204)) +#define IRQ_PENDING_2 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000208)) +#define FIQ_CONTROL ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x0000020C)) +#define ENABLE_IRQS_1 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000210)) +#define ENABLE_IRQS_2 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000214)) +#define ENABLE_BASIC_IRQS ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000218)) +#define DISABLE_IRQS_1 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x0000021C)) +#define DISABLE_IRQS_2 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000220)) +#define DISABLE_BASIC_IRQS ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000224)) \ No newline at end of file diff --git a/lab_4/shell/include/mbox.h b/lab_4/shell/include/mbox.h new file mode 100644 index 000000000..e0e2e41f1 --- /dev/null +++ b/lab_4/shell/include/mbox.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/* a properly aligned buffer */ +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 MBOX_TAG_GETSERIAL 0x10004 +#define MBOX_TAG_REVISION 0x00010002 +#define MBOX_TAG_MEMORY 0x00010005 +#define MBOX_TAG_LAST 0 + +int mbox_call(unsigned char ch); diff --git a/lab_4/shell/include/stdint.h b/lab_4/shell/include/stdint.h new file mode 100644 index 000000000..3ddcc9b17 --- /dev/null +++ b/lab_4/shell/include/stdint.h @@ -0,0 +1,9 @@ + +typedef unsigned int uint16_t; + +typedef unsigned long uint32_t; + +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +typedef float float32; +typedef double float64; \ No newline at end of file diff --git a/lab_4/shell/include/uart.h b/lab_4/shell/include/uart.h new file mode 100644 index 000000000..e2751a08a --- /dev/null +++ b/lab_4/shell/include/uart.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "gpio.h" + +#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004)) +#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040)) +#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044)) +#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048)) +#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C)) +#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050)) +#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054)) +#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058)) +#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C)) +#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060)) +#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064)) +#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068)) + +void uart_init(); +void uart_send(unsigned int c); +char uart_getc(); +void uart_puts(char *s); +void uart_hex(unsigned int d); +void uart_read_handler(); +void uart_write_handler(); +void uart_enable_interrupt(); +void demo_async_uart(); \ No newline at end of file diff --git a/lab_4/shell/include/utils.h b/lab_4/shell/include/utils.h new file mode 100644 index 000000000..e8580e603 --- /dev/null +++ b/lab_4/shell/include/utils.h @@ -0,0 +1,8 @@ +void set(long addr, unsigned int value); +void reset(); +int strcmp(char* a, char* b); +void cancel_reset(); +void utils_align(void *size, unsigned int s); +unsigned long utils_atoi(const char *s, int char_size); +void* simple_malloc(unsigned long size); +int _pow(int base, int exp); \ No newline at end of file diff --git a/lab_4/shell/initramfs.cpio b/lab_4/shell/initramfs.cpio new file mode 100644 index 0000000000000000000000000000000000000000..0b64417ccc1b259e1e0880523f255f6a8c51908a GIT binary patch literal 12288 zcmeGiOKc-awP!M41KI$Kv=Xq?#3OJbr(1dS*_UPB5_zGxN}EB+&FXNh!7WUdw|s(86gk|iSS-ky|&x2lguPY9NbF$s@}g| zbyvT7U8&X7YAT&drLw8z^fJKI{d7KuFm+E~i@;QBd1Yl~J-5D^<@mvm-~)*PD$?S5 z5u++#Ews0GA8~7GUD(4;^h!tU-P4GAhP^b7hhKf)_UZ?oyYE?D)$Z&m%8&Fy{_2%0 z3SC!~-zcIt!%-PYU{{GlQ8LOJ@MM%5%5~0r6G(?4S;#4hfNzn!gx5m8PyV1>Q+^7z z{`j3Ym6yLfKCS`j&5%5%F~hBq{sF^`a#eXt+9NEE;hOUDnEC`~c>}3YJzodR>=^#H zIsU4`M)(sPe^SrA33zpap7;d(1CD=rJct({@QO^KtK2h*^2*L~-?Et__)rPSND z1;2t6SY80_j%&4G{yC?j`bXWsY5)v80o&9H?887&L8-8Kq2F(UG)C!0s71t`?iad0 zh&(#pJ3zPv|1?`P&!0&FqzzwaYxu(c(5)MiNS;Xnw0j-?Ngw%j8*pSh6o$sHrQFsq z656BozY4f<^8b{K-#tTqXnjb(!=K@^)`#r!3g=6&+^2Pc;H32^TyKVNu9IuSj9eRX zGN2jh`z?HU>EOI_6?zt;9sRef+UCPPLun+lp{#v!?EH2pQYoY@UE02h`e}J z{t~pXeO^DMdS$8OG?qH8#g5bKA1+#!*KDucSAADa3qNqt#h7oFww2%h;Q8C1{=)vr zpFa8GS6_U8=EpyK{I6BiL;uix#p~7A`ByYBWuHc18i8p9rV*G%U>bpG1f~&~MqnC& zX#_4k0)PL{v5QJ?$$cd4H8ZkLHI9Vr$D{|e5BrkrQ*GfJvQOaO$3j2!X{$)2{|Ti1 z?dvGVS{&`mhvl&rNBh|*ekP1t6n{;jct!Eo6^d&Ve?y`ALll1#_Qe$G0R^lopO3}g zR$h$YQF>g>5NkNN(;sJd96#=-uRtwv)Squl{HQ-0fS*;M(li_OU(^y$;(qm?W!Uy*$x`C%mK9h^9SfVM6)v4#V0#CO+H(V2-S73)M&E(DhtpDcuWk8l zMQt7Rp!6wV;3=x8b^_MwI!$17q4o(s>Om)f@m|J7HBh-MgwG8U|;~%iLkUXtl1ivL2Np5uU$p9VKE|RC`l_0HWxE`YKBv1G) zz+rufKJ(pBRqxu}J=j8vaU{~q@ z(I=9p=l642FC>1+9*&>ztr2-zcV0;OQU6JfAljzbkqr)|gES8~N2rqINbjT?cH(P7 zTUUVacQpQ!YS=$Nr~FV2ds&pC*U}sOTi2LxYT_H$+VTc3Vy~oEIfTz*5>BdN6Fmi0 z&L?UIW4^QyV+$^xgerPo;FIdtI1_nMh~CusK@^T3JBW!vjIzVEm_ z=J>2_dv@c9!PhcaSXxQ8=h-%M_gJ%SdHZ&f1unCCN9@4%e7A?Xqp3~cB7HfiC zWDeS($#?gHXO?FJe~VeZ?=~F^RI--a?04;6UWOZL_(m6q=jordqbu zVNMSe+Kfo-8MyEE0~Gaa_<-XyQBxB5nw@?NJ&_!&<8&Qihil*=@o@-H^iOhclc=TZ zww%4ABf$MM@q)^bpLqaOgXkI1IoLqQnOlItd`?+wDepA@Dp9eXj?GAx0q9av_4;?qjptQw<~6PFk+Sb*wR_m%-43biq4EGD_6`%Mo!PMIjsu)xg^^$YFp-ZjR8kRE7f+H znP*yQmwjNAa(qVg56cz3T4iR18O3tJ&~r&U_ap}-Al+c1m@_cCjicPqx`Rt?3s%tB5F{DuxL;>%wc zgaKv?no&%$oL1B}(aj1o!Sf1d6F#E+&X&%xU{!;^Y|SuB7^19Ms#Tzygb`P2q4bVX z)ssxC7*z~TzG4=63^BkUgdr@UXh|1}F!Bg|PT!Y}7} zDHf{=mDSisF$R~)9b$`71cW_cAF&T~y_{G`aD>`$-C%y6 z$u1Mfg?aX|(C)dI5^*tLkv$33kS(;ynTKo+3-h*$zXL)1`isiBF&Yj;V6&7+uSmxc zJ@kPYha^UX1aJyf;16gG)hr~kX0d3N1{k3MGP{Ai7$RnS0{3xj@QE8RiGj%Cumkh& zy?5_jU>*9*&ACwzFyaSs&JsCuvAT}$m9?}c-beB!GX$b%E|zs7(fel7`zTM0!{1aP zH->BU%*B=P%tiPL<_$LVBF=D32J%46WM2K7nm9Ybl|+7Uzc%ig3A3F6Rk$`d{6BBL_d?219YS_b%-p1W?{88dNrDoNj(;fMOW)(q z$(i}y`ieM%u(B!+Ih>vE@#hwwv99&R#;ghUNwN5Ovpr=N?3_-m$j@e5^l@rxyQ@yp2V;_PCn zUHp{H4yHF2+stMmi@LT)^<)0&H!8}Db!yW{C@<1y|J=VH}L zwhAnF6VISh)wH}8TTq+xC@auNf1p+$s_uL&n=fdPfj(r5JGdcPG*fJG5BH?F8{vDs z#h&X2&}uT#f`dPz1qT56&N8-Pnze$dK}ufVfK>J&dt!S%yR)V`-TfG7eZX)(I5;F) zjoqFw_6vBy7Mmkh*dpJD4(z&P?Lt^5jV!9rWs5b~@$yQ*3Egn;b*y%p6o@QqI6ccd ziYf)UC<0>!@4%t=-Ex}egJ-?()^ob3Z$LFd=7|I+<&)uI-!|;DT{VCsntT%r#RZGm zhgSEX13O}P52~@yA1$4}&+8{=`IAkrO1rC+;GX5r`24ntDS_(4CLK#Cb9~n_7gP5; zZUZ*UA{mSc06TTKy6#hUm`bu#EG-aLtHlwBOmi0hX%ooE-0U83+B>}0=mad?Ah`y% zktsSK>-;d}S!X5(XSmNh9}~`0!ySPU7@wbq^MYr~tI9o$$95R-dCv>3; +__loader_size = (_end - _head)>>3; \ No newline at end of file diff --git a/lab_4/shell/main.c b/lab_4/shell/main.c new file mode 100644 index 000000000..4023da781 --- /dev/null +++ b/lab_4/shell/main.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#define MAX_BUFFER 50 +#include "include/uart.h" +#include "include/utils.h" +#include "include/mbox.h" +#include "include/cpio.h" +#include "include/allocator.h" + +extern void set_exception_vector_table(); +extern void core_timer_enable(); + + + +void main(int argc, char* argv[]){ + uart_init(); + set_exception_vector_table(); + + // show el + unsigned long el; + asm volatile ("mrs %0, CurrentEL" : "=r" (el)); + el = el >> 2; // CurrentEL的值在高两位 + + // print current exception level + uart_puts("Booted! Current EL: "); + uart_send('0' + el); + uart_puts("\n"); + + init_buddy_system(); + char* my_array = malloc_page(3); + char* my_array2 = malloc_page(3); + char* my_array3 = malloc_page(3); + char* my_array4 = malloc_page(3); + char* my_array5 = malloc_page(3); + char* my_array6 = malloc_page(3); + while(1){ + char command[MAX_BUFFER]; + char c = '\0'; + int length=0; + for(int i=0; i\t: print the content of file in initfs\n"); + uart_puts("hello\t: print hello world!\n"); + uart_puts("exec: execute user program in initfs"); + uart_puts("async_uart: switch to async uart mode (currently for demo only)"); + uart_puts("reboot\t: reboot the device\n"); + } + else if(strcmp(command, "hello") == 0){ + uart_puts("Hello World!\n"); + } + else if(strcmp(command, "ls") == 0){ + cpio_ls(); + } + else if(strcmp(command, "async_uart") == 0){ + demo_async_uart(); + } + else if(strcmp(command, "reboot") == 0){ + reset(); + } + else if(strcmp(command, "exec") == 0){ + uart_puts("executing...\n"); + // execute a dedicated user program + cpio_exec("user_program.img"); + } + // command with arguments + else{ + char arguments[3][MAX_BUFFER]; + // initialize + for(int i=0;i<3;i++){ + for(int j=0;j 0, stop +1: wfe + b 1b + + +2: // cpu id == 0 + + // el2 to el1 + bl from_el2_to_el1 + + // 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 + +from_el2_to_el1: + mov x0, (1 << 31) // EL1 uses aarch64 + // move system register to register (write x0 into hcr_el2) + msr hcr_el2, x0 + mov x0, 0x3c5 // 3c5 EL1h (SPSel = 1) with interrupt disabled, 345 enable interrupt + msr spsr_el2, x0 + msr elr_el2, lr + eret // return to EL1 diff --git a/lab_4/shell/uart.c b/lab_4/shell/uart.c new file mode 100644 index 000000000..dee6592ce --- /dev/null +++ b/lab_4/shell/uart.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "include/gpio.h" +#include "include/uart.h" +/** Auxilary mini UART registers + * Address & Description refer: https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf Page.8 + */ + + +/* + The definition below is for async uart IO +*/ + +#define BUFFER_SIZE 1024 +#define IRQS1 ((volatile unsigned int *)(0x3f00b210)) +char uart_read_buffer[BUFFER_SIZE]; +unsigned int read_idx = 0; + +char uart_write_buffer[BUFFER_SIZE]; +unsigned int write_idx = 0; +unsigned int write_cur = 0; +int async; + + +/** + * Set baud rate and characteristics (115200 8N1) and map to GPIO + */ +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *AUX_ENABLE |=1; // enable UART1, AUX mini uart + *AUX_MU_CNTL = 0; + *AUX_MU_LCR = 3; // 8 bits + *AUX_MU_MCR = 0; + *AUX_MU_IER = 0; + *AUX_MU_IIR = 0xc6; // disable interrupts + *AUX_MU_BAUD = 270; // 115200 baud + /* map UART1 to GPIO pins */ + r=*GPFSEL1; + r&=~((7<<12)|(7<<15)); // gpio14, gpio15 + r|=(2<<12)|(2<<15); // alt5 + *GPFSEL1 = r; + *GPPUD = 0; // enable pins 14 and 15 + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; // flush GPIO setup + *AUX_MU_CNTL = 3; // enable Tx, Rx +} + +/** + * Send a character + */ +void uart_send(unsigned int c) { + /* This bit is set if the transmit FIFO can accept at least one byte*/ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20)); + /* write the character to the buffer */ + *AUX_MU_IO=c; +} + +/** + * Receive a character + */ +char uart_getc() { + char r; + /* wait until something is in the buffer */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01)); + /* read it and return */ + r=(char)(*AUX_MU_IO); + /* convert carriage return to newline */ + return r=='\r'?'\n':r; +} + +/** + * Display a string + */ +void uart_puts(char *s) { + while(*s) { + /* convert newline to carriage return + newline */ + if(*s=='\n') + uart_send('\r'); + uart_send(*s++); + } +} + +/** + * Display a binary value in hexadecimal + */ +void uart_hex(unsigned int d) { + unsigned int n; + int c; + for(c=28;c>=0;c-=4) { + // get highest tetrad + n=(d>>c)&0xF; + // 0-9 => '0'-'9', 10-15 => 'A'-'F' + n+=n>9?0x37:0x30; + uart_send(n); + } +} + +void uart_enable_interrupt(){ + *AUX_MU_IER |= 0x02; + *IRQS1 |= 1 << 29; +} + +void uart_load_buffer(){ + while(write_cur < write_idx){ + uart_send(uart_write_buffer[write_cur]); + } +} + +void demo_async_uart(){ + uart_puts("turning to async mode...\n"); + uart_enable_interrupt(); + while(1){ + asm volatile("nop"); + } +} + +void uart_read_handler() { + char ch = (char)(*AUX_MU_IO); + uart_read_buffer[write_idx] = ch; + write_idx++; + uart_write_buffer[write_idx] = ch; + read_idx++; + write_idx++; + if(ch == '\r'){ + uart_puts(uart_write_buffer); + } +} + +void uart_write_handler(){ + if(write_cur < write_idx){ + *AUX_MU_IO=uart_read_buffer[write_cur]; + write_cur++; + } +} \ No newline at end of file diff --git a/lab_4/shell/utils.c b/lab_4/shell/utils.c new file mode 100644 index 000000000..e68c62644 --- /dev/null +++ b/lab_4/shell/utils.c @@ -0,0 +1,111 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC 0x3F10001c +#define PM_WDOG 0x3F100024 +#define SIMPLE_MALLOC_BUFFER_SIZE 8192 + +unsigned long utils_atoi(const char *s, int char_size) { + unsigned long num = 0; + for (int i = 0; i < char_size; i++) { + num = num * 16; + if (*s >= '0' && *s <= '9') { + num += (*s - '0'); + } else if (*s >= 'A' && *s <= 'F') { + num += (*s - 'A' + 10); + } else if (*s >= 'a' && *s <= 'f') { + num += (*s - 'a' + 10); + } + s++; + } + return num; +} + +int _pow(int base, int exp){ + int temp = base; + for(int i=0;i *b){ + return 1; + } + else{ + a++; + b++; + } + } + if(*a == '\0'){ + value++; + } + if(*b == '\0'){ + value--; + } + return value; +} + +/** + * set up given value to given address + */ +void set(long addr, unsigned int value) { + volatile unsigned int* point = (unsigned int*)addr; + *point = value; +} + + +void utils_align(void *size, unsigned int s) { + unsigned long* x = (unsigned long*) size; + unsigned long mask = s-1; + *x = ((*x) + mask) & (~mask); +} + +/** + * reboot respberry pi + * if tick=0, reboot instantly; + * otherwise, wait for tick seconds to reboot + */ +void reset(int tick) { // reboot after watchdog timer expire + set(PM_RSTC, PM_PASSWORD | 0x20); // full reset + if(tick != 0){ + set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick + } +} + +/** + * clear reboot register + */ +void cancel_reset() { + set(PM_RSTC, PM_PASSWORD | 0); // full reset + set(PM_WDOG, PM_PASSWORD | 0); // number of watchdog tick +} + + +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; +} \ No newline at end of file From 15d868150fee9818862a9e1ba7c33a8cb3a41a84 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Thu, 20 Jun 2024 17:45:41 +0800 Subject: [PATCH 13/23] lab4 basic done, but exist minor bug (memory allocation offset wrong) --- lab_4/shell/allocator.c | 118 ++++++++++++++++++++++++++++++-- lab_4/shell/include/allocator.h | 9 ++- lab_4/shell/main.c | 22 +++++- 3 files changed, 138 insertions(+), 11 deletions(-) diff --git a/lab_4/shell/allocator.c b/lab_4/shell/allocator.c index df8b3a21c..09ff49901 100644 --- a/lab_4/shell/allocator.c +++ b/lab_4/shell/allocator.c @@ -2,7 +2,7 @@ #include "include/utils.h" #include "include/uart.h" -int the_array[AVAILABLE_PAGE_NUM]; +struct TheArray the_array[AVAILABLE_PAGE_NUM]; OrderList order_list[MAX_ORDER]; @@ -20,6 +20,12 @@ void init_order_list(){ int current_order = MAX_ORDER-1; int current_page_index = 0; + // initialize The Array + for(int i=0;iroot != NULL; } +Node* get_buddy(OrderList* target, int target_page_index){ + Node* cur = target->root; + Node* prev = target->root; + while(cur != NULL){ + uart_puts("AAAA"); + if(cur->page_index == target_page_index){ + prev->next = cur->next; + cur->next = NULL; + return cur; + } + prev = cur; + cur = cur->next; + } + uart_puts("[Assertion Error] buddy not found\n"); + return NULL; +} + +void free_page(void* to_free){ + int page_index = ((unsigned int)to_free-HEAP_START_ADDRESS)/PAGE_SIZE; + int free_block_size = the_array[page_index].block_size; + int do_merge = 0; + if(the_array[page_index].available != OCCUPIED){ + uart_puts("[Assertion Error] releasing free page head\n"); + } + the_array[page_index].available = FREE; + int next_block_index = page_index+free_block_size; + uart_puts("[Free] block that contains "); + uart_hex(free_block_size); + uart_puts(" pages started from address 0x"); + uart_hex((unsigned int)to_free); + uart_puts(" to address 0x"); + uart_hex((unsigned int)to_free+(free_block_size*PAGE_SIZE)); + uart_puts(" with index starts from "); + uart_hex(page_index); + uart_puts("\n"); + + if(the_array[next_block_index].available == FREE){ + uart_puts("Accessing location: 0x"); + uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*next_block_index)); + uart_puts("\n"); + // same size, can merge + uart_hex(free_block_size); + uart_puts(" v.s "); + uart_hex(the_array[next_block_index].block_size); + uart_puts("\n"); + if(the_array[next_block_index].block_size == free_block_size && free_block_size!=FREE){ + int order =0, block_size = free_block_size; + // get sqrt(2) of block_size to obtain order + while(block_size > 2){ + order++; + block_size/=2; + } + uart_hex(order); + Node* buddy = get_buddy(&order_list[order], next_block_index); + if(buddy != NULL){ + Node* new_node = simple_malloc(sizeof(Node)); + // push into order list + new_node->address = (unsigned char*) to_free; + new_node->page_index = page_index; + the_array[page_index].block_size = _pow(2, order+1); + the_array[next_block_index].available = FREE; + the_array[next_block_index].block_size = FREE; + list_push_back(new_node, order+1); + uart_puts("[Merge] block that contains "); + uart_hex(free_block_size); + uart_puts(" pages started from address 0x"); + uart_hex((unsigned int)to_free); + uart_puts(" to address 0x"); + uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*(next_block_index+free_block_size-1))); + do_merge = 1; + } + } + } + if(!do_merge){ + Node* new_node = simple_malloc(sizeof(Node)); + new_node->address = (unsigned char*) to_free; + new_node->page_index = page_index; + int order =0, block_size = free_block_size; + // get sqrt(2) of block_size to obtain order + while(block_size > 2){ + order++; + block_size/=2; + } + list_push_back(new_node, order); + } + +} + unsigned char* malloc_page(int request_page_num){ //determine the minimum list order that this request needs int current_order = 0; @@ -96,7 +190,8 @@ unsigned char* malloc_page(int request_page_num){ if(check_list_has_element(&order_list[current_order])){ struct Node* allocated_address = list_pop(&order_list[current_order]); // mark the block as OCCUPIED - // the_array[(unsigned int)allocated_address->page_index] = OCCUPIED; + the_array[(unsigned int)allocated_address->page_index].available = OCCUPIED; + the_array[(unsigned int)allocated_address->page_index].block_size = _pow(2, current_order); //uart_hex((unsigned int)allocated_address->address-HEAP_START_ADDRESS); // print the log uart_puts("[Malloc] block that contains "); @@ -104,30 +199,39 @@ unsigned char* malloc_page(int request_page_num){ uart_puts(" pages started from address 0x"); uart_hex((unsigned int)allocated_address->address); uart_puts(" to address 0x"); - uart_hex((unsigned int)((allocated_address->address)+_pow(2, current_order)*PAGE_SIZE)); + uart_hex((unsigned int)((allocated_address->address)+(_pow(2, current_order)-1)*PAGE_SIZE)); uart_puts(" with index starts from "); uart_hex((unsigned int)allocated_address->page_index); uart_puts("\n"); int cutter_count = 1; while(cut_freg > 0){ - int mid_page_index = allocated_address->page_index+(_pow(2, current_order-cutter_count)); + // mid address is the starting address of last page that BEEN malloced + int mid_page_index = allocated_address->page_index+(_pow(2, current_order-cutter_count))-1; + // end address is the starting address of last page in this block unsigned char* end_address = mid_page_index+_pow(2, current_order-cutter_count); - the_array[mid_page_index+1] = _pow(2, current_order-cutter_count); Node* new_node = simple_malloc(sizeof(Node)); // push into order list new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*(mid_page_index+1)); new_node->page_index = mid_page_index+1; + the_array[new_node->page_index].block_size = _pow(2, current_order-cutter_count); + uart_hex(the_array[new_node->page_index].block_size ); + uart_puts(" pages freed.\n"); uart_puts("[Release redundant memory] block that contains "); uart_hex(_pow(2, current_order-cutter_count)); uart_puts(" pages started from address 0x"); uart_hex(new_node->address); uart_puts(" to address 0x"); - uart_hex(end_address); + uart_hex(new_node->address+((the_array[new_node->page_index].block_size-1)*PAGE_SIZE)); uart_puts(" is freed \n"); list_push_back(new_node, current_order-cutter_count); cut_freg--; cutter_count++; } + if(cutter_count>1){ + the_array[(unsigned int)allocated_address->page_index].block_size = _pow(2, current_order-(cutter_count-1)); + uart_hex(the_array[(unsigned int)allocated_address->page_index].block_size); + uart_puts(" pages allocated.\n"); + } return allocated_address->address; } diff --git a/lab_4/shell/include/allocator.h b/lab_4/shell/include/allocator.h index 1fcd626f3..76e4fe1e1 100644 --- a/lab_4/shell/include/allocator.h +++ b/lab_4/shell/include/allocator.h @@ -7,6 +7,11 @@ #define OCCUPIED -2 #define NULL 0 +typedef struct TheArray{ + int available; + int block_size; +}TheArray; + typedef struct Node{ unsigned char* address; int page_index; // the index of node in The Array @@ -24,4 +29,6 @@ struct Node* list_pop(OrderList* target); void init_order_list(); unsigned char* malloc_page(int request_page_num); int check_list_has_element(OrderList* target); -void list_push_back(Node* to_push, int order); \ No newline at end of file +void list_push_back(Node* to_push, int order); +void free_page(void* to_free); +Node* get_buddy(OrderList* target, int target_page_index); \ No newline at end of file diff --git a/lab_4/shell/main.c b/lab_4/shell/main.c index 4023da781..30cf47d29 100644 --- a/lab_4/shell/main.c +++ b/lab_4/shell/main.c @@ -54,7 +54,7 @@ void main(int argc, char* argv[]){ char* my_array3 = malloc_page(3); char* my_array4 = malloc_page(3); char* my_array5 = malloc_page(3); - char* my_array6 = malloc_page(3); + //char* my_array6 = malloc_page(3); while(1){ char command[MAX_BUFFER]; char c = '\0'; @@ -74,13 +74,29 @@ void main(int argc, char* argv[]){ uart_puts("ls\t: list all files in initfs\n"); uart_puts("cat \t: print the content of file in initfs\n"); uart_puts("hello\t: print hello world!\n"); - uart_puts("exec: execute user program in initfs"); - uart_puts("async_uart: switch to async uart mode (currently for demo only)"); + uart_puts("exec: execute user program in initfs\n"); + uart_puts("async_uart: switch to async uart mode (currently for demo only)\n"); + uart_puts("malloc \t: malloc memory of size \n"); + uart_puts("free\t: free all malloced page memory (for demo, the memory alloced in simple malloc will not be freed)\n"); uart_puts("reboot\t: reboot the device\n"); } else if(strcmp(command, "hello") == 0){ uart_puts("Hello World!\n"); } + else if(strcmp(command, "free") == 0){ + free_page(my_array); + free_page(my_array2); + free_page(my_array3); + free_page(my_array4); + free_page(my_array5); + //free_page(my_array6); + my_array = malloc_page(3); + my_array2 = malloc_page(3); + my_array3 = malloc_page(3); + my_array4 = malloc_page(3); + my_array5 = malloc_page(3); + + } else if(strcmp(command, "ls") == 0){ cpio_ls(); } From 77bdfd9cf0e2ad3946462767aefa06c773a8fb0c Mon Sep 17 00:00:00 2001 From: laxiflora Date: Thu, 20 Jun 2024 22:02:16 +0800 Subject: [PATCH 14/23] lab 4-1 done --- lab_4/shell/allocator.c | 55 +++++++++++++++++++---------------------- lab_4/shell/main.c | 1 + 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/lab_4/shell/allocator.c b/lab_4/shell/allocator.c index 09ff49901..c6c6ffd8c 100644 --- a/lab_4/shell/allocator.c +++ b/lab_4/shell/allocator.c @@ -9,9 +9,6 @@ OrderList order_list[MAX_ORDER]; /*Pop the top element in linked list, note I assume there EXIST AT LEAST ONE AVAILABLE NODE*/ struct Node* list_pop(OrderList* target){ Node* to_ret = target->root; - while(to_ret -> next != NULL){ - to_ret = to_ret->next; - } target->root = target->root->next; return to_ret; } @@ -90,11 +87,16 @@ int check_list_has_element(OrderList* target){ Node* get_buddy(OrderList* target, int target_page_index){ Node* cur = target->root; - Node* prev = target->root; + Node* prev = NULL; while(cur != NULL){ - uart_puts("AAAA"); if(cur->page_index == target_page_index){ - prev->next = cur->next; + if(prev != NULL){ + prev->next = cur->next; + } + // root is the buddy + else{ + target->root = target->root->next; + } cur->next = NULL; return cur; } @@ -113,9 +115,10 @@ void free_page(void* to_free){ uart_puts("[Assertion Error] releasing free page head\n"); } the_array[page_index].available = FREE; - int next_block_index = page_index+free_block_size; + int next_block_index = page_index+free_block_size+1; uart_puts("[Free] block that contains "); - uart_hex(free_block_size); + // block size starts from zero, thus need to +1 + uart_hex(free_block_size+1); uart_puts(" pages started from address 0x"); uart_hex((unsigned int)to_free); uart_puts(" to address 0x"); @@ -125,14 +128,12 @@ void free_page(void* to_free){ uart_puts("\n"); if(the_array[next_block_index].available == FREE){ - uart_puts("Accessing location: 0x"); - uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*next_block_index)); - uart_puts("\n"); + // debug: print the address of next page of freed block + // uart_puts("Accessing location: 0x"); + // uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*next_block_index)); + // uart_puts("\n"); + // same size, can merge - uart_hex(free_block_size); - uart_puts(" v.s "); - uart_hex(the_array[next_block_index].block_size); - uart_puts("\n"); if(the_array[next_block_index].block_size == free_block_size && free_block_size!=FREE){ int order =0, block_size = free_block_size; // get sqrt(2) of block_size to obtain order @@ -140,7 +141,6 @@ void free_page(void* to_free){ order++; block_size/=2; } - uart_hex(order); Node* buddy = get_buddy(&order_list[order], next_block_index); if(buddy != NULL){ Node* new_node = simple_malloc(sizeof(Node)); @@ -156,7 +156,8 @@ void free_page(void* to_free){ uart_puts(" pages started from address 0x"); uart_hex((unsigned int)to_free); uart_puts(" to address 0x"); - uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*(next_block_index+free_block_size-1))); + uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*(next_block_index+free_block_size))); + uart_puts("\n"); do_merge = 1; } } @@ -181,7 +182,7 @@ unsigned char* malloc_page(int request_page_num){ int current_order = 0; int cut_freg = 0; // start from allocating the smallest block until is can satisfy needs - + //print_order_list(&order_list[2]); while(current_order _pow(2, current_order)){ current_order++; @@ -191,8 +192,8 @@ unsigned char* malloc_page(int request_page_num){ struct Node* allocated_address = list_pop(&order_list[current_order]); // mark the block as OCCUPIED the_array[(unsigned int)allocated_address->page_index].available = OCCUPIED; - the_array[(unsigned int)allocated_address->page_index].block_size = _pow(2, current_order); - //uart_hex((unsigned int)allocated_address->address-HEAP_START_ADDRESS); + // the block_size start from zero, thus we need to -1 + the_array[(unsigned int)allocated_address->page_index].block_size = _pow(2, current_order)-1; // print the log uart_puts("[Malloc] block that contains "); uart_hex(_pow(2, current_order)); @@ -213,24 +214,20 @@ unsigned char* malloc_page(int request_page_num){ // push into order list new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*(mid_page_index+1)); new_node->page_index = mid_page_index+1; - the_array[new_node->page_index].block_size = _pow(2, current_order-cutter_count); - uart_hex(the_array[new_node->page_index].block_size ); - uart_puts(" pages freed.\n"); + the_array[new_node->page_index].block_size = _pow(2, current_order-cutter_count)-1; uart_puts("[Release redundant memory] block that contains "); uart_hex(_pow(2, current_order-cutter_count)); uart_puts(" pages started from address 0x"); uart_hex(new_node->address); uart_puts(" to address 0x"); - uart_hex(new_node->address+((the_array[new_node->page_index].block_size-1)*PAGE_SIZE)); + uart_hex(new_node->address+((the_array[new_node->page_index].block_size)*PAGE_SIZE)); uart_puts(" is freed \n"); list_push_back(new_node, current_order-cutter_count); cut_freg--; cutter_count++; } if(cutter_count>1){ - the_array[(unsigned int)allocated_address->page_index].block_size = _pow(2, current_order-(cutter_count-1)); - uart_hex(the_array[(unsigned int)allocated_address->page_index].block_size); - uart_puts(" pages allocated.\n"); + the_array[(unsigned int)allocated_address->page_index].block_size = _pow(2, current_order-(cutter_count-1))-1; } return allocated_address->address; @@ -249,8 +246,8 @@ unsigned char* malloc_page(int request_page_num){ void list_push_back(Node* to_push, int order){ OrderList* target_list = &(order_list[order]); - if(target_list->root == NULL){ - target_list->root = to_push; + if(order_list[order].root == NULL){ + order_list[order].root = to_push; } else{ Node* current = target_list->root; diff --git a/lab_4/shell/main.c b/lab_4/shell/main.c index 30cf47d29..c364e8770 100644 --- a/lab_4/shell/main.c +++ b/lab_4/shell/main.c @@ -90,6 +90,7 @@ void main(int argc, char* argv[]){ free_page(my_array4); free_page(my_array5); //free_page(my_array6); + my_array = malloc_page(3); my_array2 = malloc_page(3); my_array3 = malloc_page(3); From d4bf151930b2b12f2236d36168be39cd040d7c6e Mon Sep 17 00:00:00 2001 From: laxiflora Date: Sun, 23 Jun 2024 23:08:51 +0800 Subject: [PATCH 15/23] add dynamic allocator (free needed to be implemented) --- lab_4/shell/dynamic_allocator.c | 102 ++++++++++++++++++ lab_4/shell/include/dynamic_allocator.h | 23 ++++ lab_4/shell/include/page_allocator.h | 36 +++++++ lab_4/shell/include/utils.h | 3 +- lab_4/shell/main.c | 42 +++++--- lab_4/shell/{allocator.c => page_allocator.c} | 35 +++--- lab_4/shell/utils.c | 13 ++- 7 files changed, 214 insertions(+), 40 deletions(-) create mode 100644 lab_4/shell/dynamic_allocator.c create mode 100644 lab_4/shell/include/dynamic_allocator.h create mode 100644 lab_4/shell/include/page_allocator.h rename lab_4/shell/{allocator.c => page_allocator.c} (97%) diff --git a/lab_4/shell/dynamic_allocator.c b/lab_4/shell/dynamic_allocator.c new file mode 100644 index 000000000..fc9193e3d --- /dev/null +++ b/lab_4/shell/dynamic_allocator.c @@ -0,0 +1,102 @@ +#include "include/dynamic_allocator.h" +#include "include/page_allocator.h" + +// #define POOL {4, 8, 16, 32, 64, 128, 256, 512, 1024} +// #define PARTITION {4, 2, 2, 2, 2, 2, 2, 2, 2} +// #define POOL_SIZE 8 +// // max pages allowed to be partitioned +// #define MAX_PAGE 64 + +// typedef struct Page{ +// void* prefix; +// // the occupied section of each partition size in page +// int usage[POOL_SIZE]; +// } + +// typedef struct DynamicAllocator{ +// int chunk_option[POOL_SIZE]; +// int partition[POOL_SIZE]; +// int allocated_page_num; +// Page allocated_page_info[MAX_PAGE]; + +// }DynamicAllocator; + + +struct DynamicAllocator dynamic_allocator; + + +void init_dynamic_allocator(){ + int pool[] = POOL; + int part[] = PARTITION; + dynamic_allocator.allocated_page_num = 0; + for(int i=0;i0){ + void* address = dynamic_allocator.allocated_page_info[i].prefix; + unsigned int used_offset = 0x00; + for(int j=0;j= 0){ while((current_page_index+_pow(2, current_order)-1) < AVAILABLE_PAGE_NUM){ @@ -55,12 +42,6 @@ void init_order_list(){ } current_order--; } - // for(int i=0;iroot != NULL; } @@ -184,6 +177,8 @@ unsigned char* malloc_page(int request_page_num){ // start from allocating the smallest block until is can satisfy needs //print_order_list(&order_list[2]); while(current_order _pow(2, current_order)){ current_order++; } diff --git a/lab_4/shell/utils.c b/lab_4/shell/utils.c index e68c62644..bb2cb26c9 100644 --- a/lab_4/shell/utils.c +++ b/lab_4/shell/utils.c @@ -20,11 +20,12 @@ unsigned long utils_atoi(const char *s, int char_size) { } int _pow(int base, int exp){ - int temp = base; + + int ret = 1; for(int i=0;i Date: Mon, 24 Jun 2024 01:02:04 +0800 Subject: [PATCH 16/23] lab 4 basic --- lab_4/shell/dynamic_allocator.c | 97 ++++++++++++++++++------- lab_4/shell/include/dynamic_allocator.h | 8 +- lab_4/shell/main.c | 27 +++++-- lab_4/shell/page_allocator.c | 6 +- 4 files changed, 97 insertions(+), 41 deletions(-) diff --git a/lab_4/shell/dynamic_allocator.c b/lab_4/shell/dynamic_allocator.c index fc9193e3d..45bba0b18 100644 --- a/lab_4/shell/dynamic_allocator.c +++ b/lab_4/shell/dynamic_allocator.c @@ -29,16 +29,56 @@ void init_dynamic_allocator(){ int pool[] = POOL; int part[] = PARTITION; dynamic_allocator.allocated_page_num = 0; - for(int i=0;i0){ - void* address = dynamic_allocator.allocated_page_info[i].prefix; - unsigned int used_offset = 0x00; - for(int j=0;j Date: Mon, 24 Jun 2024 03:03:54 +0800 Subject: [PATCH 17/23] lab4 basic but bugged on resp pi --- lab_4/bootloader/kernel_uploader.py | 4 ++-- lab_4/shell/dynamic_allocator.c | 6 +++--- lab_4/shell/main.c | 28 +++++++++++----------------- lab_4/shell/page_allocator.c | 23 ++++++++++++----------- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/lab_4/bootloader/kernel_uploader.py b/lab_4/bootloader/kernel_uploader.py index 80ec98938..ab8def68f 100644 --- a/lab_4/bootloader/kernel_uploader.py +++ b/lab_4/bootloader/kernel_uploader.py @@ -36,7 +36,7 @@ def read_line(s): received_string += c return received_string -size = os.stat("../shell/shell_kernel.img").st_size +size = os.stat("/home/laxiflora/Desktop/osc2024/lab_4/shell/shell_kernel.img").st_size print(size) # size = os.stat("./kernel8.img").st_size @@ -51,7 +51,7 @@ def read_line(s): received_content = read_line(s) print(received_content) -with open("../shell/shell_kernel.img", "rb") as f: +with open("/home/laxiflora/Desktop/osc2024/lab_4/shell/shell_kernel.img", "rb") as f: sent_size = 0 # Initialize size counter byte = f.read(1) # Read the first byte diff --git a/lab_4/shell/dynamic_allocator.c b/lab_4/shell/dynamic_allocator.c index 45bba0b18..78eb626f7 100644 --- a/lab_4/shell/dynamic_allocator.c +++ b/lab_4/shell/dynamic_allocator.c @@ -42,9 +42,9 @@ void init_dynamic_allocator(){ int free(void* to_free){ int pool[] = POOL; int part[] = PARTITION; - // uart_puts("address 0x"); - // uart_hex(to_free); - // uart_puts("\n"); + uart_puts("address 0x"); + uart_hex(to_free); + uart_puts("\n"); unsigned int* prefix_address = ((unsigned int)to_free & (unsigned int)0xFFFFF000); unsigned int* offset = ((unsigned int)to_free & (unsigned int)0x00000FFF); for(int i=0;iroot; + uart_puts("address : \n"); while(cur != NULL){ - uart_puts("address "); uart_hex(cur->address); uart_puts("\n"); - uart_hex(cur->page_index); - uart_puts("\n"); cur = cur->next; } @@ -97,6 +95,7 @@ Node* get_buddy(OrderList* target, int target_page_index){ cur = cur->next; } uart_puts("[Assertion Error] buddy not found\n"); + print_order_list(target); return NULL; } @@ -122,18 +121,19 @@ void free_page(void* to_free){ if(the_array[next_block_index].available == FREE){ // debug: print the address of next page of freed block - uart_puts("Accessing location: 0x"); - uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*next_block_index)); - uart_puts("\n"); + // uart_puts("Accessing location: 0x"); + // uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*next_block_index)); + // uart_puts("\n"); // same size, can merge - if(the_array[next_block_index].block_size == free_block_size && free_block_size!=FREE){ + if(the_array[next_block_index].block_size == free_block_size && the_array[next_block_index].available==FREE){ int order =0, block_size = free_block_size; // get sqrt(2) of block_size to obtain order - while(block_size > 2){ + while(block_size > 0){ order++; block_size/=2; } + print_order_list(&order_list[order]); Node* buddy = get_buddy(&order_list[order], next_block_index); if(buddy != NULL){ Node* new_node = simple_malloc(sizeof(Node)); @@ -161,7 +161,7 @@ void free_page(void* to_free){ new_node->page_index = page_index; int order =0, block_size = free_block_size; // get sqrt(2) of block_size to obtain order - while(block_size > 2){ + while(block_size > 0){ order++; block_size/=2; } @@ -241,8 +241,8 @@ unsigned char* malloc_page(int request_page_num){ void list_push_back(Node* to_push, int order){ OrderList* target_list = &(order_list[order]); - if(order_list[order].root == NULL){ - order_list[order].root = to_push; + if(target_list->root == NULL){ + target_list->root = to_push; } else{ Node* current = target_list->root; @@ -251,4 +251,5 @@ void list_push_back(Node* to_push, int order){ } current->next = to_push; } + //print_order_list(target_list); } \ No newline at end of file From 749d02b08c883e2f70b3b3a5a2012a8aa80a87e5 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Mon, 24 Jun 2024 04:28:29 +0800 Subject: [PATCH 18/23] lab4 advanced --- lab_4/shell/cpio.c | 2 +- lab_4/shell/dynamic_allocator.c | 4 +++- lab_4/shell/include/page_allocator.h | 2 ++ lab_4/shell/main.c | 7 ++++-- lab_4/shell/page_allocator.c | 35 ++++++++++++++++++++++++++-- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/lab_4/shell/cpio.c b/lab_4/shell/cpio.c index 53f870e6a..99ee37706 100644 --- a/lab_4/shell/cpio.c +++ b/lab_4/shell/cpio.c @@ -3,7 +3,7 @@ #include "include/stdint.h" #include "include/utils.h" -char* cpio_addr = (char *)0x8000000;; +char* cpio_addr = (char *)0x8000000; void cpio_ls(){ char* addr = (char*) cpio_addr; diff --git a/lab_4/shell/dynamic_allocator.c b/lab_4/shell/dynamic_allocator.c index 78eb626f7..be3cc282d 100644 --- a/lab_4/shell/dynamic_allocator.c +++ b/lab_4/shell/dynamic_allocator.c @@ -39,6 +39,7 @@ void init_dynamic_allocator(){ } } + int free(void* to_free){ int pool[] = POOL; int part[] = PARTITION; @@ -144,4 +145,5 @@ void* malloc(unsigned long size){ uart_puts(" has been malloced.\n"); dynamic_allocator.allocated_page_num++; return address; -} \ No newline at end of file +} + diff --git a/lab_4/shell/include/page_allocator.h b/lab_4/shell/include/page_allocator.h index a05bc99c4..8cfc79b76 100644 --- a/lab_4/shell/include/page_allocator.h +++ b/lab_4/shell/include/page_allocator.h @@ -34,3 +34,5 @@ int check_list_has_element(OrderList* target); void list_push_back(Node* to_push, int order); void free_page(void* to_free); Node* get_buddy(OrderList* target, int target_page_index); +void memory_reserve(unsigned int start, unsigned int end); +void init_reserve_memory(); \ No newline at end of file diff --git a/lab_4/shell/main.c b/lab_4/shell/main.c index f81c353bc..d936be184 100644 --- a/lab_4/shell/main.c +++ b/lab_4/shell/main.c @@ -36,10 +36,11 @@ extern void core_timer_enable(); void main(int argc, char* argv[]){ + // init uart uart_init(); init_simple_malloc(); + // init exception table and interrupt (lab3) set_exception_vector_table(); - // show el unsigned long el; asm volatile ("mrs %0, CurrentEL" : "=r" (el)); @@ -49,9 +50,11 @@ void main(int argc, char* argv[]){ uart_puts("Booted! Current EL: "); uart_send('0' + el); uart_puts("\n"); - + // init memory (lab4) + init_reserve_memory(); init_buddy_system(); init_dynamic_allocator(); + // char* my_array = malloc_page(1); // char* my_variablwe = (char*)malloc(1023); // char* my_varieable = (char*)malloc(1023); diff --git a/lab_4/shell/page_allocator.c b/lab_4/shell/page_allocator.c index 4ad6444d1..dcebc58ac 100644 --- a/lab_4/shell/page_allocator.c +++ b/lab_4/shell/page_allocator.c @@ -4,7 +4,8 @@ struct TheArray the_array[AVAILABLE_PAGE_NUM]; OrderList order_list[MAX_ORDER]; - +extern void* _head; +extern void* _end; /*Pop the top element in linked list, note I assume there EXIST AT LEAST ONE AVAILABLE NODE*/ struct Node* list_pop(OrderList* target){ @@ -252,4 +253,34 @@ void list_push_back(Node* to_push, int order){ current->next = to_push; } //print_order_list(target_list); -} \ No newline at end of file +} + +void init_reserve_memory(){ + // Spin tables for multicore boot (0x0000 - 0x1000) + memory_reserve(0x0000, 0x1000); + // initramfs, allocate 4 pages + memory_reserve(0x8000000, 0x8000000 + 0x4000); + // kernel image + memory_reserve(&_head, (unsigned int)&_head+((unsigned int)&_end)); +} + + +void memory_reserve(unsigned int start, unsigned int end){ + start = start-(start % PAGE_SIZE); + end = end % PAGE_SIZE ? end + PAGE_SIZE - (end % PAGE_SIZE) : end; + + uart_puts("[Reserve] Memory Reserve: Start from adress 0x"); + uart_hex(start); + uart_puts(" to 0x"); + uart_hex(end); + uart_puts("\n"); + + int start_index = (start-HEAP_START_ADDRESS)/PAGE_SIZE; + // assume end_index do not exceed limit + int end_index = (end-HEAP_START_ADDRESS)/PAGE_SIZE; + + for(int i=start_index;i Date: Tue, 25 Jun 2024 01:03:36 +0800 Subject: [PATCH 19/23] lab4 advanced finish; lab5 init --- lab_4/shell/include/page_allocator.h | 4 +- lab_4/shell/main.c | 45 +-- lab_4/shell/page_allocator.c | 103 +++++-- lab_5/Makefile | 52 ++++ lab_5/Makefile.gcc | 52 ++++ lab_5/README.md | 6 + lab_5/bootloader/Makefile | 59 ++++ lab_5/bootloader/bcm2710-rpi-3-b-plus.dtb | Bin 0 -> 35026 bytes lab_5/bootloader/device_tree.c | 74 +++++ lab_5/bootloader/include/device_tree.h | 34 +++ lab_5/bootloader/include/gpio.h | 45 +++ lab_5/bootloader/include/mbox.h | 48 +++ lab_5/bootloader/include/stdint.h | 9 + lab_5/bootloader/include/uart.h | 30 ++ lab_5/bootloader/include/utils.h | 4 + lab_5/bootloader/initramfs.cpio | Bin 0 -> 1024 bytes lab_5/bootloader/kernel_uploader.py | 94 ++++++ lab_5/bootloader/link.ld | 55 ++++ lab_5/bootloader/main.c | 60 ++++ lab_5/bootloader/mbox.c | 64 ++++ lab_5/bootloader/reader.py | 9 + lab_5/bootloader/start.S | 43 +++ lab_5/bootloader/uart.c | 134 ++++++++ lab_5/bootloader/utils.c | 61 ++++ lab_5/config.txt | 2 + lab_5/rootfs/hello.txt | 1 + lab_5/rootfs/hello2.txt | 1 + lab_5/rootfs/link.ld | 44 +++ lab_5/rootfs/makefile | 36 +++ lab_5/rootfs/user_program | Bin 0 -> 5704 bytes lab_5/rootfs/user_program.S | 13 + lab_5/rootfs/user_program.elf | Bin 0 -> 928 bytes lab_5/rootfs/user_program.img | Bin 0 -> 24 bytes lab_5/shell/Makefile | 61 ++++ lab_5/shell/cpio.c | 102 +++++++ lab_5/shell/dynamic_allocator.c | 149 +++++++++ lab_5/shell/exception_vector.S | 102 +++++++ lab_5/shell/exceptions.c | 25 ++ lab_5/shell/include/cpio.h | 21 ++ lab_5/shell/include/dynamic_allocator.h | 21 ++ lab_5/shell/include/gpio.h | 45 +++ lab_5/shell/include/interrupt.h | 13 + lab_5/shell/include/mbox.h | 48 +++ .../shell/include/page_allocator.h | 6 +- lab_5/shell/include/stdint.h | 9 + lab_5/shell/include/thread.h | 32 ++ lab_5/shell/include/uart.h | 49 +++ lab_5/shell/include/utils.h | 9 + lab_5/shell/initramfs.cpio | Bin 0 -> 12288 bytes lab_5/shell/interrupt.c | 48 +++ lab_5/shell/interrupts.S | 72 +++++ lab_5/shell/link.ld | 44 +++ lab_5/shell/main.c | 172 +++++++++++ lab_5/shell/mbox.c | 64 ++++ lab_5/shell/page_allocator.c | 286 ++++++++++++++++++ lab_5/shell/start.S | 44 +++ lab_5/shell/thread.c | 29 ++ lab_5/shell/uart.c | 162 ++++++++++ lab_5/shell/utils.c | 118 ++++++++ 59 files changed, 2860 insertions(+), 53 deletions(-) create mode 100644 lab_5/Makefile create mode 100644 lab_5/Makefile.gcc create mode 100644 lab_5/README.md create mode 100644 lab_5/bootloader/Makefile create mode 100644 lab_5/bootloader/bcm2710-rpi-3-b-plus.dtb create mode 100644 lab_5/bootloader/device_tree.c create mode 100644 lab_5/bootloader/include/device_tree.h create mode 100644 lab_5/bootloader/include/gpio.h create mode 100644 lab_5/bootloader/include/mbox.h create mode 100644 lab_5/bootloader/include/stdint.h create mode 100644 lab_5/bootloader/include/uart.h create mode 100644 lab_5/bootloader/include/utils.h create mode 100644 lab_5/bootloader/initramfs.cpio create mode 100644 lab_5/bootloader/kernel_uploader.py create mode 100644 lab_5/bootloader/link.ld create mode 100644 lab_5/bootloader/main.c create mode 100644 lab_5/bootloader/mbox.c create mode 100644 lab_5/bootloader/reader.py create mode 100644 lab_5/bootloader/start.S create mode 100644 lab_5/bootloader/uart.c create mode 100644 lab_5/bootloader/utils.c create mode 100644 lab_5/config.txt create mode 100644 lab_5/rootfs/hello.txt create mode 100644 lab_5/rootfs/hello2.txt create mode 100644 lab_5/rootfs/link.ld create mode 100644 lab_5/rootfs/makefile create mode 100755 lab_5/rootfs/user_program create mode 100644 lab_5/rootfs/user_program.S create mode 100755 lab_5/rootfs/user_program.elf create mode 100755 lab_5/rootfs/user_program.img create mode 100644 lab_5/shell/Makefile create mode 100644 lab_5/shell/cpio.c create mode 100644 lab_5/shell/dynamic_allocator.c create mode 100644 lab_5/shell/exception_vector.S create mode 100644 lab_5/shell/exceptions.c create mode 100644 lab_5/shell/include/cpio.h create mode 100644 lab_5/shell/include/dynamic_allocator.h create mode 100644 lab_5/shell/include/gpio.h create mode 100644 lab_5/shell/include/interrupt.h create mode 100644 lab_5/shell/include/mbox.h rename lab_4/shell/include/allocator.h => lab_5/shell/include/page_allocator.h (85%) create mode 100644 lab_5/shell/include/stdint.h create mode 100644 lab_5/shell/include/thread.h create mode 100644 lab_5/shell/include/uart.h create mode 100644 lab_5/shell/include/utils.h create mode 100644 lab_5/shell/initramfs.cpio create mode 100644 lab_5/shell/interrupt.c create mode 100644 lab_5/shell/interrupts.S create mode 100644 lab_5/shell/link.ld create mode 100644 lab_5/shell/main.c create mode 100644 lab_5/shell/mbox.c create mode 100644 lab_5/shell/page_allocator.c create mode 100644 lab_5/shell/start.S create mode 100644 lab_5/shell/thread.c create mode 100644 lab_5/shell/uart.c create mode 100644 lab_5/shell/utils.c diff --git a/lab_4/shell/include/page_allocator.h b/lab_4/shell/include/page_allocator.h index 8cfc79b76..457d0668a 100644 --- a/lab_4/shell/include/page_allocator.h +++ b/lab_4/shell/include/page_allocator.h @@ -1,5 +1,5 @@ -#define HEAP_START_ADDRESS 0x10000000 -#define HEAP_END_ADDRESS 0x20000000 +#define HEAP_START_ADDRESS 0x00000000 +#define HEAP_END_ADDRESS 0x3B400000 #define PAGE_SIZE 0x1000 #define AVAILABLE_PAGE_NUM (HEAP_END_ADDRESS-HEAP_START_ADDRESS)/PAGE_SIZE #define MAX_ORDER 11 diff --git a/lab_4/shell/main.c b/lab_4/shell/main.c index d936be184..fa769248d 100644 --- a/lab_4/shell/main.c +++ b/lab_4/shell/main.c @@ -51,16 +51,18 @@ void main(int argc, char* argv[]){ uart_send('0' + el); uart_puts("\n"); // init memory (lab4) - init_reserve_memory(); init_buddy_system(); + uart_puts("Booted! Current EL: "); + uart_send('0' + el); + uart_puts("\n"); init_dynamic_allocator(); // char* my_array = malloc_page(1); // char* my_variablwe = (char*)malloc(1023); - // char* my_varieable = (char*)malloc(1023); - // char* wmy_variable = (char*)malloc(1023); - // char* my_vrariable = (char*)malloc(1023); - // char* my_variatble = (char*)malloc(1023); + // char* my_varieable = (char*)malloc(1023); + // char* wmy_variable = (char*)malloc(1023); + // char* my_vrariable = (char*)malloc(1023); + // char* my_variatble = (char*)malloc(1023); // free(my_variablwe); // my_variablwe = (char*)malloc(7642); // free(my_variablwe); @@ -70,12 +72,12 @@ void main(int argc, char* argv[]){ // free(my_variablwe); // free(my_variatble); - // char* my_array = malloc_page(3); - // char* my_array2 = malloc_page(3); - // char* my_array3 = malloc_page(3); - // char* my_array4 = malloc_page(3); - // char* my_array5 = malloc_page(3); - // char* my_array6 = malloc_page(3); + char* my_array = malloc_page(3); + char* my_array2 = malloc_page(3); + char* my_array3 = malloc_page(3); + char* my_array4 = malloc_page(3); + char* my_array5 = malloc_page(3); + char* my_array6 = malloc_page(3); while(1){ char command[MAX_BUFFER]; char c = '\0'; @@ -105,18 +107,17 @@ void main(int argc, char* argv[]){ uart_puts("Hello World!\n"); } else if(strcmp(command, "free") == 0){ - // free_page(my_array); - // free_page(my_array2); - // free_page(my_array3); - // free_page(my_array4); - // free_page(my_array5); - //free_page(my_array6); + free_page(my_array); + free_page(my_array2); + free_page(my_array3); + free_page(my_array4); + free_page(my_array5); - // my_array = malloc_page(3); - // my_array2 = malloc_page(3); - // my_array3 = malloc_page(3); - // my_array4 = malloc_page(3); - // my_array5 = malloc_page(3); + my_array = malloc_page(3); + my_array2 = malloc_page(3); + my_array3 = malloc_page(3); + my_array4 = malloc_page(3); + my_array5 = malloc_page(3); } else if(strcmp(command, "ls") == 0){ cpio_ls(); diff --git a/lab_4/shell/page_allocator.c b/lab_4/shell/page_allocator.c index dcebc58ac..0839fe372 100644 --- a/lab_4/shell/page_allocator.c +++ b/lab_4/shell/page_allocator.c @@ -16,34 +16,82 @@ struct Node* list_pop(OrderList* target){ void init_order_list(){ int current_order = MAX_ORDER-1; - int current_page_index = 0; - // assume all pages are available at beginnig, greedly allocate pages in max order size - while(current_order >= 0){ - while((current_page_index+_pow(2, current_order)-1) < AVAILABLE_PAGE_NUM){ - unsigned int allocated_size = _pow(2, current_order)*PAGE_SIZE; - // record the grouped block at The Array - the_array[current_page_index].block_size = _pow(2, current_order); - // malloc a struct node to record the meta data of this block - Node* new_node = simple_malloc(sizeof(Node)); - // push into order list - new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*current_page_index); - new_node->page_index = current_page_index; - list_push_back(new_node, current_order); + int current_page_start = 0; + // advanced: handle cases that some pages are reserved + while((HEAP_START_ADDRESS+(PAGE_SIZE*current_page_start)) < HEAP_END_ADDRESS){ + int continuous_block = 0; + while(continuous_block < _pow(2, MAX_ORDER) && current_page_start+continuous_blockaddress); - uart_puts(" with 0x"); - uart_hex((unsigned int)allocated_size/PAGE_SIZE); - uart_puts(" pages and start at index "); - uart_hex((unsigned int)new_node->page_index); - uart_puts(" in The Array"); - uart_puts("\n"); + unsigned int allocated_size = continuous_block*PAGE_SIZE; + // record the grouped block at The Array, start from 0 thus need to -1 + the_array[current_page_start].block_size = continuous_block-1; + // malloc a struct node to record the meta data of this block + Node* new_node = simple_malloc(sizeof(Node)); + // push into order list + new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*current_page_start); + new_node->page_index = current_page_start; + list_push_back(new_node, order); - current_page_index = current_page_index+_pow(2, current_order)+1; - } - current_order--; + uart_puts("[Init] grouping block at address 0x"); + uart_hex(new_node->address); + uart_puts(" with 0x"); + uart_hex((unsigned int)allocated_size/PAGE_SIZE); + uart_puts(" pages and start at index "); + uart_hex((unsigned int)new_node->page_index); + uart_puts(" in The Array"); + uart_puts("\n"); + current_page_start = current_page_start +continuous_block; + current_page_start++; } + // assume all pages are available at beginnig, greedly allocate pages in max order size + // while(current_order >= 0){ + // while((current_page_index+_pow(2, current_order)-1) < AVAILABLE_PAGE_NUM){ + // unsigned int allocated_size = _pow(2, current_order)*PAGE_SIZE; + // // record the grouped block at The Array + // the_array[current_page_index].block_size = _pow(2, current_order); + // // malloc a struct node to record the meta data of this block + // Node* new_node = simple_malloc(sizeof(Node)); + // // push into order list + // new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*current_page_index); + // new_node->page_index = current_page_index; + // list_push_back(new_node, current_order); + + // uart_puts("[Init] grouping block at address 0x"); + // uart_hex(new_node->address); + // uart_puts(" with 0x"); + // uart_hex((unsigned int)allocated_size/PAGE_SIZE); + // uart_puts(" pages and start at index "); + // uart_hex((unsigned int)new_node->page_index); + // uart_puts(" in The Array"); + // uart_puts("\n"); + + // current_page_index = current_page_index+_pow(2, current_order)+1; + // } + // current_order--; + // } + } void print_order_list(OrderList* list){ @@ -53,7 +101,6 @@ void print_order_list(OrderList* list){ uart_hex(cur->address); uart_puts("\n"); cur = cur->next; - } } @@ -69,6 +116,7 @@ void init_buddy_system(){ order_list[i].chain_length=0; order_list[i].root = NULL; } + init_reserve_memory(); init_order_list(); } @@ -257,7 +305,7 @@ void list_push_back(Node* to_push, int order){ void init_reserve_memory(){ // Spin tables for multicore boot (0x0000 - 0x1000) - memory_reserve(0x0000, 0x1000); + memory_reserve(0x00000000, 0x00001000); // initramfs, allocate 4 pages memory_reserve(0x8000000, 0x8000000 + 0x4000); // kernel image @@ -275,10 +323,9 @@ void memory_reserve(unsigned int start, unsigned int end){ uart_hex(end); uart_puts("\n"); - int start_index = (start-HEAP_START_ADDRESS)/PAGE_SIZE; + int start_index = (int)((start-HEAP_START_ADDRESS)/PAGE_SIZE); // assume end_index do not exceed limit int end_index = (end-HEAP_START_ADDRESS)/PAGE_SIZE; - for(int i=start_index;i/dev/null 2>/dev/null || true + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -d in_asm + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_5/Makefile.gcc b/lab_5/Makefile.gcc new file mode 100644 index 000000000..77366f3cf --- /dev/null +++ b/lab_5/Makefile.gcc @@ -0,0 +1,52 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles + +all: clean kernel8.img + +start.o: start.S + $(GCC) $(CFLAGS) -c start.S -o start.o + +%.o: %.c + $(GCC) $(CFLAGS) -c $< -o $@ -g + +kernel8.img: start.o $(OBJS) + $(LD) -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + $(OBJCPY) -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_5/README.md b/lab_5/README.md new file mode 100644 index 000000000..ff2c23e3f --- /dev/null +++ b/lab_5/README.md @@ -0,0 +1,6 @@ +1. python UART transfer data loss +2. init UART register to avoid garbage pending +3. link loader can arrange the .text section freely + - why align +4. wze is for halting CPU that is not id 0 +5. \ No newline at end of file diff --git a/lab_5/bootloader/Makefile b/lab_5/bootloader/Makefile new file mode 100644 index 000000000..2a00a5890 --- /dev/null +++ b/lab_5/bootloader/Makefile @@ -0,0 +1,59 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.c=.o) +CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles +BOOTLOADER_BIN = kernel8.img +all: clean kernel8.img + +start.o: start.S + $(GCC) $(CFLAGS) -c start.S -o start.o + +%.o: %.c + $(GCC) $(CFLAGS) -c $< -o $@ -g + +kernel8.img: start.o $(OBJS) + $(LD) -nostdlib -nostartfiles start.o $(OBJS) -T link.ld -o kernel8.elf + $(OBJCPY) -O binary kernel8.elf kernel8.img + +clean: + rm kernel8.elf *.o >/dev/null 2>/dev/null || true + +run: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -dtb bcm2710-rpi-3-b-plus.dtb + +run_asm: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial pty -display none -dtb bcm2710-rpi-3-b-plus.dtb -d in_asm + + +run_stdio: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -initrd initramfs.cpio -serial stdio -display none -dtb bcm2710-rpi-3-b-plus.dtb + +debug: + qemu-system-aarch64 -M raspi3b -kernel kernel8.img -serial null -serial stdio -display none -s -S diff --git a/lab_5/bootloader/bcm2710-rpi-3-b-plus.dtb b/lab_5/bootloader/bcm2710-rpi-3-b-plus.dtb new file mode 100644 index 0000000000000000000000000000000000000000..a219bf3d5ca7a1e6d14618556f73a73911460911 GIT binary patch literal 35026 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 literal 0 HcmV?d00001 diff --git a/lab_5/bootloader/device_tree.c b/lab_5/bootloader/device_tree.c new file mode 100644 index 000000000..6370eb7b7 --- /dev/null +++ b/lab_5/bootloader/device_tree.c @@ -0,0 +1,74 @@ +#include "include/device_tree.h" +#include "include/uart.h" +// #include +// #include + +device_tree_header myHeader; + +void header_parser(uintptr_t dtb_address){ + uint32_t* start; + //uint32_t* dtb = mock_load_file(); + uint32_t* dtb = dtb_address; + start = dtb; + // __builtin_bswap32() is a GCC built-in function to convert to the system's endianness.(RPi uses little-endian) + myHeader.magic = __builtin_bswap32(*dtb++); + if ((myHeader.magic - 0xd00dfeed) != 0) { + uart_puts("DTB magic number doesn't match!\r\n"); + return 1; + } + myHeader.totalsize = __builtin_bswap32(*dtb++); + myHeader.off_dt_struct = __builtin_bswap32(*dtb++); + myHeader.off_dt_strings = __builtin_bswap32(*dtb++); + myHeader.off_mem_rsvmap = __builtin_bswap32(*dtb++); + myHeader.version = __builtin_bswap32(*dtb++); + myHeader.last_comp_version = __builtin_bswap32(*dtb++); + myHeader.boot_cpuid_phys = __builtin_bswap32(*dtb++); + myHeader.size_dt_strings = __builtin_bswap32(*dtb++); + myHeader.size_dt_struct = __builtin_bswap32(*dtb++); + + // jump to structure + uint32_t* structure_ptr = (uint32_t *)(start + myHeader.off_dt_struct); + while(1){ + uint32_t token = __builtin_bswap32(*structure_ptr++); + if(token == FDT_BEGIN_NODE){ + uart_puts("Start\n"); + } + } + + //The node’s name as a null-terminated string + + + +} + +// unsigned long* mock_load_file() { +// FILE *file = fopen("bcm2710-rpi-3-b-plus.dtb", "rb"); +// if (!file) { +// perror("Failed to open file"); +// return 1; +// } + +// // Get the size of the file +// fseek(file, 0, SEEK_END); +// long fileSize = ftell(file); +// rewind(file); + +// // Allocate memory to hold the entire file +// unsigned char *buffer = (unsigned char *)malloc(fileSize); +// if (!buffer) { +// perror("Failed to allocate memory"); +// fclose(file); +// return 1; +// } + +// // Read the entire file into the buffer +// size_t bytesRead = fread(buffer, 1, fileSize, file); +// if (bytesRead != fileSize) { +// perror("Failed to read file"); +// free(buffer); +// fclose(file); +// return 1; +// } + +// return (unsigned long*)buffer; +// } \ No newline at end of file diff --git a/lab_5/bootloader/include/device_tree.h b/lab_5/bootloader/include/device_tree.h new file mode 100644 index 000000000..6846d0cba --- /dev/null +++ b/lab_5/bootloader/include/device_tree.h @@ -0,0 +1,34 @@ +#include "stdint.h" + + +typedef struct fdt_header { + // 0xd00dfeed (big-endian) + uint32_t magic; + uint32_t totalsize; + // offsets of each block from start + uint32_t off_dt_struct; + uint32_t off_dt_strings; + uint32_t off_mem_rsvmap; + + uint32_t version; + uint32_t last_comp_version; + // physical ID of the system’s boot CPU + uint32_t boot_cpuid_phys; + uint32_t size_dt_strings; + uint32_t size_dt_struct; +} device_tree_header; + +#define ALIGN_MEMORY_BLOCK 8 + +/* All tokens shall be aligned on a 32-bit boundary */ +#define ALIGN_STRUCT_BLOCK 4 + +/* tokens used for structure block */ +#define FDT_BEGIN_NODE 0x00000001 +#define FDT_END_NODE 0x00000002 +#define FDT_PROP 0x00000003 +#define FDT_NOP 0x00000004 +#define FDT_END 0x00000009 + + +void header_parser(); diff --git a/lab_5/bootloader/include/gpio.h b/lab_5/bootloader/include/gpio.h new file mode 100644 index 000000000..52fa671d0 --- /dev/null +++ b/lab_5/bootloader/include/gpio.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#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)) diff --git a/lab_5/bootloader/include/mbox.h b/lab_5/bootloader/include/mbox.h new file mode 100644 index 000000000..e0e2e41f1 --- /dev/null +++ b/lab_5/bootloader/include/mbox.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/* a properly aligned buffer */ +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 MBOX_TAG_GETSERIAL 0x10004 +#define MBOX_TAG_REVISION 0x00010002 +#define MBOX_TAG_MEMORY 0x00010005 +#define MBOX_TAG_LAST 0 + +int mbox_call(unsigned char ch); diff --git a/lab_5/bootloader/include/stdint.h b/lab_5/bootloader/include/stdint.h new file mode 100644 index 000000000..3ddcc9b17 --- /dev/null +++ b/lab_5/bootloader/include/stdint.h @@ -0,0 +1,9 @@ + +typedef unsigned int uint16_t; + +typedef unsigned long uint32_t; + +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; +typedef float float32; +typedef double float64; \ No newline at end of file diff --git a/lab_5/bootloader/include/uart.h b/lab_5/bootloader/include/uart.h new file mode 100644 index 000000000..245c358c8 --- /dev/null +++ b/lab_5/bootloader/include/uart.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +void uart_init(); +void uart_send(unsigned int c); +char uart_getc(); +void uart_puts(char *s); +void uart_hex(unsigned int d); \ No newline at end of file diff --git a/lab_5/bootloader/include/utils.h b/lab_5/bootloader/include/utils.h new file mode 100644 index 000000000..b993a5b68 --- /dev/null +++ b/lab_5/bootloader/include/utils.h @@ -0,0 +1,4 @@ +void set(long addr, unsigned int value); +void reset(); +int strcmp(char* a, char* b); +void cancel_reset(); \ No newline at end of file diff --git a/lab_5/bootloader/initramfs.cpio b/lab_5/bootloader/initramfs.cpio new file mode 100644 index 0000000000000000000000000000000000000000..e9c1dda97f1391b336871a2da59e34bd241fa43f GIT binary patch literal 1024 zcmeH@K@Ng26hv8j3b+87mIiQ%u_Pw0h!HOt3;y|ZOd9-B4l9R&fn>^y@5k6kI zmbaUt8zE&!W7VrbFV(b 0: + received_content = read_line(s) + print(received_content) + +with open("/home/laxiflora/Desktop/osc2024/lab_4/shell/shell_kernel.img", "rb") as f: + sent_size = 0 # Initialize size counter + + byte = f.read(1) # Read the first byte + while byte: + s.write(byte) # Send the byte over serial + # s.flush() # Flush the output buffer + sent_size += 1 # Increment size counter + byte = f.read(1) # Read the next byte + + +assert sent_size == size +print("kernel sent successfully.") +# Register signal handlers +signal.signal(signal.SIGTSTP, tstp_handler) +signal.signal(signal.SIGCONT, cont_handler) + +print(f"Process ID: {os.getpid()}") + +# Run a loop to keep the program alive and responsive to signals +while True: + received_content = read_line(s) + print(received_content) + +# # get response of whether kernel is loaded successfully or not +# time.sleep(1) +# while(True): +# while s.in_waiting > 0: +# received_content = read_line(s) +# print(received_content) +# print("#", end=" ") +# inp = input() +# if(inp == ""): +# continue +# inp += "\n" +# bytes_to_send = inp.encode('utf-8') +# s.write(bytes_to_send) +# #while s.in_waiting > 0: +# # received_content = read_line(s) +# # print(received_content) +# time.sleep(1) \ No newline at end of file diff --git a/lab_5/bootloader/link.ld b/lab_5/bootloader/link.ld new file mode 100644 index 000000000..5d4536049 --- /dev/null +++ b/lab_5/bootloader/link.ld @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +SECTIONS +{ + . = 0x60000; + PROVIDE(_head = .); + .relocate : { + KEEP(*(.text.relocate)) + } + . = ALIGN(4096); + + .imgLoader : { + KEEP(*(.text.load_img)) + } + . = ALIGN(4096); + .text : { + KEEP(*(.text.boot)) + *(.text) + } + . = ALIGN(4096); + PROVIDE(_data = .); + .data : { *(.data .data.*) } + .bss : { + . = ALIGN(16); + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + _end = .; +} +__bss_size = (__bss_end - __bss_start)>>3; +__loader_size = (_end - _head)>>3; \ No newline at end of file diff --git a/lab_5/bootloader/main.c b/lab_5/bootloader/main.c new file mode 100644 index 000000000..e8be04b8c --- /dev/null +++ b/lab_5/bootloader/main.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#define MAX_BUFFER 10 +#include "include/uart.h" +#include "include/utils.h" +#include "include/mbox.h" +#include "include/stdint.h" +#include "include/device_tree.h" + +void load_img(){ + unsigned int size = 0; + unsigned char *size_buffer = (unsigned char *) &size; + uart_puts("enter kernel size now:"); + for(int i=0; i<4; i++) + size_buffer[i] = uart_getc(); + uart_puts("size-check correct\n"); + + uart_puts("Kernel size received: "); + uart_hex(size); + uart_puts("\n"); + + char *kernel = (char *) 0x80000; + while(size--) *kernel++ = uart_getc(); + + uart_puts("kernel-loaded\n"); + return; + +} + +void relocator(uintptr_t dtb_address){ + uart_init(); + // header_parser(dtb_address); + load_img(); + asm volatile( + "mov x30, 0x80000;" + "ret;" + ); +} diff --git a/lab_5/bootloader/mbox.c b/lab_5/bootloader/mbox.c new file mode 100644 index 000000000..b5b47c2f2 --- /dev/null +++ b/lab_5/bootloader/mbox.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "include/gpio.h" + +/* mailbox message buffer +* The buffer itself is 16-byte aligned as only the upper 28 bits of the address can be passed via the mailbox. +*/ +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 +#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) +{ + 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? */ + 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; +} diff --git a/lab_5/bootloader/reader.py b/lab_5/bootloader/reader.py new file mode 100644 index 000000000..19a5e759a --- /dev/null +++ b/lab_5/bootloader/reader.py @@ -0,0 +1,9 @@ +with open("./bcm2710-rpi-3-b-plus.dtb", "rb") as f: + data = f.read() +# Filter out the 0x00 bytes +filtered_data = bytes(b for b in data if b != 0x00) + +# Print the filtered binary data +print(filtered_data) + +#print(data) \ No newline at end of file diff --git a/lab_5/bootloader/start.S b/lab_5/bootloader/start.S new file mode 100644 index 000000000..b086305c4 --- /dev/null +++ b/lab_5/bootloader/start.S @@ -0,0 +1,43 @@ +.section ".text.relocate" +.global _relocate + +_relocate: + // relocate our code from load address to link address + ldr x1, =0x80000; // src address + ldr x2, =0x60000; // target address + ldr w3, =__loader_size +1: ldr x4, [x1], #8 + str x4, [x2], #8 + sub w3, w3, #1 + cbnz w3, 1b + + ldr x1, =_start + mov sp, x1 + + // clear bss + ldr x1, =__bss_start + ldr w2, =__bss_size +2: cbz w2, 3f + str xzr, [x1], #8 + sub w2, w2, #1 + cbnz w2, 2b + + +3: // Device tree address has been moved from x0 to x10 within the bootloader. + mov x0, x10 + bl relocator-0x20000 + b _start + + +.section ".text.boot" + +.global _start + +_start: + // jump to main function in C + bl 0x80000 + // halt this core if return +1: + wfe + b 1b + diff --git a/lab_5/bootloader/uart.c b/lab_5/bootloader/uart.c new file mode 100644 index 000000000..5e63f2d3a --- /dev/null +++ b/lab_5/bootloader/uart.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "include/gpio.h" + +/** Auxilary mini UART registers + * Address & Description refer: https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf Page.8 + */ + +#define AUX_ENABLE ((volatile unsigned int*)(MMIO_BASE+0x00215004)) +#define AUX_MU_IO ((volatile unsigned int*)(MMIO_BASE+0x00215040)) +#define AUX_MU_IER ((volatile unsigned int*)(MMIO_BASE+0x00215044)) +#define AUX_MU_IIR ((volatile unsigned int*)(MMIO_BASE+0x00215048)) +#define AUX_MU_LCR ((volatile unsigned int*)(MMIO_BASE+0x0021504C)) +#define AUX_MU_MCR ((volatile unsigned int*)(MMIO_BASE+0x00215050)) +#define AUX_MU_LSR ((volatile unsigned int*)(MMIO_BASE+0x00215054)) +#define AUX_MU_MSR ((volatile unsigned int*)(MMIO_BASE+0x00215058)) +#define AUX_MU_SCRATCH ((volatile unsigned int*)(MMIO_BASE+0x0021505C)) +#define AUX_MU_CNTL ((volatile unsigned int*)(MMIO_BASE+0x00215060)) +#define AUX_MU_STAT ((volatile unsigned int*)(MMIO_BASE+0x00215064)) +#define AUX_MU_BAUD ((volatile unsigned int*)(MMIO_BASE+0x00215068)) + +/** + * Set baud rate and characteristics (115200 8N1) and map to GPIO + */ +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *AUX_ENABLE |=1; // enable UART1, AUX mini uart + *AUX_MU_CNTL = 0; + *AUX_MU_LCR = 3; // 8 bits + *AUX_MU_MCR = 0; + *AUX_MU_IER = 0; + *AUX_MU_IIR = 0xc6; // disable interrupts + *AUX_MU_BAUD = 270; // 115200 baud + /* map UART1 to GPIO pins */ + r=*GPFSEL1; + r&=~((7<<12)|(7<<15)); // gpio14, gpio15 + r|=(2<<12)|(2<<15); // alt5 + *GPFSEL1 = r; + *GPPUD = 0; // enable pins 14 and 15 + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; // flush GPIO setup + *AUX_MU_CNTL = 3; // enable Tx, Rx + /*EXTRA: Read from AUX_MU_IO until AUX_MU_LSR indicates no more data*/ + while (*AUX_MU_LSR & 0x01) { + // Read and discard the data + volatile unsigned int data = *AUX_MU_IO; + (void)data; // Prevent unused variable warning + } +} + +void uart_enable_interrupt(){ + // enable tx rx interrupt in uart + *AUX_MU_IER |= 0x02; + *IRQS1 |= 1 << 29; +} + + +/** + * Send a character + */ +void uart_send(unsigned int c) { + /* wait until we can send */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20)); + /* write the character to the buffer */ + *AUX_MU_IO=c; +} + +/** + * Receive a character + */ +char uart_getc() { + char r; + /* wait until something is in the buffer */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01)); + /* read it and return */ + r=(char)(*AUX_MU_IO); + /* convert carriage return to newline */ + return r=='\r'?'\n':r; +} + +/** + * Display a string + */ +void uart_puts(char *s) { + while(*s) { + /* convert newline to carriage return + newline */ + if(*s=='\n') + uart_send('\r'); + uart_send(*s++); + } +} + +/** + * Display a binary value in hexadecimal + */ +void uart_hex(unsigned int d) { + unsigned int n; + int c; + for(c=28;c>=0;c-=4) { + // get highest tetrad + n=(d>>c)&0xF; + // 0-9 => '0'-'9', 10-15 => 'A'-'F' + n+=n>9?0x37:0x30; + uart_send(n); + } +} \ No newline at end of file diff --git a/lab_5/bootloader/utils.c b/lab_5/bootloader/utils.c new file mode 100644 index 000000000..d31e58159 --- /dev/null +++ b/lab_5/bootloader/utils.c @@ -0,0 +1,61 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC 0x3F10001c +#define PM_WDOG 0x3F100024 + +/** + * compare two string, given s1 and s2 + * return 0 if the both string are equal; + * return -1 if s1 is less than s2; + * return 1 if s1 is greater than s2 + */ +int strcmp(char* a, char* b){ + int value = 0; + while(*a != '\0' && *b != '\0'){ + if(*a < *b){ + return -1; + } + else if(*a > *b){ + return 1; + } + else{ + a++; + b++; + } + } + if(*a == '\0'){ + value++; + } + if(*b == '\0'){ + value--; + } + return value; +} + +/** + * set up given value to given address + */ +void set(long addr, unsigned int value) { + volatile unsigned int* point = (unsigned int*)addr; + *point = value; +} + + +/** + * reboot respberry pi + * if tick=0, reboot instantly; + * otherwise, wait for tick seconds to reboot + */ +void reset(int tick) { // reboot after watchdog timer expire + set(PM_RSTC, PM_PASSWORD | 0x20); // full reset + if(tick != 0){ + set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick + } +} + +/** + * clear reboot register + */ +void cancel_reset() { + set(PM_RSTC, PM_PASSWORD | 0); // full reset + set(PM_WDOG, PM_PASSWORD | 0); // number of watchdog tick +} \ No newline at end of file diff --git a/lab_5/config.txt b/lab_5/config.txt new file mode 100644 index 000000000..7e9ff304c --- /dev/null +++ b/lab_5/config.txt @@ -0,0 +1,2 @@ +initramfs initramfs.cpio 0x80000000 +kernel=bootloader.img \ No newline at end of file diff --git a/lab_5/rootfs/hello.txt b/lab_5/rootfs/hello.txt new file mode 100644 index 000000000..ca9e3b5cc --- /dev/null +++ b/lab_5/rootfs/hello.txt @@ -0,0 +1 @@ +this is a example file. diff --git a/lab_5/rootfs/hello2.txt b/lab_5/rootfs/hello2.txt new file mode 100644 index 000000000..d90bb747c --- /dev/null +++ b/lab_5/rootfs/hello2.txt @@ -0,0 +1 @@ +this is another example file. diff --git a/lab_5/rootfs/link.ld b/lab_5/rootfs/link.ld new file mode 100644 index 000000000..bd0d89847 --- /dev/null +++ b/lab_5/rootfs/link.ld @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +SECTIONS +{ + . = 0x30000; + PROVIDE(_head = .); + .text : { KEEP(*(.text.boot)) *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + PROVIDE(_data = .); + .data : { *(.data .data.*) } + .bss : { + . = ALIGN(16); + __bss_start = .; + *(.bss .bss.*) + *(COMMON) + __bss_end = .; + } + _end = .; +} +__bss_size = (__bss_end - __bss_start)>>3; +__loader_size = (_end - _head)>>3; \ No newline at end of file diff --git a/lab_5/rootfs/makefile b/lab_5/rootfs/makefile new file mode 100644 index 000000000..1f075562f --- /dev/null +++ b/lab_5/rootfs/makefile @@ -0,0 +1,36 @@ +# +# Copyright (C) 2018 bzt (bztsrc@github) +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# +# + +GCC = "aarch64-linux-gnu-gcc" +LD = "aarch64-linux-gnu-ld" +OBJCPY = "aarch64-linux-gnu-objcopy" +SRCS = $(wildcard *.c) +OBJS = $(SRCS:.S=.o) +CFLAGS = -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles +BOOTLOADER_BIN = kernel8.img +all: user_program.S + "aarch64-linux-gnu-gcc" -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles -c user_program.S -o user_program.o + "aarch64-linux-gnu-ld" -nostdlib -nostartfiles user_program.o -T link.ld -o user_program.elf + "aarch64-linux-gnu-objcopy" -O binary user_program.elf user_program.img diff --git a/lab_5/rootfs/user_program b/lab_5/rootfs/user_program new file mode 100755 index 0000000000000000000000000000000000000000..e235f8e5dca3944e2e14158775cca560bee208ea GIT binary patch literal 5704 zcmeHLJ!lkB5T4}n>km0Kg5Y0aiZt0nlxSgbmtU1jA~6aPVcEMqyp#J0cN<7-Oc}vO z(B59KwYIYqv9U{`lF}3kB6!a1n{RWw-boY%i+ynWy_q-Pym_;?1M}`rXJ@**x(Fjd zFG!@RZlg)-!oU%oFr?`s_4D%}9iTpzdwiW)PaEJ>Gd9&Va6t75M&Z5E^(Y=!J0Kzy z?A5h)a9iUBl7AZWlvtBPhLs#L9)X|K84x^i_bc9O#wBF#D98&(7bVm$&Yn+I(7g_-^Cl z^N*Jj4<6tBdO`f)$J5^&8*liqkC^}V^f2u_Yc`kIfovI%I0JD8;ta$Yh%*ppAkILX zfj9$k2I36-w;A~Sy;+ms2DFbvubEa^dO;bZD(^F*c9}%`RX(P8R1xs4Y5cQ{RuN18 z1kvCAiSq=X3VnGiKSA9=UmMmZg1m+GJwd+0`d&g_!}`A9{voXI=e`&n@9qlkN?UF9 zgR~vd3%iGQn!9W>JLE(AecRbfbKAv!qVb$meKej4)+cF@AL01VbJJ)E~4bQ22Hl#w;4d(s|TdA(#I-Wx!5m}A(is$4Qy}H37W~HiEsIQP!t$79O zPIcAFt(N%SqvVn=6`e+rEO))i9t?VQvb@5Y=SxndlxM>lOZ>1_${wHhZw$Gok~gbm zA^2|a{oo!8dxif6L}z%RzlGoFz6gBW7eOB9$rr9I*dO%^ctQ=qix!_WuS@L$AN380 zdM5QyVh11k%dC_8CGhcG1Ec4S%GcB{>MQOaf!K%5{DE^ozR45eN(?gaUE&@M_j9P{ zh(Bq}$!3(8z{mHyrT2xfSM%Wf(DR=*#7EuPR(>>o@PM*6a)&*9)By1wE~?zygl|&%wgRdmvsU zTeoojIX8qv3|O-7{QcY|wx3Qf&YWHkJRE#L?_33ihVUI$03nV^6JmhA(ykFzSX%o4 z9mni9(X+bePk4BxUSE?D%D1YzBx+>omc&)vxc*Au!ok?|V^scwhqB^5$Dv9j`?Jm# zA;T8^j=~-I4gI0Qf7dzcz=MuDdmZ?R!pmxPUIfT-pC?&#m!(%(ya-b47l@*1o=5rh zV`9?ec7|x4#I$Nk#F?P{CXHugR!Ri$t_Q5V5{hJ z=l8(1lW&Xf`NbF{S0A!heaL<7=~{~YzA?zYeVSa4ziWdq?rqJKyc^$n T9i+V3f0M8_|I!E#{_uYTAnra7 literal 0 HcmV?d00001 diff --git a/lab_5/rootfs/user_program.img b/lab_5/rootfs/user_program.img new file mode 100755 index 0000000000000000000000000000000000000000..1adf648a4c1b9d2d1b5e9fa08b84e52ef2fafc78 GIT binary patch literal 24 gcmZQzXt>0{!Z4AMf#Hh02*bzK|Nn/dev/null 2>/dev/null || true + +run_asm: + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none -d in_asm + +run: + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none + +debug: + qemu-system-aarch64 -M raspi3b -kernel shell_kernel.img -initrd initramfs.cpio -serial null -serial stdio -display none -s -S diff --git a/lab_5/shell/cpio.c b/lab_5/shell/cpio.c new file mode 100644 index 000000000..99ee37706 --- /dev/null +++ b/lab_5/shell/cpio.c @@ -0,0 +1,102 @@ +#include "include/cpio.h" +#include "include/uart.h" +#include "include/stdint.h" +#include "include/utils.h" + +char* cpio_addr = (char *)0x8000000; + +void cpio_ls(){ + char* addr = (char*) cpio_addr; + uart_puts((char *)(addr+sizeof(struct cpio_header))); + while(strcmp((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); + uart_puts(addr+sizeof(struct cpio_header)); + uart_puts("\n"); + addr += (headerPathname_size + file_size); + } +} + +void cpio_exec(char *filename){ + char *target = findFile(filename); + if (target){ + struct cpio_header *header = (struct cpio_header *)target; + unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize)); + unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; + + utils_align(&headerPathname_size,4); + utils_align(&file_size,4); + char *file_content = target + headerPathname_size; + + char *program_ptr = (char *) 0x30000; // load the user program into 0x30000 + char* start_point = (char*) 0x30000; + char* stack_pointer = (char *) (0x30000 + 0x3000); // Stack pointer for the user program, base address+0x3000 + for (unsigned int i = 0; i < file_size; i++){ + *program_ptr ++ = *file_content++; + } + asm volatile( + // 0x3c0 + "mov x0, 0x3c0;\n\t" + "msr spsr_el1, x0;\n\t" + // start address of user program + "mov x1, 0x30000;\n\t" + "msr elr_el1, x1;\n\t" + // sp for user program + "mov x2, %0;\n\t" + "msr sp_el0, x2;\n\t" + "eret;" + : // No output operands + : "r" (start_point), "r" (stack_pointer) + : "x0", "x1", "x2" // tell compiler x0~x2 has been used + ); + } + uart_puts("completed.\n"); +} + + + +void cpio_cat(char *filename){ + char *target = findFile(filename); + if (target){ + struct cpio_header *header = (struct cpio_header *)target; + unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize)); + unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; + + utils_align(&headerPathname_size,4); + utils_align(&file_size,4); + char *file_content = target + headerPathname_size; + for (unsigned int i = 0; i < file_size; i++) + { + uart_send(file_content[i]); + } + uart_puts("\n"); + } + else + { + uart_puts("Not found the file\n"); + } +} + +char *findFile(char *name){ + char *addr = (char *)cpio_addr; + while (strcmp((char *)(addr + sizeof(struct cpio_header)), "TRAILER!!!") != 0){ + if ((strcmp((char *)(addr + sizeof(struct cpio_header)), name) == 0)){ + return addr; + } + struct cpio_header* header = (struct cpio_header *)addr; + unsigned long pathname_size = utils_atoi(header->c_namesize,(int)sizeof(header->c_namesize));; + unsigned long file_size = utils_atoi(header->c_filesize,(int)sizeof(header->c_filesize)); + unsigned long headerPathname_size = sizeof(struct cpio_header) + pathname_size; + + utils_align(&headerPathname_size,4); + utils_align(&file_size,4); + addr += (headerPathname_size + file_size); + } + return 0; +} \ No newline at end of file diff --git a/lab_5/shell/dynamic_allocator.c b/lab_5/shell/dynamic_allocator.c new file mode 100644 index 000000000..be3cc282d --- /dev/null +++ b/lab_5/shell/dynamic_allocator.c @@ -0,0 +1,149 @@ +#include "include/dynamic_allocator.h" +#include "include/page_allocator.h" + +// #define POOL {4, 8, 16, 32, 64, 128, 256, 512, 1024} +// #define PARTITION {4, 2, 2, 2, 2, 2, 2, 2, 2} +// #define POOL_SIZE 8 +// // max pages allowed to be partitioned +// #define MAX_PAGE 64 + +// typedef struct Page{ +// void* prefix; +// // the occupied section of each partition size in page +// int usage[POOL_SIZE]; +// } + +// typedef struct DynamicAllocator{ +// int chunk_option[POOL_SIZE]; +// int partition[POOL_SIZE]; +// int allocated_page_num; +// Page allocated_page_info[MAX_PAGE]; + +// }DynamicAllocator; + + +struct DynamicAllocator dynamic_allocator; + + +void init_dynamic_allocator(){ + int pool[] = POOL; + int part[] = PARTITION; + dynamic_allocator.allocated_page_num = 0; + for(int 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 +__loader_size = (_end - _head)>>3; \ No newline at end of file diff --git a/lab_5/shell/main.c b/lab_5/shell/main.c new file mode 100644 index 000000000..d936be184 --- /dev/null +++ b/lab_5/shell/main.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#define MAX_BUFFER 50 +#include "include/uart.h" +#include "include/utils.h" +#include "include/mbox.h" +#include "include/cpio.h" +#include "include/page_allocator.h" +#include "include/dynamic_allocator.h" + +extern void set_exception_vector_table(); +extern void core_timer_enable(); + + + +void main(int argc, char* argv[]){ + // init uart + uart_init(); + init_simple_malloc(); + // init exception table and interrupt (lab3) + set_exception_vector_table(); + // show el + unsigned long el; + asm volatile ("mrs %0, CurrentEL" : "=r" (el)); + el = el >> 2; // CurrentEL的值在高两位 + + // print current exception level + uart_puts("Booted! Current EL: "); + uart_send('0' + el); + uart_puts("\n"); + // init memory (lab4) + init_reserve_memory(); + init_buddy_system(); + init_dynamic_allocator(); + + // char* my_array = malloc_page(1); + // char* my_variablwe = (char*)malloc(1023); + // char* my_varieable = (char*)malloc(1023); + // char* wmy_variable = (char*)malloc(1023); + // char* my_vrariable = (char*)malloc(1023); + // char* my_variatble = (char*)malloc(1023); + // free(my_variablwe); + // my_variablwe = (char*)malloc(7642); + // free(my_variablwe); + // my_variablwe = (char*)malloc(1023); + // free(my_variablwe); + // my_variablwe = (char*)malloc(1023); + // free(my_variablwe); + // free(my_variatble); + + // char* my_array = malloc_page(3); + // char* my_array2 = malloc_page(3); + // char* my_array3 = malloc_page(3); + // char* my_array4 = malloc_page(3); + // char* my_array5 = malloc_page(3); + // char* my_array6 = malloc_page(3); + while(1){ + char command[MAX_BUFFER]; + char c = '\0'; + int length=0; + for(int i=0; i\t: print the content of file in initfs\n"); + uart_puts("hello\t: print hello world!\n"); + uart_puts("exec: execute user program in initfs\n"); + uart_puts("async_uart: switch to async uart mode (currently for demo only)\n"); + uart_puts("malloc \t: malloc memory of size \n"); + uart_puts("free\t: free all malloced page memory (for demo, the memory alloced in simple malloc will not be freed)\n"); + uart_puts("reboot\t: reboot the device\n"); + } + else if(strcmp(command, "hello") == 0){ + uart_puts("Hello World!\n"); + } + else if(strcmp(command, "free") == 0){ + // free_page(my_array); + // free_page(my_array2); + // free_page(my_array3); + // free_page(my_array4); + // free_page(my_array5); + //free_page(my_array6); + + // my_array = malloc_page(3); + // my_array2 = malloc_page(3); + // my_array3 = malloc_page(3); + // my_array4 = malloc_page(3); + // my_array5 = malloc_page(3); + } + else if(strcmp(command, "ls") == 0){ + cpio_ls(); + } + else if(strcmp(command, "async_uart") == 0){ + demo_async_uart(); + } + else if(strcmp(command, "reboot") == 0){ + reset(); + } + else if(strcmp(command, "exec") == 0){ + uart_puts("executing...\n"); + // execute a dedicated user program + cpio_exec("user_program.img"); + } + // command with arguments + else{ + char arguments[3][MAX_BUFFER]; + // initialize + for(int i=0;i<3;i++){ + for(int j=0;jroot; + target->root = target->root->next; + return to_ret; +} + +void init_order_list(){ + int current_order = MAX_ORDER-1; + int current_page_index = 0; + // assume all pages are available at beginnig, greedly allocate pages in max order size + while(current_order >= 0){ + while((current_page_index+_pow(2, current_order)-1) < AVAILABLE_PAGE_NUM){ + unsigned int allocated_size = _pow(2, current_order)*PAGE_SIZE; + // record the grouped block at The Array + the_array[current_page_index].block_size = _pow(2, current_order); + // malloc a struct node to record the meta data of this block + Node* new_node = simple_malloc(sizeof(Node)); + // push into order list + new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*current_page_index); + new_node->page_index = current_page_index; + list_push_back(new_node, current_order); + + uart_puts("[Init] grouping block at address 0x"); + uart_hex(new_node->address); + uart_puts(" with 0x"); + uart_hex((unsigned int)allocated_size/PAGE_SIZE); + uart_puts(" pages and start at index "); + uart_hex((unsigned int)new_node->page_index); + uart_puts(" in The Array"); + uart_puts("\n"); + + current_page_index = current_page_index+_pow(2, current_order)+1; + } + current_order--; + } + +} + +void print_order_list(OrderList* list){ + Node* cur = list->root; + uart_puts("address : \n"); + while(cur != NULL){ + uart_hex(cur->address); + uart_puts("\n"); + cur = cur->next; + + } +} + +void init_buddy_system(){ + // initialize The Array + for(int i=0;iroot != NULL; +} + +Node* get_buddy(OrderList* target, int target_page_index){ + Node* cur = target->root; + Node* prev = NULL; + while(cur != NULL){ + if(cur->page_index == target_page_index){ + if(prev != NULL){ + prev->next = cur->next; + } + // root is the buddy + else{ + target->root = target->root->next; + } + cur->next = NULL; + return cur; + } + prev = cur; + cur = cur->next; + } + uart_puts("[Assertion Error] buddy not found\n"); + print_order_list(target); + return NULL; +} + +void free_page(void* to_free){ + int page_index = ((unsigned int)to_free-HEAP_START_ADDRESS)/PAGE_SIZE; + int free_block_size = the_array[page_index].block_size; + int do_merge = 0; + if(the_array[page_index].available != OCCUPIED){ + uart_puts("[Assertion Error] releasing free page head\n"); + } + the_array[page_index].available = FREE; + int next_block_index = page_index+free_block_size+1; + uart_puts("[Free] block that contains "); + // block size starts from zero, thus need to +1 + uart_hex(free_block_size+1); + uart_puts(" pages started from address 0x"); + uart_hex((unsigned int)to_free); + uart_puts(" to address 0x"); + uart_hex((unsigned int)to_free+(free_block_size*PAGE_SIZE)); + uart_puts(" with index starts from "); + uart_hex(page_index); + uart_puts("\n"); + + if(the_array[next_block_index].available == FREE){ + // debug: print the address of next page of freed block + // uart_puts("Accessing location: 0x"); + // uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*next_block_index)); + // uart_puts("\n"); + + // same size, can merge + if(the_array[next_block_index].block_size == free_block_size && the_array[next_block_index].available==FREE){ + int order =0, block_size = free_block_size; + // get sqrt(2) of block_size to obtain order + while(block_size > 0){ + order++; + block_size/=2; + } + print_order_list(&order_list[order]); + Node* buddy = get_buddy(&order_list[order], next_block_index); + if(buddy != NULL){ + Node* new_node = simple_malloc(sizeof(Node)); + // push into order list + new_node->address = (unsigned char*) to_free; + new_node->page_index = page_index; + the_array[page_index].block_size = _pow(2, order+1); + the_array[next_block_index].available = FREE; + the_array[next_block_index].block_size = FREE; + list_push_back(new_node, order+1); + uart_puts("[Merge] block that contains "); + uart_hex(free_block_size); + uart_puts(" pages started from address 0x"); + uart_hex((unsigned int)to_free); + uart_puts(" to address 0x"); + uart_hex((unsigned int)HEAP_START_ADDRESS+(PAGE_SIZE*(next_block_index+free_block_size))); + uart_puts("\n"); + do_merge = 1; + } + } + } + if(!do_merge){ + Node* new_node = simple_malloc(sizeof(Node)); + new_node->address = (unsigned char*) to_free; + new_node->page_index = page_index; + int order =0, block_size = free_block_size; + // get sqrt(2) of block_size to obtain order + while(block_size > 0){ + order++; + block_size/=2; + } + list_push_back(new_node, order); + } + +} + +unsigned char* malloc_page(int request_page_num){ + //determine the minimum list order that this request needs + int current_order = 0; + int cut_freg = 0; + // start from allocating the smallest block until is can satisfy needs + //print_order_list(&order_list[2]); + while(current_order _pow(2, current_order)){ + current_order++; + } + else{ + if(check_list_has_element(&order_list[current_order])){ + struct Node* allocated_address = list_pop(&order_list[current_order]); + // mark the block as OCCUPIED + the_array[(unsigned int)allocated_address->page_index].available = OCCUPIED; + // the block_size start from zero, thus we need to -1 + the_array[(unsigned int)allocated_address->page_index].block_size = _pow(2, current_order)-1; + // print the log + uart_puts("[Malloc] block that contains "); + uart_hex(_pow(2, current_order)); + uart_puts(" pages started from address 0x"); + uart_hex((unsigned int)allocated_address->address); + uart_puts(" to address 0x"); + uart_hex((unsigned int)((allocated_address->address)+(_pow(2, current_order)-1)*PAGE_SIZE)); + uart_puts(" with index starts from "); + uart_hex((unsigned int)allocated_address->page_index); + uart_puts("\n"); + int cutter_count = 1; + while(cut_freg > 0){ + // mid address is the starting address of last page that BEEN malloced + int mid_page_index = allocated_address->page_index+(_pow(2, current_order-cutter_count))-1; + // end address is the starting address of last page in this block + unsigned char* end_address = mid_page_index+_pow(2, current_order-cutter_count); + Node* new_node = simple_malloc(sizeof(Node)); + // push into order list + new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*(mid_page_index+1)); + new_node->page_index = mid_page_index+1; + the_array[new_node->page_index].block_size = _pow(2, current_order-cutter_count)-1; + uart_puts("[Release redundant memory] block that contains "); + uart_hex(_pow(2, current_order-cutter_count)); + uart_puts(" pages started from address 0x"); + uart_hex(new_node->address); + uart_puts(" to address 0x"); + uart_hex(new_node->address+((the_array[new_node->page_index].block_size)*PAGE_SIZE)); + uart_puts(" is freed \n"); + list_push_back(new_node, current_order-cutter_count); + cut_freg--; + cutter_count++; + } + if(cutter_count>1){ + the_array[(unsigned int)allocated_address->page_index].block_size = _pow(2, current_order-(cutter_count-1))-1; + } + + return allocated_address->address; + } + else{ + cut_freg++; // we may allocate more then 2 times more memory than needed + current_order++; + } + } + } + uart_puts("[Warning] malloc failed, returning 0x00\n"); + return 0x0; +} + + + +void list_push_back(Node* to_push, int order){ + OrderList* target_list = &(order_list[order]); + if(target_list->root == NULL){ + target_list->root = to_push; + } + else{ + Node* current = target_list->root; + while(current->next != NULL){ + current = current->next; + } + current->next = to_push; + } + //print_order_list(target_list); +} + +void init_reserve_memory(){ + // Spin tables for multicore boot (0x0000 - 0x1000) + memory_reserve(0x0000, 0x1000); + // initramfs, allocate 4 pages + memory_reserve(0x8000000, 0x8000000 + 0x4000); + // kernel image + memory_reserve(&_head, (unsigned int)&_head+((unsigned int)&_end)); +} + + +void memory_reserve(unsigned int start, unsigned int end){ + start = start-(start % PAGE_SIZE); + end = end % PAGE_SIZE ? end + PAGE_SIZE - (end % PAGE_SIZE) : end; + + uart_puts("[Reserve] Memory Reserve: Start from adress 0x"); + uart_hex(start); + uart_puts(" to 0x"); + uart_hex(end); + uart_puts("\n"); + + int start_index = (start-HEAP_START_ADDRESS)/PAGE_SIZE; + // assume end_index do not exceed limit + int end_index = (end-HEAP_START_ADDRESS)/PAGE_SIZE; + + for(int i=start_index;i 0, stop +1: wfe + b 1b + + +2: // cpu id == 0 + + // el2 to el1 + bl from_el2_to_el1 + + // 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 + +from_el2_to_el1: + mov x0, (1 << 31) // EL1 uses aarch64 + // move system register to register (write x0 into hcr_el2) + msr hcr_el2, x0 + mov x0, 0x3c5 // 3c5 EL1h (SPSel = 1) with interrupt disabled, 345 enable interrupt + msr spsr_el2, x0 + msr elr_el2, lr + eret // return to EL1 diff --git a/lab_5/shell/thread.c b/lab_5/shell/thread.c new file mode 100644 index 000000000..c7a860a5b --- /dev/null +++ b/lab_5/shell/thread.c @@ -0,0 +1,29 @@ +#include "include/thread.h" +#include "include/dynamic_allocator.h" +#include "include/page_allocator.h" + +Thread thread_queue[MAX_THREAD]; + +void init_thread(){ + // create idle thread +} + +void creat_thread(void (*function_ptr)()){ + Thread* new_thread = malloc(sizeof(Thread)); + new_thread->user_stack = (uint16_t* )malloc(USER_STACK_SIZE); + // new_thread->kernel_stack = (uint16_t* )malloc(KERNEL_STACK_SIZE); + new_thread->x19 = 0x00; + new_thread->x20 = 0x00; + new_thread->x21 = 0x00; + new_thread->x22 = 0x00; + new_thread->x23 = 0x00; + new_thread->x24 = 0x00; + new_thread->x25 = 0x00; + new_thread->x26 = 0x00; + new_thread->x27 = 0x00; + new_thread->x28 = 0x00; + new_thread->fp = (uint64_t)(new_thread->user_stack+USER_STACK_SIZE); // x29: base pointer for local variable in stack + new_thread->lr = 0x00; // x30: store return address + new_thread->sp = new_thread->fp; // stack pointer, varys from function calls + +} \ No newline at end of file diff --git a/lab_5/shell/uart.c b/lab_5/shell/uart.c new file mode 100644 index 000000000..dee6592ce --- /dev/null +++ b/lab_5/shell/uart.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2018 bzt (bztsrc@github) + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "include/gpio.h" +#include "include/uart.h" +/** Auxilary mini UART registers + * Address & Description refer: https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf Page.8 + */ + + +/* + The definition below is for async uart IO +*/ + +#define BUFFER_SIZE 1024 +#define IRQS1 ((volatile unsigned int *)(0x3f00b210)) +char uart_read_buffer[BUFFER_SIZE]; +unsigned int read_idx = 0; + +char uart_write_buffer[BUFFER_SIZE]; +unsigned int write_idx = 0; +unsigned int write_cur = 0; +int async; + + +/** + * Set baud rate and characteristics (115200 8N1) and map to GPIO + */ +void uart_init() +{ + register unsigned int r; + + /* initialize UART */ + *AUX_ENABLE |=1; // enable UART1, AUX mini uart + *AUX_MU_CNTL = 0; + *AUX_MU_LCR = 3; // 8 bits + *AUX_MU_MCR = 0; + *AUX_MU_IER = 0; + *AUX_MU_IIR = 0xc6; // disable interrupts + *AUX_MU_BAUD = 270; // 115200 baud + /* map UART1 to GPIO pins */ + r=*GPFSEL1; + r&=~((7<<12)|(7<<15)); // gpio14, gpio15 + r|=(2<<12)|(2<<15); // alt5 + *GPFSEL1 = r; + *GPPUD = 0; // enable pins 14 and 15 + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = (1<<14)|(1<<15); + r=150; while(r--) { asm volatile("nop"); } + *GPPUDCLK0 = 0; // flush GPIO setup + *AUX_MU_CNTL = 3; // enable Tx, Rx +} + +/** + * Send a character + */ +void uart_send(unsigned int c) { + /* This bit is set if the transmit FIFO can accept at least one byte*/ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20)); + /* write the character to the buffer */ + *AUX_MU_IO=c; +} + +/** + * Receive a character + */ +char uart_getc() { + char r; + /* wait until something is in the buffer */ + do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01)); + /* read it and return */ + r=(char)(*AUX_MU_IO); + /* convert carriage return to newline */ + return r=='\r'?'\n':r; +} + +/** + * Display a string + */ +void uart_puts(char *s) { + while(*s) { + /* convert newline to carriage return + newline */ + if(*s=='\n') + uart_send('\r'); + uart_send(*s++); + } +} + +/** + * Display a binary value in hexadecimal + */ +void uart_hex(unsigned int d) { + unsigned int n; + int c; + for(c=28;c>=0;c-=4) { + // get highest tetrad + n=(d>>c)&0xF; + // 0-9 => '0'-'9', 10-15 => 'A'-'F' + n+=n>9?0x37:0x30; + uart_send(n); + } +} + +void uart_enable_interrupt(){ + *AUX_MU_IER |= 0x02; + *IRQS1 |= 1 << 29; +} + +void uart_load_buffer(){ + while(write_cur < write_idx){ + uart_send(uart_write_buffer[write_cur]); + } +} + +void demo_async_uart(){ + uart_puts("turning to async mode...\n"); + uart_enable_interrupt(); + while(1){ + asm volatile("nop"); + } +} + +void uart_read_handler() { + char ch = (char)(*AUX_MU_IO); + uart_read_buffer[write_idx] = ch; + write_idx++; + uart_write_buffer[write_idx] = ch; + read_idx++; + write_idx++; + if(ch == '\r'){ + uart_puts(uart_write_buffer); + } +} + +void uart_write_handler(){ + if(write_cur < write_idx){ + *AUX_MU_IO=uart_read_buffer[write_cur]; + write_cur++; + } +} \ No newline at end of file diff --git a/lab_5/shell/utils.c b/lab_5/shell/utils.c new file mode 100644 index 000000000..bb2cb26c9 --- /dev/null +++ b/lab_5/shell/utils.c @@ -0,0 +1,118 @@ +#define PM_PASSWORD 0x5a000000 +#define PM_RSTC 0x3F10001c +#define PM_WDOG 0x3F100024 +#define SIMPLE_MALLOC_BUFFER_SIZE 8192 + +unsigned long utils_atoi(const char *s, int char_size) { + unsigned long num = 0; + for (int i = 0; i < char_size; i++) { + num = num * 16; + if (*s >= '0' && *s <= '9') { + num += (*s - '0'); + } else if (*s >= 'A' && *s <= 'F') { + num += (*s - 'A' + 10); + } else if (*s >= 'a' && *s <= 'f') { + num += (*s - 'a' + 10); + } + s++; + } + return num; +} + +int _pow(int base, int exp){ + + int ret = 1; + for(int i=0;i *b){ + return 1; + } + else{ + a++; + b++; + } + } + if(*a == '\0'){ + value++; + } + if(*b == '\0'){ + value--; + } + return value; +} + +/** + * set up given value to given address + */ +void set(long addr, unsigned int value) { + volatile unsigned int* point = (unsigned int*)addr; + *point = value; +} + + +void utils_align(void *size, unsigned int s) { + unsigned long* x = (unsigned long*) size; + unsigned long mask = s-1; + *x = ((*x) + mask) & (~mask); +} + +/** + * reboot respberry pi + * if tick=0, reboot instantly; + * otherwise, wait for tick seconds to reboot + */ +void reset(int tick) { // reboot after watchdog timer expire + set(PM_RSTC, PM_PASSWORD | 0x20); // full reset + if(tick != 0){ + set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick + } +} + +/** + * clear reboot register + */ +void cancel_reset() { + set(PM_RSTC, PM_PASSWORD | 0); // full reset + set(PM_WDOG, PM_PASSWORD | 0); // number of watchdog tick +} + + +static unsigned char simple_malloc_buffer[SIMPLE_MALLOC_BUFFER_SIZE]; +static unsigned long simple_malloc_offset = 0; + +void init_simple_malloc(){ + for(int i=0;i 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; +} \ No newline at end of file From 813085440cdcbd8a5538ee66b65b4ded1e8ae0e3 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Tue, 25 Jun 2024 02:09:38 +0800 Subject: [PATCH 20/23] debug lab4 --- lab_4/shell/page_allocator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lab_4/shell/page_allocator.c b/lab_4/shell/page_allocator.c index 0839fe372..77ed2b2b8 100644 --- a/lab_4/shell/page_allocator.c +++ b/lab_4/shell/page_allocator.c @@ -309,7 +309,7 @@ void init_reserve_memory(){ // initramfs, allocate 4 pages memory_reserve(0x8000000, 0x8000000 + 0x4000); // kernel image - memory_reserve(&_head, (unsigned int)&_head+((unsigned int)&_end)); + memory_reserve(&_head, &_end); } From e66d25a76e70d9fed68f8efb5672d107b7faa083 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Tue, 25 Jun 2024 22:53:42 +0800 Subject: [PATCH 21/23] lab5 basic 1 --- lab_5/shell/Makefile | 3 +- lab_5/shell/_thread.S | 26 +++++ lab_5/shell/include/page_allocator.h | 4 +- lab_5/shell/include/stdint.h | 7 +- lab_5/shell/include/thread.h | 47 ++++++-- lab_5/shell/include/utils.h | 5 +- lab_5/shell/main.c | 43 ++----- lab_5/shell/page_allocator.c | 105 ++++++++++++----- lab_5/shell/thread.c | 161 +++++++++++++++++++++++---- lab_5/shell/utils.c | 1 + 10 files changed, 301 insertions(+), 101 deletions(-) create mode 100644 lab_5/shell/_thread.S diff --git a/lab_5/shell/Makefile b/lab_5/shell/Makefile index ecd9c6b2d..69b1bd455 100644 --- a/lab_5/shell/Makefile +++ b/lab_5/shell/Makefile @@ -39,13 +39,14 @@ all: clean kernel8.img $(GCC) $(CFLAGS) -c $< -o $@ -g "aarch64-linux-gnu-gcc" -Wall -w -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles -c exception_vector.S -o exception_vector.o -g "aarch64-linux-gnu-gcc" -Wall -w -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles -c interrupts.S -o interrupts.o -g + "aarch64-linux-gnu-gcc" -Wall -w -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles -c _thread.S -o _thread.o -g %.o: %.c $(GCC) $(CFLAGS) -c $< -w -o $@ -g kernel8.img: start.o $(OBJS) - $(LD) -nostdlib -nostartfiles start.o $(OBJS) exception_vector.o interrupts.o -T link.ld -o kernel8.elf + $(LD) -nostdlib -nostartfiles start.o $(OBJS) exception_vector.o interrupts.o _thread.o -T link.ld -o kernel8.elf $(OBJCPY) -O binary kernel8.elf shell_kernel.img clean: diff --git a/lab_5/shell/_thread.S b/lab_5/shell/_thread.S new file mode 100644 index 000000000..514958efa --- /dev/null +++ b/lab_5/shell/_thread.S @@ -0,0 +1,26 @@ +.global switch_to +switch_to: + stp x19, x20, [x0, 16 * 0] + stp x21, x22, [x0, 16 * 1] + stp x23, x24, [x0, 16 * 2] + stp x25, x26, [x0, 16 * 3] + stp x27, x28, [x0, 16 * 4] + stp fp, lr, [x0, 16 * 5] + mov x9, sp + str x9, [x0, 16 * 6] + + ldp x19, x20, [x1, 16 * 0] + ldp x21, x22, [x1, 16 * 1] + ldp x23, x24, [x1, 16 * 2] + ldp x25, x26, [x1, 16 * 3] + ldp x27, x28, [x1, 16 * 4] + ldp fp, lr, [x1, 16 * 5] + ldr x9, [x1, 16 * 6] + mov sp, x9 + msr tpidr_el1, x1 + ret + +.global get_current +get_current: + mrs x0, tpidr_el1 + ret \ No newline at end of file diff --git a/lab_5/shell/include/page_allocator.h b/lab_5/shell/include/page_allocator.h index 8cfc79b76..457d0668a 100644 --- a/lab_5/shell/include/page_allocator.h +++ b/lab_5/shell/include/page_allocator.h @@ -1,5 +1,5 @@ -#define HEAP_START_ADDRESS 0x10000000 -#define HEAP_END_ADDRESS 0x20000000 +#define HEAP_START_ADDRESS 0x00000000 +#define HEAP_END_ADDRESS 0x3B400000 #define PAGE_SIZE 0x1000 #define AVAILABLE_PAGE_NUM (HEAP_END_ADDRESS-HEAP_START_ADDRESS)/PAGE_SIZE #define MAX_ORDER 11 diff --git a/lab_5/shell/include/stdint.h b/lab_5/shell/include/stdint.h index 3ddcc9b17..1935a0e48 100644 --- a/lab_5/shell/include/stdint.h +++ b/lab_5/shell/include/stdint.h @@ -1,8 +1,5 @@ - -typedef unsigned int uint16_t; - -typedef unsigned long uint32_t; - +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; typedef unsigned long long uint64_t; typedef unsigned long uintptr_t; typedef float float32; diff --git a/lab_5/shell/include/thread.h b/lab_5/shell/include/thread.h index e83fbaf49..d4d097785 100644 --- a/lab_5/shell/include/thread.h +++ b/lab_5/shell/include/thread.h @@ -2,19 +2,19 @@ #define USER_STACK_SIZE 20480 #define KERNEL_STACK_SIZE 2048 #include "stdint.h" +// ready to run #define READY 1 +// waiting for IO #define WAIT 2 +// exit but not recycle yet #define EXIT 3 +// thread not exist +#define KILLED 4 -typedef struct ThreadQueue{ - Thread queue[MAX_THREAD]; - int queue_index; -} -typedef struct Thread{ - int available; - uint64_t x19; // callee saved registers: the called function will preserve them and restore them before returning +typedef struct TaskStateSegment { + uint64_t x19; uint64_t x20; uint64_t x21; uint64_t x22; @@ -24,9 +24,34 @@ typedef struct Thread{ uint64_t x26; uint64_t x27; uint64_t x28; - uint64_t fp; // x29: base pointer for local variable in stack - uint64_t lr; // x30: store return address - uint64_t sp; // stack pointer, varys from function calls + uint64_t fp; // x29, frame pointer + uint64_t lr; // x30, link register + uint64_t sp; + uint64_t pc; +}TaskStateSegment; + + +typedef struct Thread{ + // tss must be placed at first location, for switch_to and get_current to work + TaskStateSegment tss; + int available; uint16_t* user_stack; uint16_t* kernel_stack; -}Thread; \ No newline at end of file +}Thread; + + + +typedef struct ThreadQueue{ + Thread queue[MAX_THREAD]; + int queue_index; + int current_routine; +}ThreadQueue; + + +int creat_thread(void (*function_ptr)()); +void init_thread(); +void exit(); +void schedule(); +void context_switch(int prev_id, int next_id); +void idle(); +void foo(); \ No newline at end of file diff --git a/lab_5/shell/include/utils.h b/lab_5/shell/include/utils.h index 1808d87fd..a73d65ea4 100644 --- a/lab_5/shell/include/utils.h +++ b/lab_5/shell/include/utils.h @@ -6,4 +6,7 @@ void utils_align(void *size, unsigned int s); unsigned long utils_atoi(const char *s, int char_size); void* simple_malloc(unsigned long size); int _pow(int base, int exp); -void init_simple_malloc(); \ No newline at end of file +void init_simple_malloc(); +void foo(); +void foo2(); +void foo3(); \ No newline at end of file diff --git a/lab_5/shell/main.c b/lab_5/shell/main.c index d936be184..2089a2f63 100644 --- a/lab_5/shell/main.c +++ b/lab_5/shell/main.c @@ -29,6 +29,7 @@ #include "include/cpio.h" #include "include/page_allocator.h" #include "include/dynamic_allocator.h" +#include "include/thread.h" extern void set_exception_vector_table(); extern void core_timer_enable(); @@ -41,41 +42,10 @@ void main(int argc, char* argv[]){ init_simple_malloc(); // init exception table and interrupt (lab3) set_exception_vector_table(); - // show el - unsigned long el; - asm volatile ("mrs %0, CurrentEL" : "=r" (el)); - el = el >> 2; // CurrentEL的值在高两位 - - // print current exception level - uart_puts("Booted! Current EL: "); - uart_send('0' + el); - uart_puts("\n"); // init memory (lab4) - init_reserve_memory(); init_buddy_system(); init_dynamic_allocator(); - - // char* my_array = malloc_page(1); - // char* my_variablwe = (char*)malloc(1023); - // char* my_varieable = (char*)malloc(1023); - // char* wmy_variable = (char*)malloc(1023); - // char* my_vrariable = (char*)malloc(1023); - // char* my_variatble = (char*)malloc(1023); - // free(my_variablwe); - // my_variablwe = (char*)malloc(7642); - // free(my_variablwe); - // my_variablwe = (char*)malloc(1023); - // free(my_variablwe); - // my_variablwe = (char*)malloc(1023); - // free(my_variablwe); - // free(my_variatble); - - // char* my_array = malloc_page(3); - // char* my_array2 = malloc_page(3); - // char* my_array3 = malloc_page(3); - // char* my_array4 = malloc_page(3); - // char* my_array5 = malloc_page(3); - // char* my_array6 = malloc_page(3); + init_thread(); while(1){ char command[MAX_BUFFER]; char c = '\0'; @@ -105,12 +75,12 @@ void main(int argc, char* argv[]){ uart_puts("Hello World!\n"); } else if(strcmp(command, "free") == 0){ + // demo lab4 // free_page(my_array); // free_page(my_array2); // free_page(my_array3); // free_page(my_array4); // free_page(my_array5); - //free_page(my_array6); // my_array = malloc_page(3); // my_array2 = malloc_page(3); @@ -118,6 +88,13 @@ void main(int argc, char* argv[]){ // my_array4 = malloc_page(3); // my_array5 = malloc_page(3); } + else if(strcmp(command, "idle") == 0){ + // demo lab 5-1 + for(int i = 0; i < 5; ++i) { // N should > 2 + creat_thread(foo); + } + idle(); + } else if(strcmp(command, "ls") == 0){ cpio_ls(); } diff --git a/lab_5/shell/page_allocator.c b/lab_5/shell/page_allocator.c index dcebc58ac..77ed2b2b8 100644 --- a/lab_5/shell/page_allocator.c +++ b/lab_5/shell/page_allocator.c @@ -16,34 +16,82 @@ struct Node* list_pop(OrderList* target){ void init_order_list(){ int current_order = MAX_ORDER-1; - int current_page_index = 0; - // assume all pages are available at beginnig, greedly allocate pages in max order size - while(current_order >= 0){ - while((current_page_index+_pow(2, current_order)-1) < AVAILABLE_PAGE_NUM){ - unsigned int allocated_size = _pow(2, current_order)*PAGE_SIZE; - // record the grouped block at The Array - the_array[current_page_index].block_size = _pow(2, current_order); - // malloc a struct node to record the meta data of this block - Node* new_node = simple_malloc(sizeof(Node)); - // push into order list - new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*current_page_index); - new_node->page_index = current_page_index; - list_push_back(new_node, current_order); + int current_page_start = 0; + // advanced: handle cases that some pages are reserved + while((HEAP_START_ADDRESS+(PAGE_SIZE*current_page_start)) < HEAP_END_ADDRESS){ + int continuous_block = 0; + while(continuous_block < _pow(2, MAX_ORDER) && current_page_start+continuous_blockaddress); - uart_puts(" with 0x"); - uart_hex((unsigned int)allocated_size/PAGE_SIZE); - uart_puts(" pages and start at index "); - uart_hex((unsigned int)new_node->page_index); - uart_puts(" in The Array"); - uart_puts("\n"); + unsigned int allocated_size = continuous_block*PAGE_SIZE; + // record the grouped block at The Array, start from 0 thus need to -1 + the_array[current_page_start].block_size = continuous_block-1; + // malloc a struct node to record the meta data of this block + Node* new_node = simple_malloc(sizeof(Node)); + // push into order list + new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*current_page_start); + new_node->page_index = current_page_start; + list_push_back(new_node, order); - current_page_index = current_page_index+_pow(2, current_order)+1; - } - current_order--; + uart_puts("[Init] grouping block at address 0x"); + uart_hex(new_node->address); + uart_puts(" with 0x"); + uart_hex((unsigned int)allocated_size/PAGE_SIZE); + uart_puts(" pages and start at index "); + uart_hex((unsigned int)new_node->page_index); + uart_puts(" in The Array"); + uart_puts("\n"); + current_page_start = current_page_start +continuous_block; + current_page_start++; } + // assume all pages are available at beginnig, greedly allocate pages in max order size + // while(current_order >= 0){ + // while((current_page_index+_pow(2, current_order)-1) < AVAILABLE_PAGE_NUM){ + // unsigned int allocated_size = _pow(2, current_order)*PAGE_SIZE; + // // record the grouped block at The Array + // the_array[current_page_index].block_size = _pow(2, current_order); + // // malloc a struct node to record the meta data of this block + // Node* new_node = simple_malloc(sizeof(Node)); + // // push into order list + // new_node->address = (unsigned char*) HEAP_START_ADDRESS+(PAGE_SIZE*current_page_index); + // new_node->page_index = current_page_index; + // list_push_back(new_node, current_order); + + // uart_puts("[Init] grouping block at address 0x"); + // uart_hex(new_node->address); + // uart_puts(" with 0x"); + // uart_hex((unsigned int)allocated_size/PAGE_SIZE); + // uart_puts(" pages and start at index "); + // uart_hex((unsigned int)new_node->page_index); + // uart_puts(" in The Array"); + // uart_puts("\n"); + + // current_page_index = current_page_index+_pow(2, current_order)+1; + // } + // current_order--; + // } + } void print_order_list(OrderList* list){ @@ -53,7 +101,6 @@ void print_order_list(OrderList* list){ uart_hex(cur->address); uart_puts("\n"); cur = cur->next; - } } @@ -69,6 +116,7 @@ void init_buddy_system(){ order_list[i].chain_length=0; order_list[i].root = NULL; } + init_reserve_memory(); init_order_list(); } @@ -257,11 +305,11 @@ void list_push_back(Node* to_push, int order){ void init_reserve_memory(){ // Spin tables for multicore boot (0x0000 - 0x1000) - memory_reserve(0x0000, 0x1000); + memory_reserve(0x00000000, 0x00001000); // initramfs, allocate 4 pages memory_reserve(0x8000000, 0x8000000 + 0x4000); // kernel image - memory_reserve(&_head, (unsigned int)&_head+((unsigned int)&_end)); + memory_reserve(&_head, &_end); } @@ -275,10 +323,9 @@ void memory_reserve(unsigned int start, unsigned int end){ uart_hex(end); uart_puts("\n"); - int start_index = (start-HEAP_START_ADDRESS)/PAGE_SIZE; + int start_index = (int)((start-HEAP_START_ADDRESS)/PAGE_SIZE); // assume end_index do not exceed limit int end_index = (end-HEAP_START_ADDRESS)/PAGE_SIZE; - for(int i=start_index;iuser_stack = (uint16_t* )malloc(USER_STACK_SIZE); - // new_thread->kernel_stack = (uint16_t* )malloc(KERNEL_STACK_SIZE); - new_thread->x19 = 0x00; - new_thread->x20 = 0x00; - new_thread->x21 = 0x00; - new_thread->x22 = 0x00; - new_thread->x23 = 0x00; - new_thread->x24 = 0x00; - new_thread->x25 = 0x00; - new_thread->x26 = 0x00; - new_thread->x27 = 0x00; - new_thread->x28 = 0x00; - new_thread->fp = (uint64_t)(new_thread->user_stack+USER_STACK_SIZE); // x29: base pointer for local variable in stack - new_thread->lr = 0x00; // x30: store return address - new_thread->sp = new_thread->fp; // stack pointer, varys from function calls - + +int creat_thread(void (*function_ptr)()){ + for(int i=1;iavailable = EXIT; + schedule(); +} + +void schedule(){ + int id = get_id_from_struct_thread(get_current()); + // find next READY thread start from schedule caller id + for(int i=1; i< MAX_THREAD; i++){ + int next = (id+i)%MAX_THREAD; + // skip idle thread(id = 0) + if(next == 0){ + continue; + } + else if(thread_queue.queue[next].available == READY){ + thread_queue.current_routine = next; + context_switch(id, next); + return; + } + } + context_switch(id, 0); + return; +} + + +/* Do context switch. */ +void context_switch(int prev_id, int next_id){ + // uart_puts("[Context switch] Switch from thread id 0x"); + // uart_hex(prev_id); + // uart_puts(" to thread id 0x"); + // uart_hex(next_id); + // uart_puts("\n"); + switch_to(&thread_queue.queue[prev_id], &thread_queue.queue[next_id]); +} + +int get_id_from_struct_thread(struct Thread* cur){ + // find the id of current thread + for(int i=0;i Date: Wed, 26 Jun 2024 03:09:21 +0800 Subject: [PATCH 22/23] lab3 advanced1 but error on resp 3b --- lab_3/bootloader/kernel_uploader.py | 2 - lab_3/shell/include/interrupt.h | 25 +++++- lab_3/shell/interrupt.c | 131 ++++++++++++++++++++++++++-- lab_3/shell/interrupts.S | 4 +- lab_3/shell/main.c | 14 +++ 5 files changed, 161 insertions(+), 15 deletions(-) diff --git a/lab_3/bootloader/kernel_uploader.py b/lab_3/bootloader/kernel_uploader.py index 80ec98938..66e2575a0 100644 --- a/lab_3/bootloader/kernel_uploader.py +++ b/lab_3/bootloader/kernel_uploader.py @@ -68,8 +68,6 @@ def read_line(s): signal.signal(signal.SIGTSTP, tstp_handler) signal.signal(signal.SIGCONT, cont_handler) -print(f"Process ID: {os.getpid()}") - # Run a loop to keep the program alive and responsive to signals while True: received_content = read_line(s) diff --git a/lab_3/shell/include/interrupt.h b/lab_3/shell/include/interrupt.h index 4683019db..470f6847d 100644 --- a/lab_3/shell/include/interrupt.h +++ b/lab_3/shell/include/interrupt.h @@ -1,5 +1,8 @@ #define BASE_INTERRUPT_REGISTER 0x7E00B000 - +#ifndef NULL + #define NULL 0 +#endif +#define CORE0_TIMER_IRQ_CTRL 0x40000040 #define IRQ_BASIC_PENDING ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000200)) #define IRQ_PENDING_1 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000204)) @@ -10,4 +13,22 @@ #define ENABLE_BASIC_IRQS ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000218)) #define DISABLE_IRQS_1 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x0000021C)) #define DISABLE_IRQS_2 ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000220)) -#define DISABLE_BASIC_IRQS ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000224)) \ No newline at end of file +#define DISABLE_BASIC_IRQS ((volatile unsigned int*)(BASE_INTERRUPT_REGISTER+0x00000224)) + +typedef struct Timer{ + unsigned long long trigger_tick; + void* callback_function; + void* argument; + struct Timer* next; +}Timer; + +int print_boot_timer(); +void interrupt_entry(); +unsigned long long get_current_tick(); +void disable_timer_interrupt(); +void enable_timer_interrupt(); +void print_time_out(int delay); +void set_time_out(char* message, unsigned long long seconds); +void core_timer_init(); +void _set_time_out(void (*callback_func)(void *), char* message, unsigned long long delay); +void print_time(); \ No newline at end of file diff --git a/lab_3/shell/interrupt.c b/lab_3/shell/interrupt.c index f2203f3b0..426d49fca 100644 --- a/lab_3/shell/interrupt.c +++ b/lab_3/shell/interrupt.c @@ -1,24 +1,45 @@ #include "include/interrupt.h" #include "include/uart.h" +#include "include/utils.h" #define CORE0_INTERRUPT_SOURCE ((volatile unsigned int*)(0x40000060)) -// print_boot_timer -// cntfrq_el0 = 62500000 + +struct Timer* timer_queue_head = NULL; + int print_boot_timer(){ uart_puts("Interrupt occurs!\n"); - unsigned long long freq, ticks; + unsigned long long freq, ticks, next_tick; asm volatile( "mrs %0, cntfrq_el0;" "mrs %1, cntpct_el0;" : "=r" (freq), "=r" (ticks) ); - // set up the next timer - asm volatile ( - "msr cntp_tval_el0, %0" - : - : "r" (freq * 2) - ); + // set up the next timer - basic + // asm volatile ( + // "msr cntp_tval_el0, %0" + // : + // : "r" (freq * 2) + // ); + + // set up next timer - advanced (with timer queue) + timer_queue_head = timer_queue_head->next; + if(timer_queue_head != NULL){ + next_tick = timer_queue_head->trigger_tick; + uart_hex(next_tick); + uart_puts("\t"); + uart_hex(ticks); + asm volatile ( + "msr cntp_tval_el0, %0" + : + : "r" (next_tick - ticks) + ); + } + else{ + // no more queued core time interrupt, disable the interrupt src + disable_timer_interrupt(); + } unsigned int time = (unsigned int)(ticks/freq); + uart_puts("\n"); uart_hex(time); uart_puts(" seconds elapsed\n"); return 0; @@ -46,3 +67,95 @@ void interrupt_entry(){ } return; } + + +unsigned long long get_current_tick(){ + unsigned long long cntpct_el0 = 0; + asm volatile("mrs %0, cntpct_el0" : "=r"(cntpct_el0)); + return cntpct_el0; +} + +void disable_timer_interrupt(){ + *((volatile unsigned int*)CORE0_TIMER_IRQ_CTRL) = (0x0); +} + +void enable_timer_interrupt(){ + *((volatile unsigned int*)CORE0_TIMER_IRQ_CTRL) = (0x2); +} + +void print_time_out(int delay){ + uart_puts("Timer interrupt occured at 0x"); + uart_hex(delay); + uart_puts(" seconds"); + // remove timer head + timer_queue_head = timer_queue_head->next; +} + +void set_time_out(char* message, unsigned long long seconds){ + _set_time_out(print_time_out, message, seconds); +} + +void core_timer_init(){ + core_timer_enable(); + disable_timer_interrupt(); +} + +void print_time(){ + struct Timer* cur = timer_queue_head; + while(cur != NULL){ + uart_puts(""); + uart_hex(cur->trigger_tick); + uart_puts("\n"); + cur = cur->next; + } +} + +void _set_time_out(void (*callback_func)(void *), char* message, unsigned long long delay){ + Timer *new_timer = (Timer *)simple_malloc(sizeof(Timer)); + unsigned long long freq; + asm volatile("mrs %0, cntfrq_el0" : "=r"(freq)); + unsigned long long delay_tick = delay*(freq); + new_timer->callback_function = callback_func; + new_timer->trigger_tick = delay_tick+get_current_tick(); + new_timer->next = NULL; + + unsigned long long frweq, ticks, next_tick; + asm volatile( + "mrs %0, cntfrq_el0;" + "mrs %1, cntpct_el0;" + : "=r" (frweq), "=r" (ticks) + ); + // set up the next timer - basic + // asm volatile ( + // "msr cntp_tval_el0, %0" + // : + // : "r" (freq * 2) + // ); + + // set up next timer - advanced (with timer queue) + uart_hex(new_timer->trigger_tick); + uart_puts("\t"); + uart_hex(ticks); + uart_puts("\n"); + + + + if(timer_queue_head == NULL || new_timer->trigger_ticktrigger_tick){ + new_timer->next = timer_queue_head; + timer_queue_head = new_timer; + enable_timer_interrupt(); + asm volatile ( + "msr cntp_tval_el0, %0" + : + : "r" (timer_queue_head->trigger_tick) + ); + return; + } + struct Timer *iter = timer_queue_head; + while(iter->next != NULL && iter->next->trigger_tick <= new_timer->trigger_tick){ + iter = iter->next; + } + new_timer->next = iter->next; + iter->next = new_timer; + return; +} \ No newline at end of file diff --git a/lab_3/shell/interrupts.S b/lab_3/shell/interrupts.S index a4e530822..70aa4d74b 100644 --- a/lab_3/shell/interrupts.S +++ b/lab_3/shell/interrupts.S @@ -56,6 +56,8 @@ core_timer_enable: mov x0, 1 msr cntp_ctl_el0, x0 // enable mrs x0, cntfrq_el0 + mrs x1, cntpct_el0 // get current timer + add x0, x1, x0 // next exception = 1 second later msr cntp_tval_el0, x0 // set expired time mov x0, 2 ldr x1, =CORE0_TIMER_IRQ_CTRL @@ -68,5 +70,3 @@ interrupt_handler: bl interrupt_entry load_all eret - - \ No newline at end of file diff --git a/lab_3/shell/main.c b/lab_3/shell/main.c index 43d8e9d68..e825eb25f 100644 --- a/lab_3/shell/main.c +++ b/lab_3/shell/main.c @@ -27,6 +27,7 @@ #include "include/utils.h" #include "include/mbox.h" #include "include/cpio.h" +#include "include/interrupt.h" extern void set_exception_vector_table(); @@ -37,6 +38,8 @@ extern void core_timer_enable(); void main(int argc, char* argv[]){ uart_init(); set_exception_vector_table(); + // default: disabled, need to set interrupt ticks immediately if enable + core_timer_init(); // show el unsigned long el; @@ -49,6 +52,10 @@ void main(int argc, char* argv[]){ uart_puts("\n"); //cpio_exec("user_program.img"); core_timer_enable(); + set_time_out("", 8); + set_time_out("", 3); + set_time_out("", 6); + print_time(); while(1){ char command[MAX_BUFFER]; char c = '\0'; @@ -120,6 +127,13 @@ void main(int argc, char* argv[]){ if(strcmp(arguments[0], "cat") == 0){ cpio_cat(arguments[1]); } + else if(strcmp(arguments[0], "settimeout") == 0){ + //set_time_out(arguments[1], arguments[2]); + // for demo + set_time_out("", 8); + set_time_out("", 3); + set_time_out("", 6); + } } } return; From ca24a7dea20f8d5e7741fc456637e63db24a7492 Mon Sep 17 00:00:00 2001 From: laxiflora Date: Wed, 26 Jun 2024 03:57:39 +0800 Subject: [PATCH 23/23] still failed on resp pi 3 :( --- lab_3/shell/Makefile | 2 +- lab_3/shell/interrupt.c | 27 ++++++--------------------- lab_3/shell/interrupts.S | 2 +- lab_3/shell/main.c | 8 ++++---- 4 files changed, 12 insertions(+), 27 deletions(-) diff --git a/lab_3/shell/Makefile b/lab_3/shell/Makefile index 8591b8f74..2befc4866 100644 --- a/lab_3/shell/Makefile +++ b/lab_3/shell/Makefile @@ -28,7 +28,7 @@ LD = "aarch64-linux-gnu-ld" OBJCPY = "aarch64-linux-gnu-objcopy" SRCS = $(wildcard *.c) OBJS = $(SRCS:.c=.o) -CFLAGS = -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles +CFLAGS = -Wall -O0 -ffreestanding -nostdinc -nostdlib -nostartfiles -w BOOTLOADER_BIN = kernel8.img all: clean kernel8.img diff --git a/lab_3/shell/interrupt.c b/lab_3/shell/interrupt.c index 426d49fca..b9bb4c0d0 100644 --- a/lab_3/shell/interrupt.c +++ b/lab_3/shell/interrupt.c @@ -118,28 +118,8 @@ void _set_time_out(void (*callback_func)(void *), char* message, unsigned long l new_timer->callback_function = callback_func; new_timer->trigger_tick = delay_tick+get_current_tick(); new_timer->next = NULL; - - unsigned long long frweq, ticks, next_tick; - asm volatile( - "mrs %0, cntfrq_el0;" - "mrs %1, cntpct_el0;" - : "=r" (frweq), "=r" (ticks) - ); - // set up the next timer - basic - // asm volatile ( - // "msr cntp_tval_el0, %0" - // : - // : "r" (freq * 2) - // ); - - // set up next timer - advanced (with timer queue) - uart_hex(new_timer->trigger_tick); - uart_puts("\t"); - uart_hex(ticks); uart_puts("\n"); - - - + uart_hex(new_timer->trigger_tick); if(timer_queue_head == NULL || new_timer->trigger_ticktrigger_tick){ new_timer->next = timer_queue_head; timer_queue_head = new_timer; @@ -149,6 +129,11 @@ void _set_time_out(void (*callback_func)(void *), char* message, unsigned long l : : "r" (timer_queue_head->trigger_tick) ); + uart_puts("\nset next interrupt time to 0x"); + uart_hex(timer_queue_head->trigger_tick); + uart_puts(", current tick = 0x"); + uart_hex(get_current_tick()); + uart_puts("\n"); return; } struct Timer *iter = timer_queue_head; diff --git a/lab_3/shell/interrupts.S b/lab_3/shell/interrupts.S index 70aa4d74b..4495af92a 100644 --- a/lab_3/shell/interrupts.S +++ b/lab_3/shell/interrupts.S @@ -59,7 +59,7 @@ core_timer_enable: mrs x1, cntpct_el0 // get current timer add x0, x1, x0 // next exception = 1 second later msr cntp_tval_el0, x0 // set expired time - mov x0, 2 + mov x0, 0 ldr x1, =CORE0_TIMER_IRQ_CTRL str w0, [x1] // unmask timer interrupt ret diff --git a/lab_3/shell/main.c b/lab_3/shell/main.c index e825eb25f..8818c1e11 100644 --- a/lab_3/shell/main.c +++ b/lab_3/shell/main.c @@ -52,10 +52,10 @@ void main(int argc, char* argv[]){ uart_puts("\n"); //cpio_exec("user_program.img"); core_timer_enable(); - set_time_out("", 8); - set_time_out("", 3); - set_time_out("", 6); - print_time(); + set_time_out("", 10); + set_time_out("", 1); + set_time_out("", 7); + while(1){ char command[MAX_BUFFER]; char c = '\0';