From: Kwanghoon Choi (khchoi@ruby.kaist.ac.kr)
Date: Thu Apr 19 2001 - 09:45:45 EDT
Dear Sir,
I am trying to port uClinux on our ARM-based embedded system. Our
system uses the ARM processor in BIG-ENDIAN MODE. In uClinux-2.0.x,
we suspect that some routines are developed solely for little-endian mode.
In $LINUX/arch/armnommu/lib/bitops.S,
(http://cvs.uclinux.org/cgi-bin/cvsweb/uClinux-2.0.x/arch/armnommu/lib/bitops.S)
there are five functions written in ARM assembly language: set_bit(),
clear_bit(), change_bit(), find_zero_bit(), find_next_zero_bit().
The code for set_bit() function is as follows.
=============================================================================
set_bit: int set_bit(int bit, int *addr)
-----------------------------------------------------------------------------
input : r0 -> bit, r1 -> addr
0<= r0 < 32(=2^5)
=============================================================================
add r1, r1, r0, lsr #3 // r0, lsr #3 => (0 <= r0 < 32)/ 8(=2^3)
// => (0 <= r0' < 4) (quotient)
// add r1, r1, r0' => r1 <- r1 + (0 <= r0' < 4)
and r3, r0, #7 // r3 <- r0 & 0x111, i.e. r0 - (r0/8) * 8
(remainder)
mov r0, #1 // r0 <- 0x1
SAVEIRQS(ip)
DISABLEIRQS(ip)
ldrb r2, [r1] // r2 <- mem[r1]
// r1 => byte-indexing
tst r2, r0, lsl r3 // r0, lsl r3 => bit-indexing
// => set Z flag (checked by <cond> `eq')
orr r2, r2, r0, lsl r3 // r0, lsl r3 => bit-indexing
moveq r0, #0 // r0 <- 0 if Z flag =1 => set return-value
// 1 otherwise
strb r2, [r1] // mem[r1] <- r2
RESTOREIRQS(ip)
RETINSTR(mov,pc,lr)
=============================================================================
According to the above code, this C code
int v = 0x00000000; // 32bit
setbit(8, &v); // set 8th bit of 0th~31st bits
printf("%08x", v); // print `v'
prints 0 x 00 01 00 00, though I expect that the C code
prints 0 x 00 00 01 00. From this result, we suspect the above
instructions are developed for little-endian mode. For big-endian mode,
I think that the first instruction `add r1, r1, r0, lsr #3' must be
revised as this:
mov r2, r0, lsr #3
eor r2, r2, #3
add r1, r1, r2
// add r1, r1, r0, lsr #3 // r0, lsr #3 => (0 <= r0 < 32)/8 (=2^3)
// // => (0 <= r0' < 4) (quotient)
// // add r1, r1, r0' => r1 <- r1 + (0 <= r0' < 4)
My questions:
* Was this source program developed solely for little-endian mode?
* Or, did authors intentionally treat data in little-endian mode uniformly,
no matter what their ARM processors are either in little-endian mode or
in big-endian mode?
Please, let me know what goes on. I will also please if one leads
me to any documentation/experience about porting uClinux on BIG-ENDIAN ARM
processors.
Thanks in advance.
Kwanghoon Choi
P.S. You can see our own revision of `bitops.S' for big-endian mode.
I enclose the source program in this mail.
This archive was generated by hypermail 2.1.4 : Thu Sep 19 2002 - 13:19:40 EDT