diff --git a/kernel_module/user/README.md b/kernel_module/user/README.md index 637a35a..36ffb34 100644 --- a/kernel_module/user/README.md +++ b/kernel_module/user/README.md @@ -8,5 +8,12 @@ C programs require cross compiling, but give us more control over system calls. These programs can also be compiled and used on host. -1. [myinsmod](myinsmod.c) -1. [myrmmod](myrmmod.c) +1. Standalone + 1. [myinsmod](myinsmod.c) + 1. [myrmmod](myrmmod.c) + 1. [devmem](devmem.c) + 1. [init_hello](init_hello.c) +1. Module tests + 1. [anonymous_inode](anonymous_inode.c) + 1. [poll](poll.c) + 1. [ioctl](ioctl.c) diff --git a/kernel_module/user/devmem.c b/kernel_module/user/devmem.c new file mode 100644 index 0000000..483f26a --- /dev/null +++ b/kernel_module/user/devmem.c @@ -0,0 +1,47 @@ +/* +https://stackoverflow.com/questions/12040303/accessing-physical-address-from-user-space + +Sample call: + + /phys.out 0 16 + +Confirm memory from QEMU monitor with: + + xp/0 16 +*/ + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + if (argc < 3) { + printf("Usage: %s \n", argv[0]); + return 0; + } + off_t offset = strtoul(argv[1], NULL, 0); + size_t len = strtoul(argv[2], NULL, 0); + + size_t pagesize = sysconf(_SC_PAGE_SIZE); + off_t page_base = (offset / pagesize) * pagesize; + off_t page_offset = offset - page_base; + int fd = open("/dev/mem", O_SYNC); + size_t reallen = page_offset + len; + unsigned char *mem = mmap(NULL, reallen, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, page_base); + if (mem == MAP_FAILED) { + perror("mmap"); + exit(EXIT_FAILURE); + } + for (size_t i = 0; i < len; ++i) { + printf("%02x ", (unsigned int)mem[page_offset + i]); + mem[page_offset + i] = i % 256; + } + puts(""); + if (munmap(mem, reallen) == -1) { + perror("munmap"); + exit(EXIT_FAILURE); + } + return EXIT_SUCCESS; +}