I3MPS_Opgave4

Step 1: Lav dit første kernemodul
Til vores hello world modul gjorde vi brug af følgende kode: code format="c"
 * 1) include 
 * 2) include 

MODULE_LICENSE("Dual BSD/GPL");

static int __init hello_init(void) { printk(KERN_ALERT "Hello, World\n"); return 0; }

static void __exit hello_exit(void) { printk(KERN_ALERT "Goodbye, cruel world\n"); } module_init(hello_init); module_exit(hello_exit);

code Dette modul printer i terminalen, når det bliver indsat, samt når det bliver taget ud igen. For at kompilere dette modul bruger vi en makefil, som kompiler modulen, med den nuværende version af kernen. code format="make" ifeq ($(KERNELRELEASE),)
 * 1) To build modules outside of the kernel tree, we run "make"
 * 2) in the kernel source tree; the Makefile these then includes this
 * 3) Makefile once again.
 * 4) This conditional selects whether we are being included from the
 * 5) kernel Makefile or not.

# Assume the source tree is where the running kernel was built # You should set KERNELDIR in the environment if it's elsewhere KERNELDIR = ~/sources/linux-3.2.6 # The current directory is passed to sub-makes as argument PWD := $(shell pwd)

modules: $(MAKE) ARCH=arm CROSS_COMPILE=arm-angstrom-linux-gnueabi- -C $(KERNELDIR) M=$(PWD) modules

clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

.PHONY: modules clean

else # called from kernel build system: just declare what our modules are obj-m := hello.o endif

code linjen obj-m := definere de elementer som modulet består af, og skal ændres når der skal lavet et andet modul.

For at indsætte modulet bruges følgende kommando. code insmod hello.ko code Hvis man ønsker at se de mods der er indsat i kernen skal man bruge kommandoen code lsmod code For at fjerne modulet igen skrives code rmmod hello code

Step 2: Få lysdioden til at lyse
For at få lysdioden fra sidste øvelse til at lyse, gør vi brug af følgende program code format="c"
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 5) include 

MODULE_LICENSE("Dual BSD/GLP");

static int __init light_init(void) {   printk(KERN_ALERT "Module Inserted\n"); printk(KERN_ALERT "Declairing variables\n"); volatile unsigned long *REG_GPIO6_OE; volatile unsigned long *REG_GPIO6_DIN; volatile unsigned long *REG_GPIO6_DOUT;

unsigned long tmpLong; unsigned long ledReg;

printk(KERN_ALERT "Declaring usrKey");

if(request_mem_region(0x48310038, 12, "lightMod") == NULL) {     printk(KERN_ALERT "Allocation for Userkey Failed\n"); return 0; }

printk(KERN_ALERT "Declaring ledOE");

if(request_mem_region(0x49058034, 12, "lightMod") == NULL) {     printk(KERN_ALERT "Allocation for LED OE Failed\n"); return 0; }

printk(KERN_ALERT "Remapping Ports");

REG_GPIO6_OE = ioremap( 0x49058034, 1); REG_GPIO6_DIN = ioremap(0x48310038, 1); REG_GPIO6_DOUT = ioremap(0x4905803c, 1);

printk(KERN_ALERT "Set LED to output\n");

tmpLong = ioread32(REG_GPIO6_OE);

tmpLong &= 0xfffffff7;

iowrite32(tmpLong, REG_GPIO6_OE);

printk(KERN_ALERT "Starting While\n");

while(1) {     tmpLong = ioread32(REG_GPIO6_DIN); ledReg = ioread32(REG_GPIO6_DOUT);

if((tmpLong & 0x04000000) == 0) {	ledReg |= 0x00000008; }     else {	ledReg &= 0xfffffff7; }

iowrite32(ledReg, REG_GPIO6_DOUT);

} }

static void __exit light_exit(void) { printk(KERN_ALERT "Delocating Ports\n");

release_mem_region(0x49058034, 12); // OE release_mem_region(0x48310038, 12); // usrKEy & LED

printk(KERN_ALERT "Removing Module"); printk(KERN_ALERT "END\n"); }

module_init(light_init); module_exit(light_exit);

code Når dette modul bliver indsat, kan man slukke for lysdioden SYS_LED3, når man trykker på USER_KEY.