diff --git a/Kernel/arch/armv7/lib.S b/Kernel/arch/armv7/lib.S
index d37c4a18b772a87ebd88d588225eebc7fa638d2a..e2f06130589c4c26cc5dc24c7a288e54a83fb0d6 100644
--- a/Kernel/arch/armv7/lib.S
+++ b/Kernel/arch/armv7/lib.S
@@ -42,3 +42,43 @@ __memcpy_align4:
 
 3:	pop {r4}
 	mov pc, lr
+
+@
+@ Division
+@
+.globl __divmod32_asm
+__divmod32_asm:
+	push {r4}
+	mov r4, #0	@ Return value
+	mov r3, #1	@ add value
+
+	@ Scan up for first larger multiple of 2
+1:	cmp r0, r1	@ N < D
+	bmi 2f   	@ ^^
+	lsl r1, r1, #1	@ D <<= 1
+	lsls r3, r3, #1	@ add <<= 1
+	beq .err	@ result is zero
+	b 1b
+	
+	@ Go back down
+2:	lsrs r3, r3, #1	@ add >>= 1
+	beq 3f  	@ Done (value is zero)
+	lsr r1, r1, #1	@ D >>= 1
+	cmp r0, r1	@ N < D
+	bmi 2b
+	sub r0, r1	@ N -= D
+	add r4, r3	@ ret += add
+	b 2b
+3:
+	tst r2, r2	@ Remainder (if wanted)
+	strne r0,[r2]
+	mov r0, r4	@ Return value
+	pop {r4}
+	mov pc, lr
+.err:
+	mov r0, #0
+	tst r2, r2
+	strne r0, [r2]
+	pop {r4}
+	mov pc, lr
+
diff --git a/Kernel/arch/armv7/lib.c b/Kernel/arch/armv7/lib.c
index c0feab6c21a10169f6dc5af5f1cb8676d265cfb1..a1fbfb77cc4b906af07a18807bd33029200c4c3b 100644
--- a/Kernel/arch/armv7/lib.c
+++ b/Kernel/arch/armv7/lib.c
@@ -8,6 +8,7 @@
 // === IMPORTS ===
 extern void	__memcpy_align4(void *_dest, const void *_src, size_t _length);
 extern void	__memcpy_byte(void *_dest, const void *_src, size_t _length);
+extern Uint32	__divmod32_asm(Uint32 Num, Uint32 Den, Uint32 *Rem);
 
 // === PROTOTYPES ===
 Uint64	__divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem);
@@ -41,7 +42,7 @@ void *memcpy(void *_dest, const void *_src, size_t _length)
 	// Force alignment
 	while( (tVAddr)dst8 & 3 ) *dst8 ++ = *src8++, _length --;
 
-	__memcpy_align32(dst8, src8, _length);
+	__memcpy_align4(dst8, src8, _length);
 	
 	return _dest;
 }
@@ -136,6 +137,10 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
 {
 	Uint64	ret;
 	if(Den == 0)	return 0;	// TODO: #div0
+	if(Num < Den) {
+		if(Rem)	*Rem = Num;
+		return 0;
+	}
 	if(Num == 0) {
 		if(Rem)	*Rem = 0;
 		return 0;
@@ -160,6 +165,11 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Den, Uint64 *Rem)
 		if(Rem)	*Rem = Num & 0xFFF;
 		return Num >> 12;
 	}
+	
+	if( !(Den >> 32) && !(Num >> 32) ) {
+		if(Rem)	*Rem = 0;	// Clear high bits
+		return __divmod32_asm(Num, Den, (Uint32*)Rem);
+	}
 
 	ret = __divmod64(Num, Den, Rem);
 	return ret;
@@ -181,13 +191,13 @@ Uint64 __umoddi3(Uint64 Num, Uint64 Den)
 
 Uint32 __udivsi3(Uint32 Num, Uint32 Den)
 {
-	return __divmod32(Num, Den, NULL);
+	return __divmod32_asm(Num, Den, NULL);
 }
 
 Uint32 __umodsi3(Uint32 Num, Uint32 Den)
 {
 	Uint32	rem;
-	__divmod32(Num, Den, &rem);
+	__divmod32_asm(Num, Den, &rem);
 	return rem;
 }