2016-04-15 6 views
1

Woher weiß ich vor dem Zuweisen, wie groß von einem Array kann ich erstellen? Oder wie positioniere ich mein Array so, dass es nicht mit etwas in der Memory Map kollidiert?maximale Zeiger/Array-Größe in Linux-Kernel-Modul

Ich habe diese Konfiguration

VM running on Virtualbox with 
Operating system: Centos 7 
Memory: 2GB 
Processor: [email protected],9Ghz 
Host OS: Suse Leap 41 

Und ich habe diesen Code:

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/kernel.h> 

MODULE_DESCRIPTION("linux module"); 
MODULE_AUTHOR ("doald duck"); 

static int __init KM() { 
    size = 100000; 
    size = 10*100000; 
    printk("creating an int aray of %d 1st ....\n",size); 

    int ia [size]; 
    int ia_ = -1; 
    while (++ia_ < size){ 
     ia [ia_] = ia_ +2000; 
    } 
    return 0; 
} 

static void __exit _KM() { 
    printk ("unloading 'za module "); 
} 

module_init (KM); 
module_exit (_KM); 

wenn Größe bei 100000 bleibt; Das Modul wird geladen und rmmod funktioniert perfekt .. wenn ich irgendwie Größe tun = 10 * 100000 dann passiert, und starten Sie ist

Rufverfolgung Panik Kern:

[ 155.751747] creating an aray of 1000000 1st .... 
[ 155.753448] BUG: unable to handle kernel paging request at ffff88007c408000 
[ 155.753629] IP: [<ffffffffa0037037>] KM+0x37/0x1000 [kernel_module1] 
[ 155.753962] PGD 3f32067 PUD 3f35067 PMD 3ed00063 PTE 800000007c408161 
[ 155.754065] Oops: 0003 [#1] SMP 
[ 155.754170] Modules linked in: kernel_module1(POE+) ip6t_rpfilter ip6t_REJECT ipt_REJECT xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw iptable_filter vfat fat snd_intel8x0 snd_ac97_codec ac97_bus snd_seq iTCO_wdt iTCO_vendor_support ppdev snd_seq_device snd_pcm snd_timer snd soundcore parport_pc pcspkr parport lpc_ich mfd_core sg i2c_piix4 video i2c_core ip_tables xfs libcrc32c sr_mod cdrom sd_mod ata_generic crct10dif_generic crc_t10dif crct10dif_common pata_acpi ahci libahci ata_piix serio_raw libata e1000 dm_mirror 
[ 155.754955] dm_region_hash dm_log dm_mod 
[ 155.754979] CPU: 0 PID: 2562 Comm: insmod Tainted: P   OE ------------ 3.10.0-327.13.1.el7.x86_64 #1 
[ 155.755086] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 
[ 155.755190] task: ffff88007c72f300 ti: ffff88007c668000 task.ti: ffff88007c668000 
[ 155.755286] RIP: 0010:[<ffffffffa0037037>] [<ffffffffa0037037>] KM+0x37/0x1000 [kernel_module1] 
[ 155.755391] RSP: 0018:ffff88007c29b450 EFLAGS: 00010287 
[ 155.755487] RAX: 000000000005b2ec RBX: ffffffff81951020 RCX: ffff88007c29b450 
[ 155.755594] RDX: 000000000005babc RSI: 0000000078e678e4 RDI: 0000000000000246 
[ 155.755687] RBP: ffff88007c66bd58 R08: 0000000000000086 R09: 0000000000000269 
[ 155.755782] R10: 0000000000000000 R11: ffff88007c66ba6e R12: ffff8800026609c0 
[ 155.755877] R13: ffffffffa0037000 R14: 0000000000000000 R15: ffffffffa03e4000 
[ 155.755974] FS: 00007f6dfdbc4740(0000) GS:ffff88007da00000(0000) knlGS:0000000000000000 
[ 155.756074] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b 
[ 155.756164] CR2: ffff88007c408000 CR3: 000000007c606000 CR4: 00000000000006f0 
[ 155.756262] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 
[ 155.756356] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 
[ 155.756451] Stack: 
[ 155.756527] 000007d1000007d0 000007d3000007d2 000007d5000007d4 000007d7000007d6 
[ 155.756635] 000007d9000007d8 000007db000007da 000007dd000007dc 000007df000007de 
[ 155.756745] 000007e1000007e0 000007e3000007e2 000007e5000007e4 000007e7000007e6 
[ 155.756842] Call Trace: 
[ 155.756923] Code: e5 e8 23 81 5f e1 be 40 42 0f 00 48 c7 c7 48 30 3e a0 31 c0 e8 10 81 5f e1 48 81 ec 08 09 3d 00 31 c0 48 89 e1 8d 90 d0 07 00 00 <89> 14 81 48 ff c0 48 3d 40 42 0f 00 75 ec 48 c7 c7 3b 30 3e a0 
[ 155.757153] RIP [<ffffffffa0037037>] KM+0x37/0x1000 [kernel_module1] 
[ 155.757246] RSP <ffff88007c29b450> 
[ 155.757329] CR2: ffff88007c408000 

meist der Grund ist, weil es eine Adresse erreicht das kann nicht zugewiesen werden ...

+5

Meistens, ** nichts auf Stapel im Kernel zuweisen **. –

+1

Im Kernel tun kmalloc. Es wird nicht in Panik geraten, wenn es aus irgendeinem Grund scheitert. – stark

+0

Ja, kmalloc ist der Weg, um hier zu gehen – Luanf

Antwort

4

Die Standardstapelgröße für einen Prozess, der in Kernel-Speicher ausgeführt wird, ist 8192 Byte, obwohl es je nach Architektur weniger sein kann.

Um nach Speicher von signifikanter Größe zu fragen, verwenden Sie kmalloc und es ist Freunde.

size_t sz = 10000; 
int *ia = kmalloc(sz, GFP_KERNEL); 
if (ia == NULL) 
{ 
    /* allocation failed, handle error */ 
    return -1; 
} 
/* OK, though it may have allocated more than you asked for */ 
+0

ausgezeichnet, Ich versuchte ein kmalloc zuvor auf große Zahlen, und das ist die beste Lösung für NULL zu überprüfen :) –