One convenient Linux kernel feature is an uptime stamp in each kernel log entry. This stamp is independent of the clock time, so small or large jumps in the clock have no bearing on the reported time for each entry.
Normally, the log files in /var/log/ will include a human-readable local time stamp before the log entry, but these files are readable only by the root user. Another possibility is that the logs are routed to another system for storage. This practice would also include restricting “dmesg” to the root user; the following won’t be useful in this case.
One axiom of computing is to script commonly-used command sequences, akin to C’s functions, Pascal’s procedures, and Ada’s subprograms. But what if the command sequence involves “su” for elevated privileges? I found an idiom that Works For Me.
This example will pull pages from the swap space back into RAM:
#!/bin/sh case `id -u` in # The task is accomplished in the 0 case, # where we know we have root privileges. 0) /sbin/swapoff -a /sbin/swapon -a ;; # Everyone else gets to provide a password: *) exec /bin/su -c "`which $0`" - ;; esac
Anything requiring elevated privileges, or even simply someone else’s privileges, can be scripted this way. I have the above script in ~/bin/unswap. I have three other scripts in the same directory, called “slow”, “normal”, and “fast”, which set the CPU frequency governor to powersave, ondemand, or performance.
The one caveat is to hard-code the paths to the root-executed programs (which you already do in scripts, right?). You don’t want to execute a non-standard “swapon” that isn’t where you expect it to be.
(If someone would like to contribute an example using “sudo” instead of “su” it would be greatly appreciated.)
I run Slackware ARM on my Raspberry Pi. I’ve been a longtime fan of Slackware, which caters to my inner control-freak. However, since Slackware ARM (formerly ARMedSlack) is designed to run on a variety of ARM-based systems, and an ARM-based system is typically a System-on-Chip, this means that Slackware ARM is built for maximum compatibility… and minimum optimization. For example, not all ARM CPU’s have on-board floating-point capability. By assuming no floating-point capability, Slackware ARM can run on a wider range of ARM-based systems. However, this can reduce performance significantly.
This guide will explain how to rebuild core glibc libraries to use the greater capability of the Raspberry Pi’s on-board ARM 1176JZF-S CPU. The process is not terribly involved, but using NFS for the build space took 8-1/2 hours, even with the CPU overclocked to 900 MHz.
The first generation of x86 processors, the 8086 and 8088, had support for synchronous asymmetric multiprocessing. Synchronous, in that the main processor could wait for a READY/#BUSY or ERR signal from the coprocessor; and asymmetric, because the coprocessor’s instructions were completely different from the main processor’s. The coprocessor could not address memory, but had to wait for the main processor to decode an instruction’s addressing mode and then “open a window” into RAM for the coprocessor. The coprocessor could then read from or write to the data lines as required. For this reason, coprocessor instructions are always followed by at least one byte (ModR/M, in Intel terminology) indicating the addressing mode of the instruction. Coprocessor instructions operating on internal state only, with no memory access, could be carried out in parallel with main processor instructions, and the addressing mode byte indicates no memory access.
The coprocessor most often connected to the 8086 was the 8087 floating-point math unit. Later generations saw the 80x87 unit integrated with the main processor, at first by moving the chip logic onto the same wafer, but still using the same x86/x87 interconnect. With the Pentium series, the x87 was fully integrated into the superscalar design. The “coprocessor instruction space” became the “x87 instruction space.”
The ARM architecture has always had support for operations on up to 16 coprocessors. However, some operations now handled by coprocessors have not always been. For example, memory management is now handled by coprocessor 15, but the BBC Micro had the MEMC memory controller chip. The MEMC was managed by asserting values on the address bus, that is, reading or writing a particular location. If the address bits 25-17 contained 11011x111 in binary, then the MEMC interpreted the overall address as a re-configuration command for itself. (Interesting note: The binary sequence 11011 in the high bits is also how the 80x86 denotes a coprocessor instruction.)
Looking specifically at floating-point coprocessors, the x87 uses an extended precision (10 bytes) internally; handles logarithmic and trigonometric functions on-chip; and was strongly stack-based, though no longer so. The ARM vector floating-point (VFP) unit on the Raspberry Pi uses 4 or 8 bytes internally, does not support logarithms or trig functions in hardware, and supports the 3-register paradigm common to ARM (two source operands, and a third destination).
Let’s take a look at adding two floating-point values.
Three months on, my Raspberry Pi is still proving a delight. I have settled on the Raspbian distribution as my tinkerer’s habitat, giving me access to the floating-point unit in the glibc libraries (especially libm.so).
However, being mostly uninitiated in Debian administration, I have spent some time learning “the Debian way” of doing things. This article will therefore be a shameless hodge-podge of Raspbian review and Debian ignorance, plus a handy (for me) trick at the end.