diff --git a/miosix/config/miosix_settings.h b/miosix/config/miosix_settings.h
index a77ffc1d097d1f7f2c3927100ba0743ea2aeacf6..7b75d5f9ad3aa10675fda2f5dbe4db11b5dbb9db 100644
--- a/miosix/config/miosix_settings.h
+++ b/miosix/config/miosix_settings.h
@@ -264,7 +264,8 @@ const unsigned int WATERMARK_LEN=16;
 /// \internal Used to fill watermark
 const unsigned int WATERMARK_FILL=0xaaaaaaaa;
 
-/// \internal Used to fill stack (for checking stack usage)
+/// \internal Used to fill stack (for checking stack usage). Must be a single
+/// byte value repeated 4 times to fill a word
 const unsigned int STACK_FILL=0xbbbbbbbb;
 
 // Compiler version checks
diff --git a/miosix/kernel/process.cpp b/miosix/kernel/process.cpp
index b179e5453207e5c21943a6ffd31f5e9752e5b4ea..66aa84657521119164b73d6162dabad56b967c3c 100644
--- a/miosix/kernel/process.cpp
+++ b/miosix/kernel/process.cpp
@@ -882,6 +882,12 @@ Process::SvcResult Process::handleSvc(SyscallParameters sp)
                 break;
             }
 
+            case Syscall::SYSCONF:
+            {
+                sp.setParameter(0,sysconf(sp.getParameter(0)));
+                break;
+            }
+
             default:
                 exitCode=SIGSYS; //Bad syscall
                 #ifdef WITH_ERRLOG
diff --git a/miosix/kernel/process.h b/miosix/kernel/process.h
index 552f6d4d87aa72b8639fba2d479e36a326f5a047..8869fe86dc6e222010cc3c256d4b42cbc15b849a 100644
--- a/miosix/kernel/process.h
+++ b/miosix/kernel/process.h
@@ -397,6 +397,9 @@ enum class Syscall
     MOUNT     = 56,
     UMOUNT    = 57,
     MKFS      = 58, //Moving filesystem creation code to kernel
+
+    // Misc syscalls
+    SYSCONF   = 59
 };
 
 } //namespace miosix
diff --git a/miosix/libsyscalls/Makefile b/miosix/libsyscalls/Makefile
index 9fb829b98d30d40a2342331ccc458bb1052e086f..8895d449e4fd459aebad77e0a872bfcc31723f2f 100644
--- a/miosix/libsyscalls/Makefile
+++ b/miosix/libsyscalls/Makefile
@@ -9,13 +9,6 @@ include Makefile.pcommon
 
 SRC := crt0.s crt1.cpp memoryprofiling.cpp
 
-## Process code shouldn't include kernel headers, but memoryprofiling.cpp
-## needs to include miosix_settings.h. For this reason we add the required
-## include paths only here and not in Makefile.pcommon
-CXXFLAGS += -I$(CONFPATH) -I$(CONFPATH)/config/$(BOARD_INC) -I. -I$(KPATH)      \
-            -I$(KPATH)/arch/common -I$(KPATH)/$(CPU_INC) -I$(KPATH)/$(ARCH_INC) \
-            -I$(KPATH)/$(BOARD_INC)
-
 all: $(OBJ)
 	$(ECHO) "[AR  ] libsyscalls.a"
 	$(Q)$(AR) rcs libsyscalls.a $(OBJ)
diff --git a/miosix/libsyscalls/crt0.s b/miosix/libsyscalls/crt0.s
index 526cef3d8677206ce0108c8e82236d437d0d55cd..e3960fd3d8bf3c631af7e2d872014ab21c4c7db5 100644
--- a/miosix/libsyscalls/crt0.s
+++ b/miosix/libsyscalls/crt0.s
@@ -779,6 +779,21 @@ getppid:
 
 /* TODO: missing syscalls: getuid, getgid, geteuid, getegid, setuid, setgid */
 
+/**
+ * sysconf
+ * \param query requested value
+ * \return desired value on success, -1 on failure
+ */
+.section .text.sysconf
+.global sysconf
+.type sysconf, %function
+sysconf:
+	movs r3, #59
+	svc  0
+	cmp  r0, #0
+	blt  syscallfailed32
+	bx   lr
+
 /* common jump target for all failing syscalls with 32 bit return value */
 .section .text.__seterrno32
 syscallfailed32:
diff --git a/miosix/libsyscalls/memoryprofiling.cpp b/miosix/libsyscalls/memoryprofiling.cpp
index fcbc5c2e0efcc716c5aa7eba188d5681bc17f071..db85f55ee436ece150598241c9f6b79ad8efe0ea 100644
--- a/miosix/libsyscalls/memoryprofiling.cpp
+++ b/miosix/libsyscalls/memoryprofiling.cpp
@@ -29,8 +29,12 @@
 #include <cstdio>
 #include <malloc.h>
 #include <reent.h>
-#include <config/miosix_settings.h>
-#include <interfaces/cpu_const.h>
+#include <unistd.h>
+
+const int miosixCustomSysconfBase = 100000;
+const int watermarkLen   = miosixCustomSysconfBase+0;
+const int stackFill      = miosixCustomSysconfBase+1;
+const int ctxsaveOnStack = miosixCustomSysconfBase+2;
 
 // declared in crt1.cpp
 extern const char *__processHeapEnd;
@@ -42,7 +46,7 @@ namespace miosix {
 //TODO: when processes can spawn threads we need the per-thread stack bottom
 static const unsigned int *getStackBottom()
 {
-    return reinterpret_cast<const unsigned int *>(__processHeapEnd)+WATERMARK_LEN;
+    return reinterpret_cast<const unsigned int *>(__processHeapEnd)+sysconf(watermarkLen);
 }
 
 //
@@ -75,15 +79,18 @@ void MemoryProfiling::print()
 unsigned int MemoryProfiling::getStackSize()
 {
     //TODO: when processes can spawn threads we need the per-thread stack size
-    return __processStackEnd-__processHeapEnd-WATERMARK_LEN;
+    return __processStackEnd-__processHeapEnd-sysconf(watermarkLen);
 }
 
 unsigned int MemoryProfiling::getAbsoluteFreeStack()
 {
+    const unsigned int stackOccupiedByCtxsave=sysconf(ctxsaveOnStack);
+    const unsigned int fillByte=sysconf(stackFill);
+    const unsigned int fillWord=fillByte | fillByte<<8 | fillByte<<16 | fillByte<<24;
     const unsigned int *walk=getStackBottom();
     const unsigned int stackSize=getStackSize();
     unsigned int count=0;
-    while(count<stackSize && *walk==STACK_FILL)
+    while(count<stackSize && *walk==fillWord)
     {
         //Count unused stack
         walk++;
@@ -93,19 +100,20 @@ unsigned int MemoryProfiling::getAbsoluteFreeStack()
     //the absolute free stack (by a maximum of CTXSAVE_ON_STACK) but
     //it will never overestimate it, which is important since this
     //member function can be used to select stack sizes.
-    if(count<=CTXSAVE_ON_STACK) return 0;
-    return count-CTXSAVE_ON_STACK;
+    if(count<=stackOccupiedByCtxsave) return 0;
+    return count-stackOccupiedByCtxsave;
 }
 
 unsigned int MemoryProfiling::getCurrentFreeStack()
 {
+    unsigned int stackOccupiedByCtxsave=sysconf(ctxsaveOnStack);
     register int *stack_ptr asm("sp");
     const unsigned int *walk=getStackBottom();
     unsigned int freeStack=(reinterpret_cast<unsigned int>(stack_ptr)
                           - reinterpret_cast<unsigned int>(walk));
     //This takes into account CTXSAVE_ON_STACK.
-    if(freeStack<=CTXSAVE_ON_STACK) return 0;
-    return freeStack-CTXSAVE_ON_STACK;
+    if(freeStack<=stackOccupiedByCtxsave) return 0;
+    return freeStack-stackOccupiedByCtxsave;
 }
 
 unsigned int MemoryProfiling::getHeapSize()
diff --git a/miosix/stdlib_integration/libc_integration.cpp b/miosix/stdlib_integration/libc_integration.cpp
index 5d7f856da68a70f48e32c844a446d979e02896c4..40cf5da5b09d8ac1c75efcd835458aeb4ed28687 100644
--- a/miosix/stdlib_integration/libc_integration.cpp
+++ b/miosix/stdlib_integration/libc_integration.cpp
@@ -49,6 +49,7 @@
 #include "interfaces/bsp.h"
 #include "interfaces/poweroff.h"
 #include "interfaces_private/os_timer.h"
+#include "interfaces/cpu_const.h"
 
 using namespace std;
 
@@ -1346,6 +1347,25 @@ int posix_spawn(pid_t *pid, const char *path,
 #endif
 
 
+long int sysconf(int query)
+{
+    switch(query)
+    {
+        case _SC_NPROCESSORS_CONF:
+        case _SC_NPROCESSORS_ONLN:
+            return 1;
+        // Miosix-specific sysconf, used by memoryprofiling.cpp in userspace
+        case 100000:
+            return miosix::WATERMARK_LEN;
+        case 100001:
+            return (miosix::STACK_FILL & 0xff);
+        case 100002:
+            return miosix::CTXSAVE_ON_STACK;
+        default:
+            return -EINVAL;
+    }
+}
+
 
 
 //