kset学习demo以及Oops反汇编objdump调试例子【原创】
写一个main.c
gcc -c -g main.c
objdump -S main.o > b.txt
arm-none-linux-gnueabi-gcc -c -g a.c
arm-none-linux-gnueabi-objdump -S a.o > c.txt
这样就可以查看到c和汇编同时产生
demo1:
obj-m := kmod-demo1.o
MAKEOPT := ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
#CFLAGS := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE}
ARM_LINUX_KERNEL := /home/zhangbh/Prolin_os/si/Prolin/firmware_cygnus/build_dir/linux-brcm5830_sxxx-prolin2/linux-3.6.5
ccflags-y :=-g
PWD = $(shell pwd)
all: $(MAKE) $(MAKEOPT) -C $(ARM_LINUX_KERNEL) M=$(PWD) modules .PHONY: clean clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions Module.symvers .Makefile.swp modules.order
#include <linux/device.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/string.h> #include <linux/sysfs.h> #include <linux/stat.h> #include <linux/kobject.h> #if 1 #define RESETCOLOR "\033[0m" #define GREEN "\033[0;32m" #define RED "\033[0;31m" #define YELLOW "\033[1;33m" #define BLUE "\033[0;34m" #endif //DEBUG_PRINT(RED"cpu_restart_func."RESETCOLOR"\n"); struct kset kset_p; struct kset kset_c; int my_kset_filter(struct kset *kset, struct kobject *kobj) { printk(YELLOW"Filter: kobj %s"RESETCOLOR"\n", kobj->name); //printk("Filter: kobj %s\n", kobj->name); return 1; } const char *my_kset_name(struct kset *kset, struct kobject *kobj) { static char buf[20]; printk(YELLOW"Name: kobj %s"RESETCOLOR"\n", kobj->name); //printk("Name: kobj %s\n", kobj->name); sprintf(buf, "%s", "kset_name"); return buf; } int my_kset_uevent(struct kset *kset, struct kobject *kobj,struct kobj_uevent_env *env) { int i = 0; //printk("===my_kset_uevent===\n"); printk(YELLOW"uevent: kobj %s"RESETCOLOR"\n", kobj->name); //printk("uevent: kobj %s\n", kobj->name); while (i < env->envp_idx) { //printk(YELLOW"%s"RESETCOLOR"\n", env->envp[i]); printk("%s\n", env->envp[i]); i++; } return 0; } struct kset_uevent_ops my_uevent_ops = { .filter = my_kset_filter, .name = my_kset_name, .uevent = my_kset_uevent, }; struct kobj_type my_kobj_type; static int __init my_kset_init(void) { //printk("\033[1;33;40m kset_test_init \033[0m\r\n"); printk(YELLOW"kset_test_init"RESETCOLOR"\n"); // printk("===my_kset_init===\n"); kobject_set_name(&kset_p.kobj, "kset_p_zhangbh"); kset_p.uevent_ops = &my_uevent_ops; kset_p.kobj.ktype = &my_kobj_type; kset_register(&kset_p); kobject_set_name(&kset_c.kobj, "kset_c_zhangbh"); kset_c.kobj.kset = &kset_p; kset_c.kobj.ktype = &my_kobj_type; kset_register(&kset_c); return 0; } static void __exit my_kset_exit(void) { printk("===my_kset_exit===\n"); kset_unregister(&kset_p); kset_unregister(&kset_c); } module_init(my_kset_init); module_exit(my_kset_exit); MODULE_DESCRIPTION("kmod-demo1 driver"); MODULE_AUTHOR("zhangbh"); MODULE_LICENSE("Dual BSD/GPL");
demo2:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kobject.h>
MODULE_LICENSE("Dual BSD/GPL");
/*
* struct kset {
* struct subsystem * subsys; 所在的subsystem的指针
* struct kobj_type * ktype; 指向该kset对象类型描述符的指针
* struct list_head list; 用于连接该kset中所有kobject的链表头
* struct kobject kobj; 嵌入的kobject
* struct kset_uevent_ops *uevent_ops; 指向热插拔操作表的指针
* };
*/
struct kset my_kset_parent;
struct kset my_kset_child;
int my_kset_filter(struct kset *kset,struct kobject *kobj)
{
printk("===my_kset_filter===\n");
return 1; //返回1事事件可以上报
}
const char *my_kset_name(struct kset *kset, struct kobject *kobj )
{
static char buf[200]; //可以动态申请
printk("===my_kset_name is %s===\n", kobj->name);
sprintf(buf,"%s","what's this mean");
return buf;
}
int my_kset_uevent(struct kset *kset, struct kobject *kobj, struct kobj_uevent_env *env)
{
int i = 0;
printk("===my_kset_uevent===\n");
while(i<env->envp_idx)
{
printk("%s\n",env->envp[i++]);
}
return 0;
}
/*
* struct kset_uevnt_ops{
* int (*filter)(struct kset *kset,struct kobject *kobj);
* const char *(*name)(struct kset *kset, struct kobject *kobj );
* int (*uevent)(struct kset *kset,struct kobject *kobj,struct kobj_uevent *env);
* }
*/
struct kset_uevent_ops my_uevent_ops =
{
.filter = my_kset_filter,
.name = my_kset_name,
.uevent = my_kset_uevent,
};
struct kobj_type my_kobj_type ;
static int __init my_kset_init(void)
{
printk("===my_kset_init===\n");
kobject_set_name(&my_kset_parent.kobj,"my_keset_parent");
my_kset_parent.uevent_ops = &my_uevent_ops;
/* int kset_register(struct kset *kset); */
//下面这句多余,是为了规避kernel oops bug
my_kset_parent.kobj.ktype = &my_kobj_type;
kset_register(&my_kset_parent);
kobject_set_name(&my_kset_child.kobj,"my_kset_child");
my_kset_child.kobj.kset = &my_kset_parent;
my_kset_child.kobj.ktype = &my_kobj_type;
kset_register(&my_kset_child);
return 0;
}
static void __exit my_kset_exit(void)
{
printk("===my_kset_exit===\n");
kset_unregister(&my_kset_parent);
kset_unregister(&my_kset_child);
}
module_init(my_kset_init);
module_exit(my_kset_exit);
demo1/2需要注意:
//下面这句多余,是为了规避kernel oops bug
my_kset_parent.kobj.ktype = &my_kobj_type;
如果不加入这句的话,会报如下错误
/data/app # insmod kmod-demo1.ko [ 819.660000] [pax_verify_memory_region] verification skipped (level 2) [ 819.670000] kset_test_init [ 819.670000] Unable to handle kernel NULL pointer dereference at virtual address 0000000c [ 819.680000] pgd = de9a0000 [ 819.680000] [0000000c] *pgd=7ea5d831, *pte=00000000, *ppte=00000000 [ 819.690000] Internal error: Oops: 17 [#1] ARM [ 819.690000] Modules linked in: kmod_demo1(O+) lcd_panel_H35C65_00E(O) lcd_hw_ctrl(O) lcd_fb(O) spi(O) verify(O) asoc_bcm5830x(O) asoc_bcm5830x_i2s(O) asoc_bcm5830x_pcm(O) asoc_bcm5830x_codec_cs4344(O) tty_host(O) tty_devices(O) 5830x_usb2h(O) bcm_udc_dwc(O) misc(O) bm_mp2625gl(O) keypad_matrix(O) input_base(O) pmu_dummy(O) S820_M00_P00(O) ioconfig(O) devices_base(O) rtc(O) [ 819.690000] CPU: 0 Tainted: G O (3.6.5+ #3) [ 819.690000] PC is at kobj_child_ns_ops+0x1c/0x38 [ 819.690000] LR is at sysfs_create_dir+0x48/0xfc [ 819.690000] pc : [<c021a814>] lr : [<c010770c>] psr: a0000013 [ 819.690000] sp : dfae1df0 ip : dfae1e00 fp : dfae1dfc [ 819.690000] r10: bf0a2000 r9 : 00000184 r8 : 00000000 [ 819.690000] r7 : 00000000 r6 : c0629038 r5 : 00000000 r4 : bf0a032c [ 819.690000] r3 : 00000000 r2 : 00000001 r1 : bf0a0330 r0 : bf0a032c [ 819.690000] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user [ 819.690000] Control: 10c53c7d Table: 7e9a0059 DAC: 00000015 [ 819.690000] Process insmod (pid: 870, stack limit = 0xdfae0268) [ 819.690000] Stack: (0xdfae1df0 to 0xdfae2000) [ 819.690000] 1de0: dfae1e2c dfae1e00 c010770c c021a804 [ 819.690000] 1e00: dfae1e34 dfae1e10 c0226694 c0223d24 00000000 00000000 bf0a032c 00000001 [ 819.690000] 1e20: dfae1e64 dfae1e30 c0219e70 c01076d0 c021a30c c00b3b3c bf0a0310 bf0a0324 [ 819.690000] 1e40: 00000001 00000000 bf0a032c 00000001 00000000 00000000 dfae1e7c dfae1e68 [ 819.690000] 1e60: c021a284 c0219dfc bf0a0310 bf0a0324 dfae1e94 dfae1e80 bf0a2048 c021a240 [ 819.690000] 1e80: c064f4c0 dfae0000 dfae1eec dfae1e98 c0008638 bf0a200c c00b3c08 c048d784 [ 819.690000] 1ea0: 00000001 00000001 dea68400 00000000 dfae1edc dfae1ec0 bf0a01dc bf0a01dc [ 819.690000] 1ec0: 00000001 bf0a01dc bf0a01dc 00000001 dfaa1380 00000000 00000184 bf0a0224 [ 819.690000] 1ee0: dfae1fa4 dfae1ef0 c007e254 c0008608 bf0a01e8 00007fff c007c07c 0000005e [ 819.690000] 1f00: e0b7589c 00000000 e0b75398 e0b75394 e0b7557c bf0a0452 01acb470 bf0a01dc [ 819.690000] 1f20: e0b75000 00000f20 e0b7557c e0b754b7 e0b75d9c 00000384 00000404 00000000 [ 819.690000] 1f40: 00000000 00000013 00000014 0000000b 00000000 00000007 00000000 00000000 [ 819.690000] 1f60: 00000000 00000000 00000000 00000000 00000000 dfae1fb0 dfae1fac 01acb458 [ 819.690000] 1f80: 01acb480 01acb470 00000080 c0009be4 dfae0000 00000000 00000000 dfae1fa8 [ 819.690000] 1fa0: c0009a80 c007e198 01acb458 01acb480 01acb480 00000f20 01acb470 00000000 [ 819.690000] 1fc0: 01acb458 01acb480 01acb470 00000080 00000000 0000003e 0006874f 00000000 [ 819.690000] 1fe0: 01acb458 be8e9c34 0000cf7c 00047db0 20000010 01acb480 2000ffff 0000ffff [ 819.690000] Backtrace: [ 819.690000] [<c021a7f8>] (kobj_child_ns_ops+0x0/0x38) from [<c010770c>] (sysfs_create_dir+0x48/0xfc) [ 819.690000] [<c01076c4>] (sysfs_create_dir+0x0/0xfc) from [<c0219e70>] (kobject_add_internal+0x80/0x1f4) [ 819.690000] r6:00000001 r5:bf0a032c r4:00000000 [ 819.690000] [<c0219df0>] (kobject_add_internal+0x0/0x1f4) from [<c021a284>] (kset_register+0x50/0x6c) [ 819.690000] r8:00000000 r7:00000000 r6:00000001 r5:bf0a032c r4:00000000 [ 819.690000] [<c021a234>] (kset_register+0x0/0x6c) from [<bf0a2048>] (my_kset_init+0x48/0x6c [kmod_demo1]) [ 819.690000] r5:bf0a0324 r4:bf0a0310 [ 819.690000] [<bf0a2000>] (my_kset_init+0x0/0x6c [kmod_demo1]) from [<c0008638>] (do_one_initcall+0x3c/0x178) [ 819.690000] r5:dfae0000 r4:c064f4c0 [ 819.690000] [<c00085fc>] (do_one_initcall+0x0/0x178) from [<c007e254>] (sys_init_module+0xc8/0x1cf8) [ 819.690000] [<c007e18c>] (sys_init_module+0x0/0x1cf8) from [<c0009a80>] (ret_fast_syscall+0x0/0x30) [ 819.690000] Code: e2503000 01a00003 089da800 e5933014 (e593300c) [ 820.020000] ---[ end trace 3d8a55d9aa0462ea ]--- Segmentation fault
跟踪内核源码分析如下:
kset_register(&kset_p);
==============================>
int kset_register(struct kset *k) { int err; if (!k) return -EINVAL; kset_init(k); err = kobject_add_internal(&k->kobj); if (err) return err; kobject_uevent(&k->kobj, KOBJ_ADD); return 0; }
继续跟踪
kobject_add_internal(&k->kobj)
===============================>
static int kobject_add_internal(struct kobject *kobj) { int error = 0; struct kobject *parent; if (!kobj) return -ENOENT; if (!kobj->name || !kobj->name[0]) { WARN(1, "kobject: (%p): attempted to be registered with empty " "name!\n", kobj); return -EINVAL; } parent = kobject_get(kobj->parent); /* join kset if set, use it as parent if we do not already have one */ if (kobj->kset) { if (!parent) parent = kobject_get(&kobj->kset->kobj); kobj_kset_join(kobj); kobj->parent = parent; } pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", kobject_name(kobj), kobj, __func__, parent ? kobject_name(parent) : "<NULL>", kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>"); error = create_dir(kobj); if (error) { kobj_kset_leave(kobj); kobject_put(parent); kobj->parent = NULL; /* be noisy on error issues */ if (error == -EEXIST) WARN(1, "%s failed for %s with " "-EEXIST, don't try to register things with " "the same name in the same directory.\n", __func__, kobject_name(kobj)); else WARN(1, "%s failed for %s (error: %d parent: %s)\n", __func__, kobject_name(kobj), error, parent ? kobject_name(parent) : "'none'"); } else kobj->state_in_sysfs = 1; return error;
}
继续跟踪create_dir(kobj)
==================>
static int create_dir(struct kobject *kobj) { int error = 0; error = sysfs_create_dir(kobj); if (!error) { error = populate_dir(kobj); if (error) sysfs_remove_dir(kobj); } return error; }
跟踪
sysfs_create_dir(kobj);
============================>
/** * sysfs_create_dir - create a directory for an object. * @kobj: object we're creating directory for. */ int sysfs_create_dir(struct kobject * kobj) { enum kobj_ns_type type; struct sysfs_dirent *parent_sd, *sd; const void *ns = NULL; int error = 0; BUG_ON(!kobj); if (kobj->parent) parent_sd = kobj->parent->sd; else parent_sd = &sysfs_root; if (!parent_sd) return -ENOENT; if (sysfs_ns_type(parent_sd)) ns = kobj->ktype->namespace(kobj); type = sysfs_read_ns_type(kobj); error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd); if (!error) kobj->sd = sd; return error; }
这下大家看懂了吧,直接操作了指针ktype,相当于操作了空指针
然后我反汇编调试,可打印Oops的信息
arm-none-linux-gnueabi-objdump -DfhS kmod-demo1.o > b.txt
b.txt文档信息如下:
1 kmod-demo1.o: file format elf32-littlearm 2 architecture: arm, flags 0x00000011: 3 HAS_RELOC, HAS_SYMS 4 start address 0x00000000 5 6 Sections: 7 Idx Name Size VMA LMA File off Algn 8 0 .text 000000c4 00000000 00000000 00000034 2**2 9 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 10 1 .data 0000000c 00000000 00000000 000000f8 2**2 11 CONTENTS, ALLOC, LOAD, RELOC, DATA 12 2 .bss 00000088 00000000 00000000 00000104 2**2 13 ALLOC 14 3 .init.text 00000078 00000000 00000000 00000104 2**2 15 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 16 4 .exit.text 00000034 00000000 00000000 0000017c 2**2 17 CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE 18 5 .modinfo 00000042 00000000 00000000 000001b0 2**0 19 CONTENTS, ALLOC, LOAD, READONLY, DATA 20 6 .rodata.str1.4 000000b4 00000000 00000000 000001f4 2**2 21 CONTENTS, ALLOC, LOAD, READONLY, DATA 22 7 .comment 00000031 00000000 00000000 000002a8 2**0 23 CONTENTS, READONLY 24 8 .note.GNU-stack 00000000 00000000 00000000 000002d9 2**0 25 CONTENTS, READONLY 26 9 .ARM.attributes 00000031 00000000 00000000 000002d9 2**0 27 CONTENTS, READONLY 28 29 Disassembly of section .text: 30 31 00000000 <my_kset_uevent>: 32 0: e1a0c00d mov ip, sp 33 4: e92dd878 push {r3, r4, r5, r6, fp, ip, lr, pc} 34 8: e24cb004 sub fp, ip, #4 35 c: e3000000 movw r0, #0 36 10: e1a06002 mov r6, r2 37 14: e5911000 ldr r1, [r1] 38 18: e3400000 movt r0, #0 39 1c: ebfffffe bl 0 <printk> 40 20: e5963080 ldr r3, [r6, #128] ; 0x80 41 24: e3530000 cmp r3, #0 42 28: da000009 ble 54 <my_kset_uevent+0x54> 43 2c: e2465004 sub r5, r6, #4 44 30: e3a04000 mov r4, #0 45 34: e3000000 movw r0, #0 46 38: e5b51004 ldr r1, [r5, #4]! 47 3c: e3400000 movt r0, #0 48 40: e2844001 add r4, r4, #1 49 44: ebfffffe bl 0 <printk> 50 48: e5960080 ldr r0, [r6, #128] ; 0x80 51 4c: e1500004 cmp r0, r4 52 50: cafffff7 bgt 34 <my_kset_uevent+0x34> 53 54: e3a00000 mov r0, #0 54 58: e89da878 ldm sp, {r3, r4, r5, r6, fp, sp, pc} 55 56 0000005c <my_kset_filter>: 57 5c: e1a0c00d mov ip, sp 58 60: e92dd800 push {fp, ip, lr, pc} 59 64: e24cb004 sub fp, ip, #4 60 68: e3000000 movw r0, #0 61 6c: e5911000 ldr r1, [r1] 62 70: e3400000 movt r0, #0 63 74: ebfffffe bl 0 <printk> 64 78: e3a00001 mov r0, #1 65 7c: e89da800 ldm sp, {fp, sp, pc} 66 67 00000080 <my_kset_name>: 68 80: e1a0c00d mov ip, sp 69 84: e92dd800 push {fp, ip, lr, pc} 70 88: e24cb004 sub fp, ip, #4 71 8c: e3000000 movw r0, #0 72 90: e5911000 ldr r1, [r1] 73 94: e3400000 movt r0, #0 74 98: ebfffffe bl 0 <printk> 75 9c: e3000000 movw r0, #0 76 a0: e3400000 movt r0, #0 77 a4: e300c000 movw ip, #0 78 a8: e340c000 movt ip, #0 79 ac: e8900007 ldm r0, {r0, r1, r2} 80 b0: e1a0300c mov r3, ip 81 b4: e8a30003 stmia r3!, {r0, r1} 82 b8: e1a0000c mov r0, ip 83 bc: e1c320b0 strh r2, [r3] 84 c0: e89da800 ldm sp, {fp, sp, pc} 85 86 Disassembly of section .data: 87 88 00000000 <my_uevent_ops>: 89 ... 90 91 Disassembly of section .bss: 92 93 00000000 <buf.12100>: 94 ... 95 96 00000014 <kset_p>: 97 ... 98 99 00000044 <my_kobj_type>: 100 ... 101 102 00000058 <kset_c>: 103 ... 104 105 Disassembly of section .init.text: 106 107 00000000 <init_module>: 108 0: e1a0c00d mov ip, sp 109 4: e92dd878 push {r3, r4, r5, r6, fp, ip, lr, pc} 110 8: e24cb004 sub fp, ip, #4 111 c: e3004000 movw r4, #0 112 10: e3404000 movt r4, #0 113 14: e2846014 add r6, r4, #20 114 18: e3000000 movw r0, #0 115 1c: e3400000 movt r0, #0 116 20: e2845044 add r5, r4, #68 ; 0x44 117 24: ebfffffe bl 0 <printk> 118 28: e284001c add r0, r4, #28 119 2c: e3001000 movw r1, #0 120 30: e3401000 movt r1, #0 121 34: ebfffffe bl 0 <kobject_set_name> 122 38: e1a00006 mov r0, r6 123 3c: e5845030 str r5, [r4, #48] ; 0x30 124 40: e3003000 movw r3, #0 125 44: e3403000 movt r3, #0 126 48: e5843040 str r3, [r4, #64] ; 0x40 127 4c: ebfffffe bl 0 <kset_register> 128 50: e2840060 add r0, r4, #96 ; 0x60 129 54: e3001000 movw r1, #0 130 58: e3401000 movt r1, #0 131 5c: ebfffffe bl 0 <kobject_set_name> 132 60: e2840058 add r0, r4, #88 ; 0x58 133 64: e5846070 str r6, [r4, #112] ; 0x70 134 68: e5845074 str r5, [r4, #116] ; 0x74 135 6c: ebfffffe bl 0 <kset_register> 136 70: e3a00000 mov r0, #0 137 74: e89da878 ldm sp, {r3, r4, r5, r6, fp, sp, pc} 138 139 Disassembly of section .exit.text: 140 141 00000000 <cleanup_module>: 142 0: e1a0c00d mov ip, sp 143 4: e92dd818 push {r3, r4, fp, ip, lr, pc} 144 8: e24cb004 sub fp, ip, #4 145 c: e3000000 movw r0, #0 146 10: e3004000 movw r4, #0 147 14: e3400000 movt r0, #0 148 18: e3404000 movt r4, #0 149 1c: ebfffffe bl 0 <printk> 150 20: e2840014 add r0, r4, #20 151 24: ebfffffe bl 0 <kset_unregister> 152 28: e2840058 add r0, r4, #88 ; 0x58 153 2c: ebfffffe bl 0 <kset_unregister> 154 30: e89da818 ldm sp, {r3, r4, fp, sp, pc} 155 156 Disassembly of section .modinfo: 157 158 00000000 <__mod_license95>: 159 0: 6563696c strbvs r6, [r3, #-2412]! ; 0xfffff694 160 4: 3d65736e stclcc 3, cr7, [r5, #-440]! ; 0xfffffe48 161 8: 6c617544 cfstr64vs mvdx7, [r1], #-272 ; 0xfffffef0 162 c: 44534220 ldrbmi r4, [r3], #-544 ; 0xfffffde0 163 10: 4c50472f mrrcmi 7, 2, r4, r0, cr15 164 ... 165 166 00000015 <__mod_author94>: 167 15: 68747561 ldmdavs r4!, {r0, r5, r6, r8, sl, ip, sp, lr}^ 168 19: 7a3d726f bvc f5c9dd <.LC8+0xf5c93d> 169 1d: 676e6168 strbvs r6, [lr, -r8, ror #2]! 170 21: 64006862 strvs r6, [r0], #-2146 ; 0xfffff79e 171 172 00000024 <__mod_description93>: 173 24: 63736564 cmnvs r3, #100, 10 ; 0x19000000 174 28: 74706972 ldrbtvc r6, [r0], #-2418 ; 0xfffff68e 175 2c: 3d6e6f69 stclcc 15, cr6, [lr, #-420]! ; 0xfffffe5c 176 30: 646f6d6b strbtvs r6, [pc], #-3435 ; 38 <__mod_description93+0x14> 177 34: 6d65642d cfstrdvs mvd6, [r5, #-180]! ; 0xffffff4c 178 38: 6420316f strtvs r3, [r0], #-367 ; 0xfffffe91 179 3c: 65766972 ldrbvs r6, [r6, #-2418]! ; 0xfffff68e 180 40: Address 0x00000040 is out of bounds. 181 182 183 Disassembly of section .rodata.str1.4: 184 185 00000000 <.LC0>: 186 0: 3b315b1b blcc c56c74 <.LC8+0xc56bd4> 187 4: 756d3333 strbvc r3, [sp, #-819]! ; 0xfffffccd 188 8: 6e657665 cdpvs 6, 6, cr7, cr5, cr5, {3} 189 c: 6b203a74 blvs 80e9e4 <.LC8+0x80e944> 190 10: 206a626f rsbcs r6, sl, pc, ror #4 191 14: 5b1b7325 blpl 6dccb0 <.LC8+0x6dcc10> 192 18: 000a6d30 andeq r6, sl, r0, lsr sp 193 194 0000001c <.LC1>: 195 1c: 000a7325 andeq r7, sl, r5, lsr #6 196 197 00000020 <.LC2>: 198 20: 3b315b1b blcc c56c94 <.LC8+0xc56bf4> 199 24: 466d3333 ; <UNDEFINED> instruction: 0x466d3333 200 28: 65746c69 ldrbvs r6, [r4, #-3177]! ; 0xfffff397 201 2c: 6b203a72 blvs 80e9fc <.LC8+0x80e95c> 202 30: 206a626f rsbcs r6, sl, pc, ror #4 203 34: 5b1b7325 blpl 6dccd0 <.LC8+0x6dcc30> 204 38: 000a6d30 andeq r6, sl, r0, lsr sp 205 206 0000003c <.LC3>: 207 3c: 3b315b1b blcc c56cb0 <.LC8+0xc56c10> 208 40: 4e6d3333 mcrmi 3, 3, r3, cr13, cr3, {1} 209 44: 3a656d61 bcc 195b5d0 <.LC8+0x195b530> 210 48: 626f6b20 rsbvs r6, pc, #32, 22 ; 0x8000 211 4c: 7325206a teqvc r5, #106 ; 0x6a 212 50: 6d305b1b fldmdbxvs r0!, {d5-d17} ;@ Deprecated 213 54: 0000000a andeq r0, r0, sl 214 215 00000058 <.LC4>: 216 58: 7465736b strbtvc r7, [r5], #-875 ; 0xfffffc95 217 5c: 6d616e5f stclvs 14, cr6, [r1, #-380]! ; 0xfffffe84 218 60: 00000065 andeq r0, r0, r5, rrx 219 220 00000064 <.LC5>: 221 64: 3b315b1b blcc c56cd8 <.LC8+0xc56c38> 222 68: 6b6d3333 blvs 1b4cd3c <.LC8+0x1b4cc9c> 223 6c: 5f746573 svcpl 0x00746573 224 70: 74736574 ldrbtvc r6, [r3], #-1396 ; 0xfffffa8c 225 74: 696e695f stmdbvs lr!, {r0, r1, r2, r3, r4, r6, r8, fp, sp, lr}^ 226 78: 305b1b74 subscc r1, fp, r4, ror fp 227 7c: 00000a6d andeq r0, r0, sp, ror #20 228 229 00000080 <.LC6>: 230 80: 7465736b strbtvc r7, [r5], #-875 ; 0xfffffc95 231 84: 7a5f705f bvc 17dc208 <.LC8+0x17dc168> 232 88: 676e6168 strbvs r6, [lr, -r8, ror #2]! 233 8c: 00006862 andeq r6, r0, r2, ror #16 234 235 00000090 <.LC7>: 236 90: 7465736b strbtvc r7, [r5], #-875 ; 0xfffffc95 237 94: 7a5f635f bvc 17d8e18 <.LC8+0x17d8d78> 238 98: 676e6168 strbvs r6, [lr, -r8, ror #2]! 239 9c: 00006862 andeq r6, r0, r2, ror #16 240 241 000000a0 <.LC8>: 242 a0: 6d3d3d3d ldcvs 13, cr3, [sp, #-244]! ; 0xffffff0c 243 a4: 736b5f79 cmnvc fp, #484 ; 0x1e4 244 a8: 655f7465 ldrbvs r7, [pc, #-1125] ; fffffc4b <.LC8+0xfffffbab> 245 ac: 3d746978 ldclcc 9, cr6, [r4, #-480]! ; 0xfffffe20 246 b0: 000a3d3d andeq r3, sl, sp, lsr sp 247 248 Disassembly of section .comment: 249 250 00000000 <.comment>: 251 0: 43434700 movtmi r4, #14080 ; 0x3700 252 4: 5328203a teqpl r8, #58 ; 0x3a 253 8: 6372756f cmnvs r2, #465567744 ; 0x1bc00000 254 c: 20797265 rsbscs r7, r9, r5, ror #4 255 10: 65646f43 strbvs r6, [r4, #-3907]! ; 0xfffff0bd 256 14: 636e6542 cmnvs lr, #276824064 ; 0x10800000 257 18: 694c2068 stmdbvs ip, {r3, r5, r6, sp}^ 258 1c: 32206574 eorcc r6, r0, #116, 10 ; 0x1d000000 259 20: 2e323130 mrccs 1, 1, r3, cr2, cr0, {1} 260 24: 352d3330 strcc r3, [sp, #-816]! ; 0xfffffcd0 261 28: 34202937 strtcc r2, [r0], #-2359 ; 0xfffff6c9 262 2c: 332e362e teqcc lr, #48234496 ; 0x2e00000 263 ... 264 265 Disassembly of section .ARM.attributes: 266 267 00000000 <.ARM.attributes>: 268 0: 00003041 andeq r3, r0, r1, asr #32 269 4: 61656100 cmnvs r5, r0, lsl #2 270 8: 01006962 tsteq r0, r2, ror #18 271 c: 00000026 andeq r0, r0, r6, lsr #32 272 10: 412d3705 teqmi sp, r5, lsl #14 273 14: 070a0600 streq r0, [sl, -r0, lsl #12] 274 18: 09010841 stmdbeq r1, {r0, r6, fp} 275 1c: 14041202 strne r1, [r4], #-514 ; 0xfffffdfe 276 20: 17011501 strne r1, [r1, -r1, lsl #10] 277 24: 19011803 stmdbne r1, {r0, r1, fp, ip} 278 28: 1e021a01 vmlane.f32 s2, s4, s2 279 2c: 2c012202 sfmcs f2, 4, [r1], {2} 280 30: Address 0x00000030 is out of bounds.
makefile中加入了调试选项ccflags-y :=-g的话,
反汇编的时候就可以c语言和汇编语言一起显示
arm-none-linux-gnueabi-objdump -S kmod-demo1.o > c.txt
kmod-demo1.o: file format elf32-littlearm Disassembly of section .text: 00000000 <my_kset_uevent>: return buf; } int my_kset_uevent(struct kset *kset, struct kobject *kobj,struct kobj_uevent_env *env) { 0: e1a0c00d mov ip, sp 4: e92dd878 push {r3, r4, r5, r6, fp, ip, lr, pc} 8: e24cb004 sub fp, ip, #4 int i = 0; //printk("===my_kset_uevent===\n"); printk(YELLOW"uevent: kobj %s"RESETCOLOR"\n", kobj->name); c: e3000000 movw r0, #0 return buf; } int my_kset_uevent(struct kset *kset, struct kobject *kobj,struct kobj_uevent_env *env) { 10: e1a06002 mov r6, r2 int i = 0; //printk("===my_kset_uevent===\n"); printk(YELLOW"uevent: kobj %s"RESETCOLOR"\n", kobj->name); 14: e5911000 ldr r1, [r1] 18: e3400000 movt r0, #0 1c: ebfffffe bl 0 <printk> //printk("uevent: kobj %s\n", kobj->name); while (i < env->envp_idx) { 20: e5963080 ldr r3, [r6, #128] ; 0x80 24: e3530000 cmp r3, #0 28: da000009 ble 54 <my_kset_uevent+0x54> sprintf(buf, "%s", "kset_name"); return buf; } int my_kset_uevent(struct kset *kset, struct kobject *kobj,struct kobj_uevent_env *env) 2c: e2465004 sub r5, r6, #4 { int i = 0; 30: e3a04000 mov r4, #0 //printk("===my_kset_uevent===\n"); printk(YELLOW"uevent: kobj %s"RESETCOLOR"\n", kobj->name); //printk("uevent: kobj %s\n", kobj->name); while (i < env->envp_idx) { //printk(YELLOW"%s"RESETCOLOR"\n", env->envp[i]); printk("%s\n", env->envp[i]); 34: e3000000 movw r0, #0 38: e5b51004 ldr r1, [r5, #4]! 3c: e3400000 movt r0, #0 i++; 40: e2844001 add r4, r4, #1 //printk("===my_kset_uevent===\n"); printk(YELLOW"uevent: kobj %s"RESETCOLOR"\n", kobj->name); //printk("uevent: kobj %s\n", kobj->name); while (i < env->envp_idx) { //printk(YELLOW"%s"RESETCOLOR"\n", env->envp[i]); printk("%s\n", env->envp[i]); 44: ebfffffe bl 0 <printk> { int i = 0; //printk("===my_kset_uevent===\n"); printk(YELLOW"uevent: kobj %s"RESETCOLOR"\n", kobj->name); //printk("uevent: kobj %s\n", kobj->name); while (i < env->envp_idx) { 48: e5960080 ldr r0, [r6, #128] ; 0x80 4c: e1500004 cmp r0, r4 50: cafffff7 bgt 34 <my_kset_uevent+0x34> printk("%s\n", env->envp[i]); i++; } return 0; } 54: e3a00000 mov r0, #0 58: e89da878 ldm sp, {r3, r4, r5, r6, fp, sp, pc} 0000005c <my_kset_filter>: struct kset kset_p; struct kset kset_c; int my_kset_filter(struct kset *kset, struct kobject *kobj) { 5c: e1a0c00d mov ip, sp 60: e92dd800 push {fp, ip, lr, pc} 64: e24cb004 sub fp, ip, #4 printk(YELLOW"Filter: kobj %s"RESETCOLOR"\n", kobj->name); 68: e3000000 movw r0, #0 6c: e5911000 ldr r1, [r1] 70: e3400000 movt r0, #0 74: ebfffffe bl 0 <printk> //printk("Filter: kobj %s\n", kobj->name); return 1; } 78: e3a00001 mov r0, #1 7c: e89da800 ldm sp, {fp, sp, pc} 00000080 <my_kset_name>: const char *my_kset_name(struct kset *kset, struct kobject *kobj) { 80: e1a0c00d mov ip, sp 84: e92dd800 push {fp, ip, lr, pc} 88: e24cb004 sub fp, ip, #4 static char buf[20]; printk(YELLOW"Name: kobj %s"RESETCOLOR"\n", kobj->name); 8c: e3000000 movw r0, #0 90: e5911000 ldr r1, [r1] 94: e3400000 movt r0, #0 98: ebfffffe bl 0 <printk> //printk("Name: kobj %s\n", kobj->name); sprintf(buf, "%s", "kset_name"); 9c: e3000000 movw r0, #0 a0: e3400000 movt r0, #0 a4: e300c000 movw ip, #0 a8: e340c000 movt ip, #0 ac: e8900007 ldm r0, {r0, r1, r2} b0: e1a0300c mov r3, ip b4: e8a30003 stmia r3!, {r0, r1} return buf; } b8: e1a0000c mov r0, ip { static char buf[20]; printk(YELLOW"Name: kobj %s"RESETCOLOR"\n", kobj->name); //printk("Name: kobj %s\n", kobj->name); sprintf(buf, "%s", "kset_name"); bc: e1c320b0 strh r2, [r3] return buf; } c0: e89da800 ldm sp, {fp, sp, pc} Disassembly of section .init.text: 00000000 <init_module>: struct kobj_type my_kobj_type; static int __init my_kset_init(void) { 0: e1a0c00d mov ip, sp 4: e92dd878 push {r3, r4, r5, r6, fp, ip, lr, pc} 8: e24cb004 sub fp, ip, #4 //printk("\033[1;33;40m kset_test_init \033[0m\r\n"); printk(YELLOW"kset_test_init"RESETCOLOR"\n"); // printk("===my_kset_init===\n"); kobject_set_name(&kset_p.kobj, "kset_p_zhangbh"); c: e3004000 movw r4, #0 10: e3404000 movt r4, #0 14: e2846014 add r6, r4, #20 struct kobj_type my_kobj_type; static int __init my_kset_init(void) { //printk("\033[1;33;40m kset_test_init \033[0m\r\n"); printk(YELLOW"kset_test_init"RESETCOLOR"\n"); 18: e3000000 movw r0, #0 1c: e3400000 movt r0, #0 // printk("===my_kset_init===\n"); kobject_set_name(&kset_p.kobj, "kset_p_zhangbh"); kset_p.uevent_ops = &my_uevent_ops; kset_p.kobj.ktype = &my_kobj_type; 20: e2845044 add r5, r4, #68 ; 0x44 struct kobj_type my_kobj_type; static int __init my_kset_init(void) { //printk("\033[1;33;40m kset_test_init \033[0m\r\n"); printk(YELLOW"kset_test_init"RESETCOLOR"\n"); 24: ebfffffe bl 0 <printk> // printk("===my_kset_init===\n"); kobject_set_name(&kset_p.kobj, "kset_p_zhangbh"); 28: e284001c add r0, r4, #28 2c: e3001000 movw r1, #0 30: e3401000 movt r1, #0 34: ebfffffe bl 0 <kobject_set_name> kset_p.uevent_ops = &my_uevent_ops; kset_p.kobj.ktype = &my_kobj_type; kset_register(&kset_p); 38: e1a00006 mov r0, r6 //printk("\033[1;33;40m kset_test_init \033[0m\r\n"); printk(YELLOW"kset_test_init"RESETCOLOR"\n"); // printk("===my_kset_init===\n"); kobject_set_name(&kset_p.kobj, "kset_p_zhangbh"); kset_p.uevent_ops = &my_uevent_ops; kset_p.kobj.ktype = &my_kobj_type; 3c: e5845030 str r5, [r4, #48] ; 0x30 { //printk("\033[1;33;40m kset_test_init \033[0m\r\n"); printk(YELLOW"kset_test_init"RESETCOLOR"\n"); // printk("===my_kset_init===\n"); kobject_set_name(&kset_p.kobj, "kset_p_zhangbh"); kset_p.uevent_ops = &my_uevent_ops; 40: e3003000 movw r3, #0 44: e3403000 movt r3, #0 48: e5843040 str r3, [r4, #64] ; 0x40 kset_p.kobj.ktype = &my_kobj_type; kset_register(&kset_p); 4c: ebfffffe bl 0 <kset_register> kobject_set_name(&kset_c.kobj, "kset_c_zhangbh"); 50: e2840060 add r0, r4, #96 ; 0x60 54: e3001000 movw r1, #0 58: e3401000 movt r1, #0 5c: ebfffffe bl 0 <kobject_set_name> kset_c.kobj.kset = &kset_p; kset_c.kobj.ktype = &my_kobj_type; kset_register(&kset_c); 60: e2840058 add r0, r4, #88 ; 0x58 kset_p.uevent_ops = &my_uevent_ops; kset_p.kobj.ktype = &my_kobj_type; kset_register(&kset_p); kobject_set_name(&kset_c.kobj, "kset_c_zhangbh"); kset_c.kobj.kset = &kset_p; 64: e5846070 str r6, [r4, #112] ; 0x70 kset_c.kobj.ktype = &my_kobj_type; 68: e5845074 str r5, [r4, #116] ; 0x74 kset_register(&kset_c); 6c: ebfffffe bl 0 <kset_register> return 0; } 70: e3a00000 mov r0, #0 74: e89da878 ldm sp, {r3, r4, r5, r6, fp, sp, pc} Disassembly of section .exit.text: 00000000 <cleanup_module>: static void __exit my_kset_exit(void) { 0: e1a0c00d mov ip, sp 4: e92dd818 push {r3, r4, fp, ip, lr, pc} 8: e24cb004 sub fp, ip, #4 printk("===my_kset_exit===\n"); c: e3000000 movw r0, #0 kset_unregister(&kset_p); 10: e3004000 movw r4, #0 return 0; } static void __exit my_kset_exit(void) { printk("===my_kset_exit===\n"); 14: e3400000 movt r0, #0 kset_unregister(&kset_p); 18: e3404000 movt r4, #0 return 0; } static void __exit my_kset_exit(void) { printk("===my_kset_exit===\n"); 1c: ebfffffe bl 0 <printk> kset_unregister(&kset_p); 20: e2840014 add r0, r4, #20 24: ebfffffe bl 0 <kset_unregister> kset_unregister(&kset_c); 28: e2840058 add r0, r4, #88 ; 0x58 2c: ebfffffe bl 0 <kset_unregister> } 30: e89da818 ldm sp, {r3, r4, fp, sp, pc}
如有转载请注明出处
新浪博客:http://blog.sina.com.cn/u/2049150530
博客园:http://www.cnblogs.com/sky-heaven/
知乎:http://www.zhihu.com/people/zhang-bing-hua
部分资料来源:http://www.cnblogs.com/sky-zhang/archive/2012/05/28/2521497.html