On 64 bit Linux kernel, division (/) and modulus operator (%) will behaved as expected. GCC C compiler generates code that calls functions in the libgcc library to implement the / and % operations with 64-bit operands on 32-bit CPUs. Linux kernel is not linked against the libgcc library, so such code will fail to link when building code for a 32-bit Linux kernel.

Linux kernel has #include header, which defines a set of functions which can help with operations which are not supported on 32-bit kernel. The functions declared by #include <linux/math64.h> for 64-bit division are listed below

  • u64 div_u64 (u64 dividend, u32 divisor) : Unsigned division of 64-bit dividend by 32-bit divisor.
  • s64 div_s64(s64 dividend, s32 divisor) : Signed division of 64-bit dividend by 32-bit divisor.
  • u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) : Unsigned division of 64-bit dividend by 32-bit divisor with remainder.
  • s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) : Signed division of 64-bit dividend by 32-bit divisor with remainder.
  • u64 div64_u64(u64 dividend, u64 divisor) : Unsigned division of 64-bit dividend by 64-bit divisor.
  • s64 div64_s64(s64 dividend, s64 divisor) : Signed division of 64-bit dividend by 64-bit divisor.
  • u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder) : Unsigned division of 64-bit dividend by 64-bit divisor with remainder.
  • s64 div64_s64_rem(s64 dividend, s64 divisor, s64 *remainder) : Signed division of 64-bit dividend by 64-bit divisor with remainder.
  • div64_long(x,y) : Signed division of a 64-bit dividend by a long int divisor
  • div64_ul(x,y) : Unsigned division of a 64-bit dividend by an unsigned long int divisor.

do_div macro

Originally, the Linux kernel only had the do_div(n,base) macro defined by #include<asm/div64.h> . It modifies its first argument in place to become the quotient resulting from the division, and returns the remainder from the division as its result. It only supports division of a 64-bit unsigned dividend by a 32-bit divisor.

The specific definition of do_div(n,base) is related to the current architecture. For the arm platform, in

arch/arm/include\asm\div64.h