Monday, August 20, 2007

Bash: command list (|| &&)

#!/bin/bash

# delete.sh, not-so-cunning file deletion utility.
# Usage: delete filename

E_BADARGS=65

if [ -z "$1" ]
then
echo "Usage: `basename $0` filename"
exit $E_BADARGS # No arg? Bail out.
else
file=$1 # Set filename.
fi


[ ! -f "$file" ] && echo "File \"$file\" not found. \
Cowardly refusing to delete a nonexistent file."
# AND LIST, to give error message if file not present.
# Note echo message continued on to a second line with an escape.

[ ! -f "$file" ] || (rm -f $file; echo "File \"$file\" deleted.")
# OR LIST, to delete file if present.

# Note logic inversion above.
# AND LIST executes on true, OR LIST on false.

exit 0

Sunday, August 19, 2007

Gnu-make: pattern rule

A pattern rule contains the character `%' (exactly one of them) in the
target; otherwise, it looks exactly like an ordinary rule. The target is
a pattern for matching file names; the `%' matches any nonempty
substring, while other characters match only themselves

Here are some examples of pattern rules actually predefined in make.
First, the rule that compiles `.c' files into `.o' files:

%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

defines a rule that can make any file `x.o' from `x.c'. The command uses
the automatic variables `$@' and `$<' to substitute the names of the
target file and the source file in each case where the rule applies (see
section Automatic Variables).

Gnu-make: patsubst

$(var:pattern=replacement)
is equivalent to
$(patsubst pattern,replacement,$(var))
The second shorthand simplifies one of the most common uses of patsubst:
replacing the suffix at the end of file names.
$(var:suffix=replacement)
is equivalent to
$(patsubst %suffix,%replacement,$(var))
For example, you might have a list of object files:
objects = foo.o bar.o baz.o
To get the list of corresponding source files, you could simply write:
$(objects:.o=.c)
instead of using the general form:
$(patsubst %.o,%.c,$(objects))

Friday, August 10, 2007

initramfs

Docs:
Document/early-userspace/

http://linuxdevices.com/articles/AT4017834659.html

initramfs by default load a cpio image. But it can also load initrd (a
fs) image.

The "initramfs" concept has been in the 2.5 plans since back before
there was a 2.5 kernel. Things have been very quiet on the initramfs
front, however, until the first patch showed up and was merged into the
2.5.46 tree.

The basic idea behind initramfs is that a cpio archive can be attached
to the kernel image itself. At boot time, the kernel unpacks that
archive into a RAM-based disk, which is then mounted and used at the
initial root filesystem. Much of the kernel initialization and bootstrap
code can then be moved into this disk and run in user mode. Tasks like
finding the real root disk, boot-time networking setup, handling of
initrd-style ramdisks, ACPI setup, etc. will be shifted out of the
kernel in this way.

An obvious advantage of this scheme is that the size of the kernel code
itself can shrink. That does not free memory for a running system, since
the Linux kernel already dumps initialization code when it is no longer
needed. But a smaller code base for the kernel itself makes the whole
thing a little easier to maintain, and that is always a good thing. But
the real advantages of initramfs are:

* Customizing the early boot process becomes much easier. Anybody
who needs to change how the system boot can now do so with
user-space code; patching the kernel itself will no longer be
required.

* Moving the initialization code into user space makes it easier
to write that code - it has a full C library, memory protection,
etc.

* As pointed out by Alexander Viro: user-space code is required to
deal with the kernel via system calls. This requirement will
flush a lot of in-kernel "magic" currently used by the
initialization code; the result will be cleaner, safer code.

Code:

init/initramfs.c:
rootfs_initcall(populate_rootfs);

init/main.c:
_start() -> start_kernel() -> rest_init()->

kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);

_init() -> do_basic_settup():

/*
* Ok, the machine is now initialized. None of the devices
* have been touched yet, but the CPU subsystem is up and
* running, and memory and process management works.
*
* Now we can finally start doing some real work..
*/
static void __init do_basic_setup(void)
{
/* drivers will send hotplug events */
init_workqueues();
usermodehelper_init();
driver_init();
init_irq_proc();
do_initcalls();
}

do_initcalls() --> populate_rootfs()

Monday, August 06, 2007

Gnu-make: "-include"

If you want make to simply ignore a makefile which does not exist and
cannot be remade, with no error message, use the -include directive
instead of include, like this:

-include filenames...

This acts like include in every way except that there is no error (not
even a warning) if any of the filenames do not exist. For compatibility
with some other make implementations, sinclude is another name for
-include.

Blog Archive