]> Chaos Git - corbenik/corbenik.git/commitdiff
Misc stuff.
authorchaoskagami <chaos.kagami@gmail.com>
Thu, 2 Jun 2016 08:12:38 +0000 (04:12 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Thu, 2 Jun 2016 08:12:38 +0000 (04:12 -0400)
 * More work prepping for bytecode.
 * Improve decidedly shitty putc buffer to just directly render. Old behavior kept around via -DBUFFER=1.
   * I need to reimplement scrollback still

README.md
doc/todo.md
source/linker.c [deleted file]
source/patch/aadowngrade.c
source/patch/prot.c
source/patch/sig.c
source/patch/svc.c
source/patcher.c
source/std/draw.c

index d2bd42f57f8c4877090686f6493a5b6e39971cd8..24c2032cf1e47ab166188fa2ac11272b96979d56 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,31 +1,33 @@
 Corbenik
 ==============================
 
-## Oh god yet another rebrand of--
+This is (yet another) CFW for the 3DS. Unlike other CFWs, this was mostly written from scratch and for fun. I'm a control freak, and this carries quite a bit of my mindset being a LFS/Gentoo user.
+
+Some parts are inherited from other CFWs - e.g. the firmware loading code in src/firm is mostly based on Cakes, and the signature patch bytecode is roughly based on the implementation in Luma3DS.
 
-No. Definitely not.
+Out of the bunch, corbenik is most similar to cakes of the bunch, in that it uses external patches. Unlike cakes, patches consist of a headered bytecode file. See `doc/bytecode.md`, `host/bytecode_asm.py`  and `patch/*` for more on this.
 
-This is (yet another) CFW for the 3DS. Unlike other CFWs, this was mostly written from scratch and for fun. I'm a control freak, and this carries quite a bit of my mindset, and some OSDev and self-done RE with it.
+## Oh god yet another rebrand of--
 
-Some parts are inherited from other CFWs - e.g. the firmware loading code in src/firm is mostly based on Cakes, and sigpatch/firmprot/svcbackdoor were loosely based on Luma3DS's patches.
+No. This is >75% original code. If you notice, there's a large amount of history because I didn't just dump the code on github; it's been in a repo all along while I worked on it and before it was made public.
 
-The *plan* at least is to be most similar to Cakes out of the bunch. That is, it will use external patches from the SD card's filesystem.
+I also am not claiming to have written everything. See `doc/credits.md`.
 
-Unlike cakes, patches will be some form of program, be it bytecode, a scripting language or dynamically loaded binaries. This is not yet implemented due to technical problems, but IS on the roadmap to get done as soon as I figure out *why* it isn't working. This code is located in a branch offline, due to the fact that it doesn't work.
+It shares close to zero of the actual architecture with other CFWs, only trivially implemented parts that look the same no matter who coded them.
 
 ## Rationale
 
-I was initially going to make dynamic cakes, but I quickly realized a fatal flaw in any "patch" format: what you can do from a patch is limited to what the parser handles. This exact problem is why sempatches are used sometimes instead of classic diffs on the LKML, and it isn't a problem that will be solved without code. In my opinion, the best way to fix it is to simply externalize patches.
+I was initially going to make dynamic cakes, but I quickly realized a fatal flaw in any "patch" format: what you can do from a patch is limited to what the parser handles. This exact problem is why sempatches are used sometimes instead of classic diffs on the LKML, and it isn't a problem that will be solved without code. In my opinion, the best way to fix it is to simply externalize patches as programs. I also had a number of mad science experiments which would be very hard to perform in the context of ReiNAND based firmwares, and Cakes wouldn't make it easy either.
 
 ## Comparison
 
-If you want to know how Corbenik sizes up to other CFWs as of NOW - see `doc/features.md`. I don't intend to sugarcoat - Corbenik is under development and is incomplete. There will be no stable release until a number of common features are implemented, and patches have been externalized.
+If you want to know how Corbenik sizes up to other CFWs as of NOW - see `doc/features.md`. I don't intend to sugarcoat - Corbenik is under development and is incomplete. There will be no stable release until a number of common features are implemented, such as emunand.
 
-That said, feedback is welcome, but don't report anything obvious. Chances are I know, since Corbenik is my day-to-day CFW now.
+That said, feedback is welcome, but don't report anything obvious. Chances are I know, since Corbenik is my day-to-day CFW now, and I'll run into the same bugs as you.
 
 For compilation instructions, see `doc/compiling.md`.
 
-Unless otherwise noted, everything original in this repo can be used under the terms of the GNU GPLv2 or later. This includes situations where there's no copyright header within a source file. I get lazy with those; assume everything can be used under the GPL, or files were from software licensed GPLv2 or later (and thus are upgraded.) No source files within this repo bear questionable licenses.
+Unless otherwise noted, everything original in this repo can be used under the terms of the GNU GPLv3 or later. This includes situations where there's no copyright header within a source file. I get lazy with those; assume everything can be used under the GPL, or files were from software licensed GPLv2 or later (and thus are upgraded.) No source files within this repo bear questionable licenses.
 
 ## Quote of the Day
 
index dbb2738ca26019d42ed319a9b6a02c67e874a37a..33c303648341279d684078f70d994808fcfc5308 100644 (file)
@@ -4,6 +4,7 @@ Next
  * Make config file for corbenik plaintext. Nobody likes binary configs. They suck. Massively. Especially when you fuck up a setting and need to change it on something that isn't a 3ds.
  * In place firmware loading/patching.
  * Weird hack central - Developer 11.4 leaked. Allow injecting debug module? Ehehehehe. No clue what the point of this would be, but hey, it'd be FUCKING cool, man.
+ * Optimize the code in svc. It's slow, because it checks the filesystem for 0xff files that don't exist. It should list the dir instead.
 
 Shortterm
 -------------
diff --git a/source/linker.c b/source/linker.c
deleted file mode 100644 (file)
index 46a7dd7..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "common.h"
-#include "firm/fcram.h"
-#include "firm/firm.h"
-
-// Yes, this is EXACTLY what it looks like. We dynamically link and
-// load patches as binaries; they use functions from corbenik to do
-// the work, and therefore must have a function table in them.
-
-// See vco/template for how this magic works.
-
-// This ensures relatively small patches while also having incredible
-// flexibility unlike a 'patch format'.
-
-extern exefs_h* firm_p9_exefs;
-exefs_h*
-get_firm_proc9_exefs()
-{
-    return firm_p9_exefs;
-}
-
-extern exefs_h* twl_firm_p9_exefs;
-exefs_h*
-get_twl_proc9_exefs()
-{
-    return twl_firm_p9_exefs;
-}
-
-extern exefs_h* agb_firm_p9_exefs;
-exefs_h*
-get_agb_proc9_exefs()
-{
-    return agb_firm_p9_exefs;
-}
-
-int
-execp(char* path)
-{
-    int basename = 0;
-    for (basename = strlen(path); basename > 0; basename--)
-        if (path[basename] == '/')
-            break;
-    basename++;
-
-    fprintf(stderr, "Exec: %s\n", &path[basename]);
-
-    struct system_patch patch;
-
-    // Load patch from path.
-    FILE* f = fopen(path, "r");
-    fread(&patch, 1, sizeof(patch), f);
-
-    fprintf(stderr, "  [h]");
-
-    fread((uint8_t*)FCRAM_PATCHBIN_EXEC_LOC, 1, patch.patch_size, f);
-
-    fprintf(stderr, "[x]");
-
-    fclose(f);
-
-    fprintf(stderr, "[b]\n");
-
-    int (*patch_loc)() = (void*)FCRAM_PATCHBIN_EXEC_LOC;
-
-    int ret = (*patch_loc)();
-
-    fprintf(stderr, "  Exit: %d\n", ret);
-
-    return ret;
-}
index 64132a95f0e968ed6694d6b97206a6f28031c1d9..e4d9e41be8d5816540af1b7e096e64ab73f51339 100644 (file)
@@ -7,10 +7,10 @@
    set 1, 0xE0
  */
 
+extern exefs_h* firm_p9_exefs;
+
 PATCH(aadowngrade)
 {
-       exefs_h* firm_p9_exefs = get_firm_proc9_exefs();
-
     uint8_t* firm_mem = (uint8_t*)firm_p9_exefs + sizeof(exefs_h) +
                         firm_p9_exefs->fileHeaders[0].offset;
     uint32_t size = firm_p9_exefs->fileHeaders[0].size;
index ec2c2f16017ad06cf77d626128e2880f186ad322..544c7f9b9319f3f7feec1fdc650546a69ea0a548 100644 (file)
   set 4, 0x00, 0x20, 0xC0, 0x46
  */
 
+extern exefs_h* firm_p9_exefs;
+
 PATCH(firmprot)
 {
-       exefs_h* firm_p9_exefs = get_firm_proc9_exefs();
-
     uint8_t* firm_mem = (uint8_t*)firm_p9_exefs + sizeof(exefs_h) +
                         firm_p9_exefs->fileHeaders[0].offset;
     uint32_t size = firm_p9_exefs->fileHeaders[0].size;
index b91e9ff4b838f9912bd20a73832920ccc4807abd..66bbe7e2bac1880dc40915f3527ddf58828d722e 100644 (file)
   set  4, 0x00, 0x20, 0x70, 0x47
  */
 
+extern exefs_h* firm_p9_exefs;
+
 PATCH(signatures)
 {
-       exefs_h* firm_p9_exefs = get_firm_proc9_exefs();
 
     // Look for signature checks
 
index ff9deed40fce78e33cb52010a10503726ce45706..e3b01d833a4c531d4728bf0dbd1f6afda0ec6963 100644 (file)
@@ -43,49 +43,54 @@ PATCH(services)
 
     char str[] = PATH_SERVICES "/00.bin";
     char* at = str + (strlen(str) - 6);
-    for (uint32_t i = 0; i <= 0xff; i++) {
-        // Get string for svc.
-        at[0] = ("0123456789abcdef")[((i >> 4) & 0xf)];
-               // This is just hexdump. Nothing complicated.
-        at[1] = ("0123456789abcdef")[(i & 0xf)];
+       // FIXME - This is really slow. Some way to optimize it?
+    for (uint32_t i = 0; i <= 0xf; i++) {
+           // Get string for svc.
+           at[0] = ("0123456789abcdef")[i];
 
-        FILE* data = fopen(str, "r");
-        if (!data) {
-            continue; // No file for svc. Move on.
-        }
+               for (uint32_t j = 0; j < 0xf; j++) {
+                       // This is just hexdump. Nothing complicated.
+               at[1] = ("0123456789abcdef")[j];
 
-        // Refuse to replace non-NULL services unless the user says to.
-        if (svcTable[i] && !config.options[OPTION_REPLACE_ALLOCATED_SVC]) {
-            fclose(data);
-            fprintf(stderr, "Svc: %x non-null, moving on\n", i);
-            continue;
-        }
+               FILE* data = fopen(str, "r");
+               if (!data)
+                   continue; // No file for svc. Move on.
 
-        uint32_t size = fsize(data);
-        uint8_t* read_to = (void*)FCRAM_JUNK_LOCATION;
+                       uint32_t svc = (i << 4) & j;
 
-        fprintf(stderr, "Svc: %s, %d bytes\n", at, size);
+               // Refuse to replace non-NULL services unless the user says to.
+               if (svcTable[svc] && !config.options[OPTION_REPLACE_ALLOCATED_SVC]) {
+                   fclose(data);
+                   fprintf(stderr, "Svc: %x non-null, moving on\n", i);
+                   continue;
+               }
 
-        fread(read_to, 1, size, data);
+           uint32_t size = fsize(data);
+               uint8_t* read_to = (void*)FCRAM_JUNK_LOCATION;
 
-        fclose(data);
+               fprintf(stderr, "Svc: %s, %d bytes\n", at, size);
 
-        if (!freeSpace) {
-            for (freeSpace = exceptionsPage; *freeSpace != 0xFFFFFFFF;
-                 freeSpace++)
-                ;
-        }
+               fread(read_to, 1, size, data);
 
-        fprintf(stderr, "Svc: Copy code to %x\n", (uint32_t)freeSpace);
+               fclose(data);
 
-        memcpy(freeSpace, read_to, size);
-        svcTable[i] =
-            0xFFFF0000 + ((uint8_t*)freeSpace - (uint8_t*)exceptionsPage);
+               if (!freeSpace) {
+               for (freeSpace = exceptionsPage; *freeSpace != 0xFFFFFFFF;
+                    freeSpace++)
+                   ;
+               }
 
-        freeSpace +=
-            size; // We keep track of this because there's more than 7B free.
+                       fprintf(stderr, "Svc: Copy code to %x\n", (uint32_t)freeSpace);
 
-        fprintf(stderr, "Svc: entry set as %x\n", svcTable[0x7B]);
+               memcpy(freeSpace, read_to, size);
+               svcTable[svc] =
+               0xFFFF0000 + ((uint8_t*)freeSpace - (uint8_t*)exceptionsPage);
+
+               freeSpace +=
+               size; // We keep track of this because there's more than 7B free.
+
+               fprintf(stderr, "Svc: entry set as %x\n", svcTable[svc]);
+               }
     }
 
     return 0;
index 720194d7acc3475ed4aa15208697ca038ec08d67..a93332e026f29fe24746e15adb07776dfd0c0ae0 100644 (file)
@@ -8,7 +8,6 @@
 // TODO - Basically all this needs to move to patcher programs.
 
 uint32_t wait_key();
-int execp(char* path);
 
 extern int patch_signatures();
 extern int patch_firmprot();
index 491910a9287a9f7bc7edd7b2c7fc9813bdca81c1..4828f235f91fcdc94672105770e3836ad243a718 100644 (file)
 static unsigned int top_cursor_x = 0, top_cursor_y = 0;
 static unsigned int bottom_cursor_x = 0, bottom_cursor_y = 0;
 
+#ifdef BUFFER
 static char text_buffer_top[TEXT_TOP_HEIGHT * TEXT_TOP_WIDTH + 1];
 static char text_buffer_bottom[TEXT_BOTTOM_HEIGHT * TEXT_BOTTOM_WIDTH + 1];
 
 static char color_buffer_top[TEXT_TOP_HEIGHT * TEXT_TOP_WIDTH + 1];
 static char color_buffer_bottom[TEXT_BOTTOM_HEIGHT * TEXT_BOTTOM_WIDTH + 1];
+#endif
 
 static uint32_t colors[16] = {
     0x000000, // Black
@@ -52,6 +54,7 @@ clear_disp(uint8_t* screen)
     }
 }
 
+#ifdef BUFFER
 void
 clear_text(uint8_t* screen)
 {
@@ -72,12 +75,15 @@ clear_text(uint8_t* screen)
         }
     }
 }
+#endif
 
 void
 clear_screen(uint8_t* screen)
 {
     clear_disp(screen);
+#ifdef BUFFER
     clear_text(screen);
+#endif
 }
 
 void
@@ -164,24 +170,35 @@ putc(void* buf, const int c)
         _UNUSED unsigned int height = 0;
         unsigned int* cursor_x = NULL;
         unsigned int* cursor_y = NULL;
+#ifdef BUFFER
         char* colorbuf = NULL;
         char* strbuf = NULL;
-
+#else
+        uint8_t* screen = NULL;
+#endif
         unsigned char* color = NULL;
 
         if (buf == TOP_SCREEN) {
             width = TEXT_TOP_WIDTH;
             height = TEXT_TOP_HEIGHT;
+#ifdef BUFFER
             colorbuf = color_buffer_top;
             strbuf = text_buffer_top;
+#else
+            screen = framebuffers->top_left;
+#endif
             cursor_x = &top_cursor_x;
             cursor_y = &top_cursor_y;
             color = &color_top;
         } else if (buf == BOTTOM_SCREEN) {
             width = TEXT_BOTTOM_WIDTH;
             height = TEXT_BOTTOM_HEIGHT;
+#ifdef BUFFER
             colorbuf = color_buffer_bottom;
             strbuf = text_buffer_bottom;
+#else
+            screen = framebuffers->bottom;
+#endif
             cursor_x = &bottom_cursor_x;
             cursor_y = &bottom_cursor_y;
             color = &color_bottom;
@@ -193,6 +210,7 @@ putc(void* buf, const int c)
         }
 
         while (cursor_y[0] >= height) {
+#ifdef BUFFER
             // Scroll.
             for (unsigned int y = 0; y < height - 1; y++) {
                 memset(&strbuf[y * width], 0, width);
@@ -204,21 +222,33 @@ putc(void* buf, const int c)
             memset(&strbuf[(height - 1) * width], 0, width);
             memset(&colorbuf[(height - 1) * width], 0, width);
 
-            cursor_y[0]--;
-
             clear_disp(buf); // Clear screen.
+#else
+                       clear_disp(buf);
+                       cursor_x[0] = 0;
+                       cursor_y[0] = 0;
+/*                     uint32_t col = SCREEN_TOP_HEIGHT * SCREEN_DEPTH;
+                       uint32_t one_c = 8 * SCREEN_DEPTH;
+                       for (unsigned int x = 0; x < width * 8; x++) {
+                               memmove(&screen[x * col + one_c], &screen[x * col + one_c], col - one_c);
+                       } */
+#endif
+            cursor_y[0]--;
         }
 
         switch (c) {
             case '\n':
+#ifdef BUFFER
                 strbuf[cursor_y[0] * width + cursor_x[0]] = 0;
                 colorbuf[cursor_y[0] * width + cursor_x[0]] = 0;
+#endif
                 cursor_y[0]++;
             // Fall through intentional.
             case '\r':
                 cursor_x[0] = 0; // Reset to beginning of line.
                 break;
             default:
+#ifdef BUFFER
                 strbuf[cursor_y[0] * width + cursor_x[0]] = c;
                 colorbuf[cursor_y[0] * width + cursor_x[0]] = *color;
 
@@ -228,6 +258,10 @@ putc(void* buf, const int c)
                     colorbuf[cursor_y[0] * width + cursor_x[0] + 1] = 0;
                 }
 
+#else
+                               draw_character(screen, c, cursor_x[0], cursor_y[0], colors[(*color >> 4) & 0xF], colors[*color & 0xF]);
+#endif
+
                 cursor_x[0]++;
 
                 break;
@@ -334,6 +368,7 @@ void
 fflush(void* channel)
 {
     if (channel == TOP_SCREEN) {
+#ifdef BUFFER
         if (kill_output)
             return;
 
@@ -350,7 +385,9 @@ fflush(void* channel)
                                color_bg);
             }
         }
+#endif
     } else if (channel == BOTTOM_SCREEN) {
+#ifdef BUFFER
         if (kill_output)
             return;
 
@@ -368,6 +405,7 @@ fflush(void* channel)
                                color_bg);
             }
         }
+#endif
     } else {
         f_sync(&(((FILE*)channel)->handle)); // Sync to disk.
     }