LinuxKernel

Keywords: Step through Linux Kernel (3.1.1)

Exploring Linux Kernel

1. Kernel Source

The official Linux Kernel can be downloaded from here.

The more readable format is from LXR (Linux Cross Referencer).

2. The Linux Documentation Project

There are a lot of documents for Linux Kernel and boot process.

The Linux Kernel Book is the one of best guides although it is an old one from the last century.

Booting Linux: The History and the Future was written by Werner Almesberger. (2000)

The Linux Boot Process from a Canadian Linux User Group was another concise, non-nonsense paper (2004)

The most recent one is 6 Stages of Linux Boot Process (2011)

3. How PC start

In Linux, the flow of control during a boot is from BIOS, to boot loader, to kernel.

3.1. BIOS: First Stage Boot loader

Smaller computers often use less flexible but more automatic bootload mechanisms to ensure that the computer starts quickly and with a predetermined software configuration. In many desktop computers, for example, the bootstrapping process begins with the CPU executing software contained in ROM (for example, the BIOS of an IBM PC) at a predefined address (some CPUs, including the Intel x86 series are designed to execute this software after reset without outside help). This software contains rudimentary functionality to search for devices eligible to participate in booting, and load a small program from a special section (most commonly the boot sector) of the most promising device.

Boot loaders may face peculiar constraints, especially in size; for instance, on the IBM PC and compatibles, the first stage of boot loaders located on hard drives must fit into the first 446 bytes (or 440 bytes if Windows NT or above has to be supported because NT put 6 byte disk-signature starting from offset 440) of the Master Boot Record, in order to leave room for the 64-byte partition table and the 2-byte 0xAA55 ‘signature’, which the BIOS requires for a proper boot loader.

3.2. Second-stage boot loader

This small program is most often not itself an operating system, but only a second-stage boot loader, such as GRUB, BOOTMGR, Syslinux, LILO or NTLDR. It will then be able to load the operating system properly, and finally transfer execution to it. The operating system will initialize itself, and may load device drivers that are needed for the normal operation of the OS. After that it starts loading normal system programs.

Many bootloaders (like GRUB, BOOTMGR, LILO, and NTLDR) can be configured to give the user multiple booting choices. These choices can include different operating systems (for dual or multi-booting from different partitions or drives), different versions of the same operating system (in case a new version has unexpected problems), different operating system loading options (e.g., booting into a rescue or safe mode) or some standalone program that can function without an operating system, such as memory testers (e.g., memtest86+) or even games (see List of PC Booter games).Usually a default choice is preselected with a time delay during which a user can press a key to change the choice, after which the default choice is automatically run, so normal booting can occur without interaction.

3.3. Booting a new kernel

Use a boot loader, like lilo or grub. The boot source can be from an USB / DVD

After compilation you have a file arch/i386/boot/bzImage (assuming that was on a PC). For a bootfloppy, dd this file to an empty diskette. Otherwise, copy the file to /boot, add it to /etc/lilo.conf or /boot/grub/grub.conf or so, run lilo and lilo -R if you are a lilo user, and reboot into your new kernel.

Grub allows you a menu with possible kernels to boot. That is nice. Lilo has a much better feature: lilo -R allows you to set the kernel to boot into for the next time only. So, for kernel development lilo is easier than grub: make a new kernel, try a boot, probably something will fail, and the next reboot is into the good old solid kernel again.

On the other hand, lilo has a disadvantage: you must rerun lilo after installing a new kernel, and very obscure things will happen if you forget.

Never delete your old kernel. Maybe the new one doesn’t work.

3.4. Examples of config files

Example of a grub.conf file:

# /boot/grub/grub.conf
#
default=0
timeout=10
splashimage=(hd0,1)/boot/grub/splash.xpm.gz
title 2.4.18-pre7-ac3a-unclip-scsi
        root (hd0,1)
        kernel /boot/bzImage-2.4.18-pre7-ac3a-unclip-scsi ro root=/dev/hda2
title 2.4.20pre4bs
        root (hd0,1)
        kernel /boot/bzImage-2.4.20pre4bs ro root=/dev/hda2
title Red Hat Linux (2.4.7-10)
        root (hd0,1)
        kernel /boot/vmlinuz-2.4.7-10 ro root=/dev/hda2
        initrd /boot/initrd-2.4.7-10.img
title WINNT
        rootnoverify (hd1,1)
        chainloader +1
title DOS
        rootnoverify (hd0,0)
        chainloader +1

Example of a lilo.conf file:

# /etc/lilo.conf
#
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50
image=/boot/vmlinuz-2.0.34-0.6
        label=linux
        root=/dev/hda5
        read-only

# 2.2.1 plus disk output
image=/boot/bzImage-test
        label=test
        root=/dev/hda5
        read-only

other=/dev/hda1
        label=w95
        table=/dev/hda

and another one:

# /etc/lilo.conf
#
boot    = /dev/hda
#
disk    = /dev/hda
  bios  = 0x80
disk    = /dev/hdb
  bios  = 0x81
disk    = /dev/hde
  bios  = 0x82
disk    = /dev/hdf
  bios  = 0x83
#
change-rules
reset
read-only
menu-scheme = Wg:kw:Wg:Wg
lba32
prompt
timeout = 80
message = /boot/message

  image = /boot/bzImage-2.5.38a
  label = 2.5.38a
  root  = /dev/hdb6
  append = "rootfstype=ext3 hdc=ide-scsi"

  image = /boot/bzImage-2.4.19a
  label = 2.4.19a
  root  = /dev/hdb6
  append = "rootfstype=ext3 hdc=ide-scsi"

  # SuSE kernel; warning: eth0 and eth2 interchanged
  image  = /boot/vmlinuz
  label  = suse
  root   = /dev/hdb6
  vga    = 791
  initrd = /boot/initrd
  append = " ide=nodma apm=off acpi=off hdc=ide-scsi"

  image  = /boot/memtest.bin
  label  = memtest86

4. Get Started with Linux Kernels

The kernel in Linux handles all operating system processes, such as memory management, task scheduling, I/O, interprocess communication, and overall system control. This is loaded in two stages – in the first stage the kernel (as a compressed image file) is loaded into memory and decompressed, and a few fundamental functions such as basic memory management are set up. Control is then switched one final time to the main kernel start process. Once the kernel is fully operational – and as part of its startup, upon being loaded and executing – the kernel looks for an init process to run, which (separately) sets up a user space and the processes needed for a user environment and ultimate login. The kernel itself is then allowed to go idle, subject to calls from other processes.

4.1. Real mode initialization code (transition to protected mode)

In Linux Kernel 3.1.1, the starting point is linux/arch/x86/boot/main.c where

127
128void main(void)
129{
130 /* First, copy the boot header into the "zeropage" */
131        copy_boot_params();
132
133        /* Initialize the early-boot console */
134        console_init();
135        if (cmdline_find_option_bool("debug"))
136                puts("early console in setup code\n");
137
138        /* End of heap check */
139        init_heap();
140
141        /* Make sure we have all the proper CPU support */
142        if (validate_cpu()) {
143                puts("Unable to boot - please use a kernel appropriate "
144                     "for your CPU.\n");
145                die();
146        }
147
148        /* Tell the BIOS what CPU mode we intend to run in. */
149        set_bios_mode();
150
151        /* Detect memory layout */
152        detect_memory();
153
154        /* Set keyboard repeat rate (why?) */
155        keyboard_set_repeat();
156
157        /* Query MCA information */
158        query_mca();
159
160        /* Query Intel SpeedStep (IST) information */
161        query_ist();
162
163        /* Query APM information */
164#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
165        query_apm_bios();
166#endif
167
168        /* Query EDD information */
169#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
170        query_edd();
171#endif
172
173        /* Set the video mode */
174        set_video();
175
176        /* Do the last things and invoke protected mode */
177        go_to_protected_mode();
178}
  • linux/arch/x86/boot/boot.h provides the location of most of functions in boot module.
  • copy_boot_params():  Copy the header into the boot parameter block (4K page).
  • console_init(): make sure we have console ready (ttyS0)
  • set_bios_mode(): 64 bits extra stuff detect_memory(): set ireg.ax = 0x88 or 0xe801 or 0xe820
  • query_mca(): mca (IBM Micro-Channel Architecture), and then copy_from_fs(&boot_params.sys_desc_table,..) with (linux/arch/x86/boot/copy.S)
  • query_apm_bios(), query_edd(), set_video() etc  all results in boot_params block structure set to relevant hardware information.
  • Therefore, it is ready to go_to_protected_mode() in linux/arch/x86/boot/pm.c.
  • Finally, switch to protected mode in linux/arch/x86/boot/pmjump.S (an Assembly code) where the actual transition carries out [void protected_mode_jump(u32 entrypoint, u32 bootparams)]

4.2. Protected mode initialization code

The kernel as loaded is typically an image file, compressed into either zImage or bzImage formats with zlib. A routine at the head of it does a minimal amount of hardware setup, decompresses the image fully into high memory, and takes note of any RAM disk if configured. It then executes kernel startup via ./arch/i386/boot/head and the startup_32 () (for x86 based processors) process.

In Kernel 3.1.1, it is  linux/arch/x86/boot/compressed/head_32.S or  linux/arch/x86/boot/compressed/head_64.S (all assembly codes)

  • starting point is ENTRY(startup_32)
  • Startup happens at absolute address 0x00001000, which is also where the page directory will exists.
  • Calculate loading safe address for kernel image in-place decompression and reserve real time stack
  • Copy the compressed kernel to the end of our buffer where decompression in place becomes safe.
  • Do the decompression by (call decompress_kernel) which is in linux/arch/x86/boot/compressed/misc.c
  • Jump to the new kernel (jmp *%ebp)…

Take a look at linux/include/linux/init.h for linkage. Here we go to the following…

linux/arch/x86/kernel/head32.c   or linux/arch/x86/kernel/head64.c

 32void __init i386_start_kernel(void)
 33{
 34        memblock_init();
 35
 36        memblock_x86_reserve_range(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
 37
 38#ifdef CONFIG_BLK_DEV_INITRD
 39        /* Reserve INITRD */
 40        if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
 41                /* Assume only end is not page aligned */
 42                u64 ramdisk_image = boot_params.hdr.ramdisk_image;
 43                u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
 44                u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
 45                memblock_x86_reserve_range(ramdisk_image, ramdisk_end, "RAMDISK");
 46        }
 47#endif
 48
 49        /* Call the subarch specific early setup function */
 50        switch (boot_params.hdr.hardware_subarch) {
 51        case X86_SUBARCH_MRST:
 52                x86_mrst_early_setup();
 53                break;
 54        case X86_SUBARCH_CE4100:
 55                x86_ce4100_early_setup();
 56                break;
 57        default:
 58                i386_default_early_setup();
 59                break;
 60        }
 61
 62        /*
 63         * At this point everything still needed from the boot loader
 64         * or BIOS or kernel text should be early reserved or marked not
 65         * RAM in e820. All other memory is free game.
 66         */
 67
 68       start_kernel();
 69}
 70

Here we are. The most exciting part: start_kernel()…..

4.3. Real Kernel

The startup function for the kernel (also called the swapper or process 0) establishes memory management (paging tables and memory paging), detects the type of CPU and any additional functionality such as floating point capabilities, and then switches to non-architecture specific Linux kernel functionality via a call to start_kernel ().

In 3.1.1,  linux/init/main.c,

4.3.1. Kernel Starting Phase: start_kernel()
467asmlinkage void __init start_kernel(void)
468{
469        char * command_line;
470        extern const struct kernel_param __start___param[], __stop___param[];
471
472        smp_setup_processor_id();
473
474        /*
475         * Need to run as early as possible, to initialize the
476         * lockdep hash:
477         */
478        lockdep_init();
479        debug_objects_early_init();
480
481        /*
482         * Set up the the initial canary ASAP:
483         */
484        boot_init_stack_canary();
485
486        cgroup_init_early();
487
488        local_irq_disable();
489        early_boot_irqs_disabled = true;
490
491/*
492 * Interrupts are still disabled. Do necessary setups, then
493 * enable them
494 */
495        tick_init();
496        boot_cpu_init();
497        page_address_init();
498        printk(KERN_NOTICE "%s", linux_banner);
499        setup_arch(&command_line);
500        mm_init_owner(&init_mm, &init_task);
501        mm_init_cpumask(&init_mm);
502        setup_command_line(command_line);
503        setup_nr_cpu_ids();
504        setup_per_cpu_areas();
505        smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
506
507        build_all_zonelists(NULL);
508        page_alloc_init();
509
510        printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
511        parse_early_param();
512        parse_args("Booting kernel", static_command_line, __start___param,
513                   __stop___param - __start___param,
514                   &unknown_bootoption);
515        /*
516         * These use large bootmem allocations and must precede
517         * kmem_cache_init()
518         */
519        setup_log_buf(0);
520        pidhash_init();
521        vfs_caches_init_early();
522        sort_main_extable();
523        trap_init();
524        mm_init();
525
526        /*
527         * Set up the scheduler prior starting any interrupts (such as the
528         * timer interrupt). Full topology setup happens at smp_init()
529         * time - but meanwhile we still have a functioning scheduler.
530         */
531        sched_init();
532        /*
533         * Disable preemption - early bootup scheduling is extremely
534         * fragile until we cpu_idle() for the first time.
535         */
536        preempt_disable();
537        if (!irqs_disabled()) {
538                printk(KERN_WARNING "start_kernel(): bug: interrupts were "
539                                "enabled *very* early, fixing it\n");
540                local_irq_disable();
541        }
542        idr_init_cache();
543        perf_event_init();
544        rcu_init();
545        radix_tree_init();
546        /* init some links before init_ISA_irqs() */
547        early_irq_init();
548        init_IRQ();
549        prio_tree_init();
550        init_timers();
551        hrtimers_init();
552        softirq_init();
553        timekeeping_init();
554        time_init();
555        profile_init();
556        call_function_init();
557        if (!irqs_disabled())
558                printk(KERN_CRIT "start_kernel(): bug: interrupts were "
559                                 "enabled early\n");
560        early_boot_irqs_disabled = false;
561        local_irq_enable();
562
563        /* Interrupts are enabled now so all GFP allocations are safe. */
564        gfp_allowed_mask = __GFP_BITS_MASK;
565
566        kmem_cache_init_late();
567
568        /*
569         * HACK ALERT! This is early. We're enabling the console before
570         * we've done PCI setups etc, and console_init() must be aware of
571         * this. But we do want output early, in case something goes wrong.
572         */
573        console_init();
574        if (panic_later)
575                panic(panic_later, panic_param);
576
577        lockdep_info();
578
579        /*
580         * Need to run this when irqs are enabled, because it wants
581         * to self-test [hard/soft]-irqs on/off lock inversion bugs
582         * too:
583         */
584        locking_selftest();
585
586#ifdef CONFIG_BLK_DEV_INITRD
587        if (initrd_start && !initrd_below_start_ok &&
588            page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
589                printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
590                    "disabling it.\n",
591                    page_to_pfn(virt_to_page((void *)initrd_start)),
592                    min_low_pfn);
593                initrd_start = 0;
594        }
595#endif
596        page_cgroup_init();
597        enable_debug_pagealloc();
598        debug_objects_mem_init();
599        kmemleak_init();
600        setup_per_cpu_pageset();
601        numa_policy_init();
602        if (late_time_init)
603                late_time_init();
604        sched_clock_init();
605        calibrate_delay();
606        pidmap_init();
607        anon_vma_init();
608#ifdef CONFIG_X86
609        if (efi_enabled)
610                efi_enter_virtual_mode();
611#endif
612        thread_info_cache_init();
613        cred_init();
614        fork_init(totalram_pages);
615        proc_caches_init();
616        buffer_init();
617        key_init();
618        security_init();
619        dbg_late_init();
620        vfs_caches_init(totalram_pages);
621        signals_init();
622        /* rootfs populating might need page-writeback */
623        page_writeback_init();
624#ifdef CONFIG_PROC_FS
625        proc_root_init();
626#endif
627        cgroup_init();
628        cpuset_init();
629        taskstats_init_early();
630        delayacct_init();
631
632        check_bugs();
633
634        acpi_early_init(); /* before LAPIC and SMP init */
635        sfi_init_late();
636
637        ftrace_init();
638
639        /* Do the rest non-__init'ed, we're now alive */
640        rest_init();
641}
642

There are quite a number of things to be explored here. However, before branching out to the specific functions, let’s see how the other explain the start_kernel() in general terms:

IBM Explanation

start_kernel executes a wide range of initialization functions. It sets up interrupt handling (IRQs), further configures memory, starts the Init process (the first user-space process), and then starts the idle task via cpu_idle (). Notably, the kernel startup process also mounts the initial RAM disk (“initrd”) that was loaded previously as the temporary root filing system during the boot phase. This allows driver modules to be loaded without reliance upon other physical devices and drivers, and keeps the kernel smaller. The root file system is later switched via a call to pivot_root () which unmounts the temporary root file system and replaces it with the use of the real one, once the latter is accessible. The memory used by the temporary root file system is then reclaimed.

Redhat Explanation

“When the kernel is loaded, it immediately initializes and configures the computer’s memory and configures the various hardware attached to the system, including all processors, I/O subsystems, and storage devices. It then looks for the compressed initrd image in a predetermined location in memory, decompresses it, mounts it, and loads all necessary drivers. Next, it initializes virtual devices related to the file system, such as LVM or software RAID before unmounting the initrd disk image and freeing up all the memory the disk image once occupied. The kernel then creates a root device, mounts the root partition read-only, and frees any unused memory. At this point, the kernel is loaded into memory and operational. However, since there are no user applications that allow meaningful input to the system, not much can be done with it.”

In the above program, most of functions are init related, and one can explore them in days, if not weeks. I take a look at some of them:

In rest_init(), it will call the following:

        kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

then the kernal_init() will be called.

4.3.2. kernel_init()
791
792static int __init kernel_init(void * unused)
793{
794        /*
795         * Wait until kthreadd is all set-up.
796         */
797        wait_for_completion(&kthreadd_done);
798        /*
799         * init can allocate pages on any node
800         */
801        set_mems_allowed(node_states[N_HIGH_MEMORY]);
802        /*
803         * init can run on any cpu.
804         */
805        set_cpus_allowed_ptr(current, cpu_all_mask);
806
807        cad_pid = task_pid(current);
808
809        smp_prepare_cpus(setup_max_cpus);
810
811        do_pre_smp_initcalls();
812        lockup_detector_init();
813
814        smp_init();
815        sched_init_smp();
816
817        do_basic_setup();
818
819        /* Open the /dev/console on the rootfs, this should never fail */
820        if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
821                printk(KERN_WARNING "Warning: unable to open an initial console.\n");
822
823        (void) sys_dup(0);
824        (void) sys_dup(0);
825        /*
826         * check if there is an early userspace init.  If yes, let it do all
827         * the work
828         */
829
830        if (!ramdisk_execute_command)
831                ramdisk_execute_command = "/init";
832
833        if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
834                ramdisk_execute_command = NULL;
835                prepare_namespace();
836        }
837
838        /*
839         * Ok, we have completed the initial bootup, and
840         * we're essentially up and running. Get rid of the
841         * initmem segments and start the user-mode stuff..
842         */
843
844        init_post();
845        return 0;
846}

prepare_namespace() is very important. At this point, with interrupts enabled, the scheduler can take control of the overall management of the system, to provide pre-emptive multi-tasking, and the init process is left to continue booting the user environment in user space.

The last part of kernal_init() is calling init_post() in the following.

4.3.3. init_post()
static noinline int init_post(void)
755{
756        /* need to finish all async __init code before freeing the memory */
757        async_synchronize_full();
758        free_initmem();
759        mark_rodata_ro();
760        system_state = SYSTEM_RUNNING;
761        numa_default_policy();
762
763
764        current->signal->flags |= SIGNAL_UNKILLABLE;
765
766        if (ramdisk_execute_command) {
767                run_init_process(ramdisk_execute_command);
768                printk(KERN_WARNING "Failed to execute %s\n",
769                                ramdisk_execute_command);
770        }
771
772        /*
773         * We try each of these until one succeeds.
774         *
775         * The Bourne shell can be used instead of init if we are
776         * trying to recover a really broken machine.
777         */
778        if (execute_command) {
779                run_init_process(execute_command);
780                printk(KERN_WARNING "Failed to execute %s.  Attempting "
781                                        "defaults...\n", execute_command);
782        }
783        run_init_process("/sbin/init");
784        run_init_process("/etc/init");
785        run_init_process("/bin/init");
786        run_init_process("/bin/sh");
787
788        panic("No init found.  Try passing init= option to kernel. "
789              "See Linux Documentation/init.txt for guidance.");
790}

By the time init_post(), the boot init memory could be released and the init process (/sbin/init) will be the first process (PID=1, UID=root) got started. The user mode should be ready.

5. Init Process (System V)

Init is the father of all processes. Its primary role is to create processes from a script stored in the file /etc/inittab. This file usually has entries which cause init to spawn gettys on each line that users can log in. It also controls autonomous processes required by any particular system. A run level is a software configuration of the system which allows only a selected group of processes to exist. The processes spawned by init for each of these run levels are defined in the /etc/inittab file.
— manual page for Init(2)

Init’s job is “to get everything running the way it should be once the kernel is fully running. Essentially it establishes and operates the entire user space. This includes checking and mounting file systems, starting up necessary user services, and ultimately switching to a user-environment when system startup is completed. It is similar to the Unix and BSD init processes, from which it derived, but in some cases has diverged or became customized. In a standard Linux system, Init is executed with a parameter, known as a run level, that takes a value from 1 to 6, and that determines which subsystems are to be made operational. Each runlevel has its own scripts which codify the various processes involved in setting up or leaving the given runlevel, and it is these scripts which are referenced as necessary in the boot process. Init scripts are typically held in directories with names such as "/etc/rc...". The top level configuration file for init is at /etc/inittab.

During system boot, it checks whether a default runlevel is specified in /etc/inittab, and requests the runlevel to enter via the system console if not. It then proceeds to run all the relevant boot scripts for the given runlevel, including loading modules, checking the integrity of the root file system (which was mounted read-only) and then remounting it for full read-write access, and sets up the network.

After it has spawned all of the processes specified, init goes dormant, and waits for one of three events to happen:- processes it started to end or die, a power failure signal, or a request via /sbin/telinit to further change the runlevel.

This applies to SysV-style init. Other init binaries, such as systemd or Upstart, may behave differently.

6. Kernel Daemon

~$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1   2888  1708 ?        Ss   18:15   0:01 /sbin/init
root         2  0.0  0.0      0     0 ?        S    18:15   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    18:15   0:01 [ksoftirqd/0]
root         4  0.0  0.0      0     0 ?        S    18:15   0:00 [migration/0]
root         5  0.0  0.0      0     0 ?        S    18:15   0:00 [watchdog/0]
root         9  0.0  0.0      0     0 ?        S    18:15   0:00 [events/0]
root        11  0.0  0.0      0     0 ?        S    18:15   0:00 [cpuset]
root        12  0.0  0.0      0     0 ?        S    18:15   0:00 [khelper]
root        13  0.0  0.0      0     0 ?        S    18:15   0:00 [netns]
root        14  0.0  0.0      0     0 ?        S    18:15   0:00 [async/mgr]
root        15  0.0  0.0      0     0 ?        S    18:15   0:00 [pm]
root        17  0.0  0.0      0     0 ?        S    18:15   0:00 [sync_supers]
root        18  0.0  0.0      0     0 ?        S    18:15   0:00 [bdi-default]
root        19  0.0  0.0      0     0 ?        S    18:15   0:00 [kintegrityd/0]
root        21  0.0  0.0      0     0 ?        S    18:15   0:00 [kblockd/0]
root        23  0.0  0.0      0     0 ?        S    18:15   0:00 [kacpid]
root        24  0.0  0.0      0     0 ?        S    18:15   0:01 [kacpi_notify]
root        25  0.0  0.0      0     0 ?        S    18:15   0:00 [kacpi_hotplug]
root        26  0.0  0.0      0     0 ?        S    18:15   0:00 [ata_aux]
root        27  0.0  0.0      0     0 ?        S    18:15   0:00 [ata_sff/0]
root        29  0.0  0.0      0     0 ?        S    18:15   0:00 [khubd]
root        30  0.0  0.0      0     0 ?        S    18:15   0:00 [kseriod]
root        31  0.0  0.0      0     0 ?        S    18:15   0:00 [kmmcd]
root        32  0.0  0.0      0     0 ?        S    18:15   0:00 [khungtaskd]
root        33  0.0  0.0      0     0 ?        S    18:15   0:00 [kswapd0]
root        34  0.0  0.0      0     0 ?        SN   18:15   0:00 [ksmd]
root        35  0.0  0.0      0     0 ?        S    18:15   0:00 [aio/0]
root        37  0.0  0.0      0     0 ?        S    18:15   0:00 [ecryptfs-kthrea]
root        38  0.0  0.0      0     0 ?        S    18:15   0:00 [crypto/0]
root        46  0.0  0.0      0     0 ?        S    18:15   0:00 [kstriped]
root        47  0.0  0.0      0     0 ?        S    18:15   0:00 [kmpathd/0]
root        49  0.0  0.0      0     0 ?        S    18:15   0:00 [kmpath_handlerd]
root        50  0.0  0.0      0     0 ?        S    18:15   0:00 [ksnapd]
root        51  0.1  0.0      0     0 ?        S    18:15   0:14 [kondemand/0]
root        53  0.0  0.0      0     0 ?        S    18:15   0:00 [kconservative/0]
.......

This is a list of the processes running on the system. The information comes from the /proc filesystem . Note that init is process number one. There is something strange here though: notice that in both the virtual storage size (SIZE) and the Real Storage Size (RSS) columns, these processes have zeroes. How can a process use no memory?

These processes are the kernel daemons. Most of the kernel does not show up on process lists at all, and you can only work out what memory it is using by subtracting the memory available from the amount on your system. The kernel daemons are started after init, so they get process numbers like normal processes do. But their code and data lives in the kernel’s part of the memory.

There are brackets around the entries in the command column because the /proc filesystem does not contain command line information for these processes.

Good Web Resources

http://www.win.tue.nl/~aeb/linux/lk/lk.html#toc9

http://lwn.net/

https://events.linuxfoundation.org/events/linuxcon/slides

http://lennartb.home.xs4all.nl/bootloaders/node3.html

http://www.ibm.com/developerworks/library/l-linuxboot/index.html

http://users.cecs.anu.edu.au/~okeefe/p2b/power2bash/power2bash.html

http://www.bglug.ca/articles/linux_boot_process.pdf

Leave a comment