kernel module example: proc file create/remove

In kernel debug, this is very common to export the proc fs interface.

This example just create/remove one directory under /proc.
kernel module example: add a module parameter

In kernel module, there is a way to setup some parameters, which are used to
control the behavior of this module.

The usage is:
    insmode hello_world.ko num=5
kernel module example: one example to trigger an oops

This is an obvious bug, pointer is set to NULL. When this module is inserted,
we will see this error log:

 BUG: unable to handle kernel NULL pointer dereference at   (null)
 IP: [<f856500a>] oops_example_init+0xa/0x20 [oops]
 *pde = 00000000
 Oops: 0002 [#1] SMP
 Modules linked in: oops(O+) bnep rfcomm bluetooth ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables xt_limit ip6t_REJECT xt_tcpudp ip6t_ah nf_conntrack_ipv6 nf_defrag_ipv6 xt_state ip6table_filter ip6_tables x_tables hdaps(O) thinkpad_ec(O) usb_storage uas parport_pc ppdev nfsd nfs_acl auth_rpcgss nfs fscache lockd binfmt_misc sunrpc dm_round_robin coretemp kvm_intel snd_hda_codec_hdmi kvm snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_pcm thinkpad_acpi snd_seq_midi snd_rawmidi nvidia(PO) snd_seq_midi_event snd_seq mei joydev snd_timer snd_seq_device snd lpc_ich snd_page_alloc soundcore microcode dm_multipath psmouse nvram serio_raw nf_conntrack_ftp nf_conntrack tpm_tis lp parport dm_crypt raid10 raid456 async_raid6_recov async_pq raid6_pq async_xor xor async_memcpy async_tx raid1 raid0 multipath linear dm_mirror dm_region_hash dm_log aesni_intel ablk_helper cryptd aes_i586 wmi sdhci_pci sdhci video e1000e
 Pid: 13383, comm: insmod Tainted: P        W  O 3.6.0+ #4 LENOVO 4180A65/4180A65
 EIP: 0060:[<f856500a>] EFLAGS: 00010246 CPU: 0
 EIP is at oops_example_init+0xa/0x20 [oops]
 EAX: 00000000 EBX: f8567000 ECX: 00000000 EDX: 00000001
 ESI: 000002a8 EDI: 00000001 EBP: db117eec ESP: db117eec
  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
 CR0: 8005003b CR2: 00000000 CR3: 31f96000 CR4: 000407d0
 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
 DR6: ffff0ff0 DR7: 00000400
 Process insmod (pid: 13383, ti=db116000 task=db16cb60 task.ti=db116000)
 Stack:
  db117f1c c1001124 00000002 00000000 00000000 00000000 f8567000 f8565000
  00000000 f8567000 000002a8 00000001 db117fac c10926f8 000002a8 c17bd1c8
  00000000 c1734c59 f856700c f1d9befc f85680ae 00000006 f85b0230 00000000
 Call Trace:
  [<c1001124>] do_one_initcall+0x34/0x170
  [<f8565000>] ? 0xf8564fff
  [<c10926f8>] sys_init_module+0x2c8/0x1af0
  [<c156a8df>] sysenter_do_call+0x12/0x28
 Code: <c7> 05 00 00 00 00 01 00 00 00 5d c3 8d 76 00 8d bc 27 00 00 00 00
 EIP: [<f856500a>] oops_example_init+0xa/0x20 [oops] SS:ESP 0068:db117eec
 CR2: 0000000000000000
 ---[ end trace 4a03a052b59f484d ]---

First we can see the error happens at EIP is at oops_example_init+0xa/0x20
[oops].

Then use objdump -S oops_example.o to dump out the object.

objdump -S oops_example.o

oops_example.o:     file format elf32-i386

Disassembly of section .text:

00000000 <init_module>:
MODULE_LICENSE("Dual BSD/GPL");

static int oops_example_init(void)
{
   0:	55                   	push   %ebp
   1:	89 e5                	mov    %esp,%ebp
   3:	e8 fc ff ff ff       	call   4 <init_module+0x4>
	int *p = NULL;
	*p = 1;
        return 0;
}
   8:	31 c0                	xor    %eax,%eax
MODULE_LICENSE("Dual BSD/GPL");

static int oops_example_init(void)
{
	int *p = NULL;
	*p = 1;
   a:	c7 05 00 00 00 00 01 	movl   $0x1,0x0
  11:	00 00 00
        return 0;
}
  14:	5d                   	pop    %ebp
  15:	c3                   	ret
  16:	8d 76 00             	lea    0x0(%esi),%esi
  19:	8d bc 27 00 00 00 00 	lea    0x0(%edi,%eiz,1),%edi

00000020 <cleanup_module>:
static void oops_example_exit(void)
{
  20:	55                   	push   %ebp
  21:	89 e5                	mov    %esp,%ebp
  23:	e8 fc ff ff ff       	call   24 <cleanup_module+0x4>
}
  28:	5d                   	pop    %ebp
  29:	c3                   	ret

From the output, we locate the oops_example_init+0xa is the movl instruction.