Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

working thing

  • Loading branch information...
commit b08728dcc4d8c07d8272a4043576a9e37f9069c0 1 parent 060d198
comex authored
1  .gitignore
View
@@ -0,0 +1 @@
+.*.swp
2  base.ld
View
@@ -1,5 +1,5 @@
SECTIONS {
- . = 0xc076c000;
+ . = 0xc06ed000;
.init : { *(.init) }
/DISCARD/ : { *(.comment); *(.ARM.attributes) }
}
2  kasm.S
View
@@ -1,7 +1,5 @@
.thumb
.syntax unified
-// etc...
-
.section .init
stub:
b mysyscall
46 kcode.c
View
@@ -1,14 +1,54 @@
#include "kinc.h"
struct mysyscall_args {
- uint32_t a;
+ uint32_t mode;
uint32_t b;
uint32_t c;
+ uint32_t d;
};
+static void dump_ttbr(unsigned int ttbr0) {
+ void *descriptor = IOMemoryDescriptor_withPhysicalAddress(ttbr0 & ~0x3f, 4096, kIODirectionIn);
+ void *map = IOMemoryDescriptor_map(descriptor, 0);
+ unsigned int *data = IOMemoryMap_getAddress(map);
+
+
+ delete_object(map);
+ delete_object(descriptor);
+}
+
int mysyscall(void *p, struct mysyscall_args *uap, int32_t *retval)
{
- IOLog("mysyscall: a=%u b=%u c=%u\n", uap->a, uap->b, uap->c);
- *retval = 42;
+ IOLog("Hi mode=%d\n", uap->mode);
+ switch(uap->mode) {
+ case 0: { // get regs
+ unsigned int ttbr0, ttbr1, ttbcr;
+ asm("mrc p15, 0, %0, c2, c0, 0" :"=r"(ttbr0) :);
+ asm("mrc p15, 0, %0, c2, c0, 1" :"=r"(ttbr1) :);
+ asm("mrc p15, 0, %0, c2, c0, 2" :"=r"(ttbcr) :);
+ int error;
+ if(error = copyout(&ttbr0, (user_addr_t) uap->b, sizeof(ttbr0))) return error;
+ if(error = copyout(&ttbr1, (user_addr_t) uap->c, sizeof(ttbr1))) return error;
+ if(error = copyout(&ttbcr, (user_addr_t) uap->d, sizeof(ttbcr))) return error;
+ IOLog("ttbr0=%x ttbr1=%x, ttbcr=%x\n", ttbr0, ttbr1, ttbcr);
+ break;
+ }
+ case 1: { // copy physical data
+ void *descriptor = IOMemoryDescriptor_withPhysicalAddress(uap->b, uap->c, kIODirectionIn);
+ void *map = IOMemoryDescriptor_map(descriptor, 0);
+ unsigned int *data = IOMemoryMap_getAddress(map);
+ //IOLog("data = %x\n", data); break;
+
+ *retval = copyout(data, (user_addr_t) uap->d, uap->c);
+
+ delete_object(map);
+ delete_object(descriptor);
+ break;
+ }
+ default:
+ IOLog("Unknown mode %d\n", uap->mode);
+ break;
+ }
+
return 0;
}
25 kinc.h
View
@@ -3,4 +3,29 @@
// A proper solution is apparently making the generated symbol have the right attribute, but I can't do that without... manually generating an ELF file?
#define LC __attribute__((long_call))
+typedef uint32_t user_addr_t;
+typedef uint32_t vm_size_t;
+
+LC int copyout(const void *kernel_addr, user_addr_t user_addr, vm_size_t nbytes);
+
LC void IOLog(const char *msg, ...) __attribute__((format (printf, 1, 2)));
+
+typedef enum IODirection {
+ kIODirectionNone = 0,
+ kIODirectionIn = 1, // User land 'read'
+ kIODirectionOut = 2, // User land 'write'
+ kIODirectionOutIn = 3
+} IODirection;
+
+LC void *IOMemoryDescriptor_withPhysicalAddress(unsigned long address, unsigned long withLength, IODirection withDirection)
+asm("_ZN18IOMemoryDescriptor19withPhysicalAddressEmm11IODirection");
+
+LC void *IOMemoryDescriptor_map(void *descriptor, unsigned int options)
+asm("_ZN18IOMemoryDescriptor3mapEm");
+
+LC void *IOMemoryMap_getAddress(void *map)
+asm("_ZN11IOMemoryMap10getAddressEv");
+
+static inline void delete_object(void *object) {
+ ((void (***)(void *)) object)[0][1](object);
+}
22 loader.c
View
@@ -2,9 +2,8 @@
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
-#include <sys/syscall.h>
-#include <unistd.h>
#include <stdlib.h>
+#include <unistd.h>
struct proc;
// copied from xnu
@@ -28,22 +27,20 @@ struct sysent { /* system call table */
// end copied
-#define SCRATCH 0xc076c000
+#define SCRATCH 0xc06ed000
#define SYSENT 0xc0255924
// search for 01 00 00 00 0c 00 00 00
-struct sysent my_sysent = { 1, 0, 0, (void *) (SCRATCH | 1), NULL, NULL, _SYSCALL_RET_INT_T, 3 * sizeof(uint32_t) };
+struct sysent my_sysent = { 1, 0, 0, (void *) (SCRATCH | 1), NULL, NULL, _SYSCALL_RET_INT_T, 4 * sizeof(uint32_t) };
-int mysyscall(uint32_t a, uint32_t b, uint32_t c) {
- return syscall(8, a, b, c);
-}
int main() {
assert(sizeof(struct sysent) == 0x18);
int fd = open("kcode.bin", O_RDONLY);
assert(fd > 0);
off_t size = lseek(fd, 0, SEEK_END);
+ assert(size > 0);
lseek(fd, 0, SEEK_SET);
char *buf = malloc(size);
assert(read(fd, buf, size) == size);
@@ -51,6 +48,13 @@ int main() {
assert(k > 0);
assert(pwrite(k, buf, size, SCRATCH) == size);
assert(pwrite(k, &my_sysent, sizeof(struct sysent), SYSENT + 8 * sizeof(struct sysent)) == sizeof(struct sysent));
- printf("ok I wrote it\n"); sleep(3);
- printf("%d\n", mysyscall(0, 0, 0));
+ close(k);
+
+ char *buf2 = malloc(size);
+ int l = open("/dev/kmem", O_RDONLY);
+ assert(l > 0);
+ assert(pread(l, buf2, size, SCRATCH) == size);
+ assert(!memcmp(buf, buf2, size));
+ close(l);
+ return 0;
}
5 make.py
View
@@ -3,6 +3,7 @@
sources = ['kcode.c', 'kasm.S']
def build():
run('gcc-4.2', '-o', 'loader', 'loader.c', '-arch', 'armv6', '-isysroot', '/var/sdk')
+ run('gcc-4.2', '-std=gnu99', '-o', 'stuff', 'stuff.c', '-arch', 'armv6', '-isysroot', '/var/sdk')
#run('ldid', '-S', 'loader')
run('python', 'nm.py')
@@ -12,7 +13,9 @@ def build():
for source in sources:
run(GCC, '-c', source)
- run(GCC, '-o', 'kcode.elf', [source[:source.find('.')]+'.o' for source in sources], '-nostdlib', '-nodefaultlibs', '-lgcc', '-T', 'nm.ld')
+ run(GCC, '-std=gnu99', '-o', 'kcode.elf', [source[:source.find('.')]+'.o' for source in sources], '-nostdlib', '-nodefaultlibs', '-lgcc', '-T', 'nm.ld')
+
+ run(OBJCOPY, '-O', 'binary', 'kcode.elf', 'kcode.bin')
def clean():
autoclean()
80 stuff.c
View
@@ -0,0 +1,80 @@
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+int get_regs(uint32_t *ttbr0, uint32_t *ttbr1, uint32_t *ttbcr) {
+ return syscall(8, 0, ttbr0, ttbr1, ttbcr);
+}
+
+int copy_phys(uint32_t paddr, uint32_t size, void *buf) {
+ return syscall(8, 1, paddr, size, buf);
+}
+
+static void dump_pagetable(uint32_t ttbr, uint32_t baseaddr, uint32_t size) {
+ unsigned int *data = malloc(size);
+ assert(!copy_phys(ttbr & ~0x3f, size, data));
+ for(int i = 0; i < (size / 4); i++) {
+ unsigned int l1desc = data[i];
+ if((l1desc & 3) == 0) continue; // fault
+ printf("%08x: ", baseaddr + i * 0x100000);
+ switch(l1desc & 3) {
+ case 1: {
+ printf("coarse page table base=%x P=%d domain=%d\n", l1desc & ~0x3ff, (l1desc & (1 << 9)) ? 1 : 0, (l1desc >> 5) & 0xf);
+ unsigned int data2[256];
+ memset(data2, 0xff, sizeof(data2));
+ assert(!copy_phys(l1desc & ~0x3ff, sizeof(data2), data2));
+ for(int j = 0; j < 256; j++) {
+ unsigned int l2desc = data2[i];
+ if((l2desc & 3) == 0) continue; // fault
+ printf(" %08x: ", baseaddr + (i * 0x100000) + (j * 0x1000));
+ switch(l2desc & 3) {
+ case 1:
+ printf("large base=%x TEX=%d AP0=%d AP1=%d AP2=%d AP3=%d C=%d B=%d\n", l2desc & 0xffff0000, (l2desc >> 12) & 7, (l2desc >> 4) & 3, (l2desc >> 6) & 3, (l2desc >> 8) & 3, (l2desc >> 10) & 3, (l2desc >> 3) & 1, (l2desc >> 2) & 1);
+ break;
+ case 2:
+ printf("large base=%x AP0=%d AP1=%d AP2=%d AP3=%d C=%d B=%d\n", l2desc & 0xfffff000, (l2desc >> 4) & 3, (l2desc >> 6) & 3, (l2desc >> 8) & 3, (l2desc >> 10) & 3, (l2desc >> 3) & 1, (l2desc >> 2) & 1);
+ break;
+ case 3:
+ printf("reserved (probably; extended small page)\n");
+ break;
+ }
+ }
+ } break;
+ case 2:
+ if(l1desc & (1 << 18)) {
+ printf("supersection base=%x extbase=%x NS=%d nG=%d TEX=%x AP=%x extbase2=%x XN=%x C=%x B=%x\n",
+ l1desc & 0xff000000,
+ (l1desc >> 20) & 0xf,
+ (l1desc >> 19) ? 1 : 0,
+ (l1desc >> 17) ? 1 : 0,
+ (l1desc >> 12) & 7,
+ ((l1desc >> 15) ? 4 : 0) | ((l1desc >> 10) & 3),
+ (l1desc >> 5) & 0xf,
+ (l1desc >> 4) ? 1 : 0,
+ (l1desc >> 3) ? 1 : 0,
+ (l1desc >> 2) ? 1 : 0);
+
+ } else {
+ printf("section!!\n");
+ }
+ break;
+ case 3:
+ printf("reserved\n");
+ break;
+ }
+ }
+}
+
+int main() {
+ uint32_t ttbr0, ttbr1, ttbcr;
+ ttbr0 = ttbr1 = ttbcr = 0;
+ printf("%x\n", get_regs(&ttbr0, &ttbr1, &ttbcr));
+ printf("ttbr0=%x ttbr1=%x ttbcr=%x\n", ttbr0, ttbr1, ttbcr);
+
+ //dump_pagetable(ttbr0, 0, 4096);
+ dump_pagetable(ttbr1, 0, 16384);
+}
Please sign in to comment.
Something went wrong with that request. Please try again.