aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--TODOs4
-rw-r--r--cpsr.h39
-rw-r--r--kernel.c52
-rw-r--r--pipe_image.c64
5 files changed, 122 insertions, 43 deletions
diff --git a/Makefile b/Makefile
index 2ef48d5..bb8d06e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CFLAGS=-mcpu=cortex-a7 -ffreestanding -std=gnu99 -Wall -Wextra -I.
+CFLAGS=-mcpu=cortex-a7 -ffreestanding -std=gnu11 -Wall -Wextra -I.
ELFFLAGS=-ffreestanding -O2 -nostdlib -lgcc -I.
@@ -45,10 +45,10 @@ qemu-elf : kernel.elf
qemu-system-arm -m 256 -M raspi2 -serial stdio -kernel $^
qemu-bin : loader.elf kernel7.img pipe_image
- ./pipe_image && qemu-system-arm -m 256 -M raspi2 -serial stdio -kernel $<
+ ./pipe_image --stdout | qemu-system-arm -m 256 -M raspi2 -serial stdio -kernel $<
run-on-rpi : kernel7.img pipe_image
- ./pipe_image | socat FILE:/dev/ttyUSB0,b115200,raw -
+ ./pipe_image --stdout | socat FILE:/dev/ttyUSB0,b115200,raw -
sleep 1
screen /dev/ttyUSB0 115200,cs8,-parenb,-cstopb,-hupcl
diff --git a/TODOs b/TODOs
index dcc08d5..5b78455 100644
--- a/TODOs
+++ b/TODOs
@@ -17,4 +17,6 @@
* Start doing this on hardware already... (Hey, whole making of a bootloader was with this in mind!)
-* Find a way to pipe kernel through uart (I'm afraid `./pipe_image | screen ...` might not work) \ No newline at end of file
+* Fix piping with pipe_image
+
+* write some procedures for dumping registers and other stuff (for use in debugging) \ No newline at end of file
diff --git a/cpsr.h b/cpsr.h
new file mode 100644
index 0000000..327bdf0
--- /dev/null
+++ b/cpsr.h
@@ -0,0 +1,39 @@
+#include <stdint.h>
+
+enum execution_mode {
+ MODE_USER = 0x10,
+ MODE_FIQ = 0x11,
+ MODE_IRQ = 0x12,
+ MODE_SUPERVISOR = 0x13,
+ MODE_MONITOR = 0x16,
+ MODE_ABORT = 0x17,
+ MODE_HYPERVISOR = 0x1a,
+ MODE_UNDEFINED = 0x1b,
+ MODE_SYSTEM = 0x1f,
+};
+
+inline static uint32_t read_CPSR(void)
+{
+ uint32_t CPSR;
+ // get content of current program status register
+ asm("mrs %0, cpsr" : "=r" (CPSR) ::);
+
+ return CPSR;
+}
+
+inline static enum execution_mode read_processor_mode(void)
+{
+ /* lowest 5 bits indicate processor mode */
+ return read_CPSR() & 0x1f;
+}
+
+inline static void set_system_mode(void)
+{
+ uint32_t CPSR = read_CPSR();
+
+ CPSR = (CPSR >> 5) << 5;
+
+ CPSR |= MODE_SYSTEM;
+
+ asm("msr cpsr, %0" :: "r" (CPSR) : "memory");
+}
diff --git a/kernel.c b/kernel.c
index 3898cf2..dbc45e4 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1,4 +1,5 @@
-#include <uart.h>
+#include "uart.h"
+#include "cpsr.h"
void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags)
{
@@ -20,16 +21,16 @@ void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags)
// uart_puts("Hello, kernel World!\r\n");
char *paging;
-
- switch(ID_MMFR0 & 0xf) /* lowest 4 bits indicate VMSA support */ {
- case 0 : paging = "no paging\n\r"; break;
- case 1 : paging = "implementation defined paging\n\r\r\n"; break;
- case 2 : paging = "VMSAv6, with cache and TLB type registers\n\r"; break;
- case 3 : paging = "VMSAv7, with support for remapping and access flag\n\r"; break;
- case 4 : paging = "VMSAv7 with PXN bit supported\n\r"; break;
- case 5 : paging = "VMSAv7, PXN and long format descriptors. EPAE is supported.\n\r"; break;
- default : paging = "?_? unknown paging ?_?\n\r";
- }
+ switch(ID_MMFR0 & 0xf) /* lowest 4 bits indicate VMSA support */
+ {
+ case 0 : paging = "no paging\n\r"; break;
+ case 1 : paging = "implementation defined paging\n\r"; break;
+ case 2 : paging = "VMSAv6, with cache and TLB type registers\n\r"; break;
+ case 3 : paging = "VMSAv7, with support for remapping and access flag\n\r"; break;
+ case 4 : paging = "VMSAv7 with PXN bit supported\n\r"; break;
+ case 5 : paging = "VMSAv7, PXN and long format descriptors. EPAE is supported.\n\r"; break;
+ default : paging = "?_? unknown paging ?_?\n\r";
+ }
uart_puts(paging);
@@ -39,19 +40,22 @@ void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags)
asm("mrs %0, cpsr" : "=r" (CPSR) :: "memory");
char *mode;
-
- switch(CPSR & 0x1f) /* lowest 5 bits indicate processor mode */ {
- case 0x10 : mode = "User (PL0)\r\n"; break;
- case 0x11 : mode = "FIQ (PL1)\r\n"; break;
- case 0x12 : mode = "IRQ (PL1)\r\n"; break;
- case 0x13 : mode = "Supervisor (PL1)\r\n"; break;
- case 0x16 : mode = "Monitor (PL1)\r\n"; break;
- case 0x17 : mode = "Abort (PL1)\r\n"; break;
- case 0x1a : mode = "Hyp (PL2)\r\n"; break;
- case 0x1b : mode = "Undefined (PL1)\r\n"; break;
- case 0x1f : mode = "System (PL1)\r\n"; break;
- default : mode = "Unknown mode\r\n"; break;
- }
+
+ switch(read_processor_mode())
+ {
+ case 0x10 : mode = "User (PL0)\r\n"; break;
+ case 0x11 : mode = "FIQ (PL1)\r\n"; break;
+ case 0x12 : mode = "IRQ (PL1)\r\n"; break;
+ case 0x13 : mode = "Supervisor (PL1)\r\n"; break;
+ case 0x16 : mode = "Monitor (PL1)\r\n"; break;
+ case 0x17 : mode = "Abort (PL1)\r\n"; break;
+ case 0x1a : mode = "Hyp (PL2)\r\n"; break;
+ case 0x1b : mode = "Undefined (PL1)\r\n"; break;
+ case 0x1f : mode = "System (PL1)\r\n"; break;
+ default : mode = "Unknown mode\r\n"; break;
+ }
+
+ set_system_mode();
uart_puts(mode);
diff --git a/pipe_image.c b/pipe_image.c
index b52cec2..03d2c8f 100644
--- a/pipe_image.c
+++ b/pipe_image.c
@@ -6,18 +6,32 @@
#include "lib/rs232/rs232.h"
#define ANSI_FG_RED "\033[0;31m"
+#define ANSI_FG_DEFAULT "\033[0;39m"
-/* This program pipes it's argument file to stdout prepending it */
-/* with it's size (4 bytes, little endian). It is intended to be used */
-/* with our bootloader (i.e. by piping kernel image to UART). */
+/* This program pipes it's argument file to /dev/ttyUSB0 or stdout */
+/* prepending it with it's size (4 bytes, little endian). */
+/* It is intended to be used with our bootloader. */
-int main(int argc, char **argv) {
- char *image_file_name = argc > 1 ? argv[1] : "kernel7.img";
+int main(int argc, const char **argv) {
+ const char *image_file_name = "kernel7.img";
+ _Bool stdout_instead_of_uart = 0;
+
+ if (argc > 1)
+ if (!strcmp(argv[1], "--stdout"))
+ {
+ stdout_instead_of_uart = 1;
+ argc--;
+ argv++;
+ }
+
+ if (argc > 1)
+ image_file_name = argv[1];
FILE *image_file_handle = fopen(image_file_name, "r");
if (!image_file_handle)
- err(-1, "couldn't open" ANSI_FG_RED "%s", image_file_name);
+ err(-1, "couldn't open" ANSI_FG_RED "%s" ANSI_FG_DEFAULT,
+ image_file_name);
if (fseek(image_file_handle, 0, SEEK_END))
err(-1, "error navigating through file");
@@ -33,16 +47,25 @@ int main(int argc, char **argv) {
err(-1, "error navigating through file");
//init comport
- int comport=16;
-
- if(RS232_OpenComport(comport,115200,"8N1",0)==1)
- err(1,"Error opening comport");
+ const int comport=16;
+ if (!stdout_instead_of_uart)
+ if (RS232_OpenComport(comport, 115200, "8N1", 0) == 1)
+ err(-1, "Error opening comport");
uint32_t image_size_le = htole32(image_size);
- if (RS232_SendBuf(comport,(unsigned char*)&image_size_le,4) == 1)
- err(1, "error writing number to serial");
+ if (stdout_instead_of_uart)
+ {
+ if (fwrite((unsigned char*) &image_size_le, 4, 1, stdout) != 1)
+ err(-1, "error writing number to stdout");
+ }
+ else
+ {
+ if (RS232_SendBuf(comport, (unsigned char*) &image_size_le, 4)
+ == 1)
+ err(-1, "error writing number to serial");
+ }
ssize_t bytes_left = image_size;
@@ -54,10 +77,21 @@ int main(int argc, char **argv) {
< 1)
err(-1, "error reading the file");
- if (RS232_SendBuf(comport,buf,bytes_read) == 1)
- err(1, "error writing to serial");
+ if (stdout_instead_of_uart)
+ {
+ if (fwrite((unsigned char*) buf, bytes_read, 1, stdout) != 1)
+ err(-1, "error writing to stdout");
+ }
+ else
+ {
+ if (RS232_SendBuf(comport, buf, bytes_read) == 1)
+ err(-1, "error writing to serial");
+ }
bytes_left -= bytes_read;
}
- RS232_CloseComport(comport);
+ if (!stdout_instead_of_uart)
+ RS232_CloseComport(comport);
+
+ return 0;
}