-
-
Save starwing/5937805 to your computer and use it in GitHub Desktop.
#include <linux/init.h> | |
#include <linux/module.h> | |
#include <linux/kernel.h> | |
#include <linux/io.h> | |
#include <linux/proc_fs.h> | |
#include <linux/seq_file.h> | |
/* procfs routines */ | |
int chipid_show(struct seq_file *p, void *v) { | |
#define SW_VA_SID_IO_BASE ((const volatile void __iomem*)0xf1c23800) | |
return seq_printf(p, "Chipid\t\t: %08x-%08x-%08x-%08x\n", | |
readl(SW_VA_SID_IO_BASE), | |
readl(SW_VA_SID_IO_BASE + 0x4), | |
readl(SW_VA_SID_IO_BASE + 0x8), | |
readl(SW_VA_SID_IO_BASE + 0xC) | |
); | |
} | |
int chipid_single_open(struct inode *inode, struct file *file) { | |
return single_open(file, chipid_show, NULL); | |
} | |
struct file_operations chipid_single_seq_file_operations = { | |
.open = chipid_single_open, | |
.read = seq_read, | |
.llseek = seq_lseek, | |
.release = single_release, | |
}; | |
struct proc_dir_entry *entry = NULL; | |
/* initialize routines */ | |
static int __init chipid_init(void) | |
{ | |
printk(KERN_ALERT "chipid module loading ...\n"); | |
entry = proc_create("chipid", 0, NULL, &chipid_single_seq_file_operations); | |
if (entry) { | |
printk(KERN_ALERT "chipid module load ok, entry = %p\n", entry); | |
return 0; | |
} | |
return -EFAULT; | |
} | |
static void __exit chipid_exit(void) | |
{ | |
printk(KERN_ALERT "chipid module unloading ..., entry = %p\n", entry); | |
if (entry) { | |
remove_proc_entry("chipid", NULL); | |
printk(KERN_ALERT "chipid module unloaded.\n"); | |
entry = NULL; | |
} | |
} | |
MODULE_AUTHOR("Xavier-Wang"); | |
MODULE_LICENSE("Dual BSD/GPL"); | |
MODULE_DESCRIPTION("kernel module used to get chipid of cubieboard!\n"); | |
MODULE_ALIAS("retrieve chipid from procfs"); | |
module_init(chipid_init); | |
module_exit(chipid_exit); |
obj-m := chipid.o |
sw@sw-acer:~/Work/Code/procfsk$ make -C /usr/src/linux-headers-3.8.0-25-generic SUBDIRS=$PWD modules | |
make:进入目录'/usr/src/linux-headers-3.8.0-25-generic' | |
CC [M] /home/sw/Work/Code/procfsk/chipid.o | |
Building modules, stage 2. | |
MODPOST 1 modules | |
CC /home/sw/Work/Code/procfsk/chipid.mod.o | |
LD [M] /home/sw/Work/Code/procfsk/chipid.ko | |
make:离开目录“/usr/src/linux-headers-3.8.0-25-generic” | |
sw@sw-acer:~/Work/Code/procfsk$ sudo insmod chipid.kosw@sw-acer:~/Work/Code/procfsk$ cat /proc/chipid | |
Chipid : 63682074-65645f69-682a2076-2c766564 | |
sw@sw-acer:~/Work/Code/procfsk$ sudo rmmod chipid sw@sw-acer:~/Work/Code/procfsk$ | |
sw@sw-acer:~/Work/Code/procfsk$ dmesg | tail | |
[354923.091725] type=1400 audit(1373061974.062:42): apparmor="DENIED" operation="open" parent=3490 profile="/usr/bin/evince" name="/media/sw/Private/Downloads/vilua.love" pid=29762 comm="pool" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 | |
[354923.092409] type=1400 audit(1373061974.062:43): apparmor="DENIED" operation="open" parent=3490 profile="/usr/bin/evince" name="/media/sw/Private/Downloads/Soundbanks.for.Guitar.Pro.6.rar.emule.td" pid=29762 comm="pool" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 | |
[358156.365857] chipid module loading .../n | |
[358156.365875] chipid module load ok/nchipid module unloaded/n | |
[358575.034287] chipid module loading .../n<1>[358592.043926] chipid module unloading ..., entry = ce6bf480 | |
[358592.043931] chipid module unloaded. | |
[358947.262917] chipid module loading ... | |
[358947.262942] chipid module load ok, entry = e5430ae0 | |
[358970.715428] chipid module unloading ..., entry = e5430ae0 | |
[358970.715434] chipid module unloaded. | |
sw@sw-acer:~/Work/Code/procfsk$ |
还有一部分(不多,但也不能忽略不计)的时间是花在shell上。
之前的想法是: bash, sed, awk... 这些东西有什么用? 我需要深入学习的只是少数 真正的 编程语言而已。
但大致应该是在学git的时候, 我感觉到一件事: 这套东西是一套用代码而不是文字描述要做什么的方法。
就像讨论其他编程语言的各种问题一样, 用文字很难准确描述, 上代码才是王道。
比如"将/proc/config.gz"的内容解压到.config, 再修改或添加CONFIG_STRICT_DEVMEM=y一行",如果再附带一条shell命令:
$ zcat /proc/config.gz | sed 's|^CONFIG_STRICT_DEVMEM=.*$|CONFIG_STRICT_DEVMEM=n|w/dev/stderr' > .config
读者(可能就是半年后的自己)只要看明白其中任意一项就可以知道要做什么了。甚至不需要看明白, 只要把这个命令复制到终端里执行就可以了, 之后在慢慢体会去。
另外,我还有(也许是坏的)习惯将命令输出的内容作一些变换。
比如将"/usr/src/linux-headers-3.8.0-25-generic"中的3.8.0-25-generic再替换回$(uname -r), "63682074-65645f69-682a2076-2c766564"替换成星号, 将"[354923.092409]"给删除掉,等等。
尽量在其他环境下重复执行指令能有相同的输出。
还会将[354923.091725] type=1400 audit(1373061974.062:42): apparmor="DENIED" operation="open" parent=3490 profile="/usr/bin/evince" name="/media/sw/Private/Downloads/vilua.love" pid=29762 comm="pool" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
这种与问题无关的杂乱信息给去掉。
$ ls -1 /boot/config* | sed "s|$(uname -r)|"'$(uname -r)|'
/boot/config-$(uname -r)
$ sed -r -n 's|^Chipid\t\t: [0-9a-z]{8}-[0-9a-z]{8}-[0-9a-z]{8}-[0-9a-z]{8}$|Chipid\t\t: -**-**-**|p' /proc/cpuinfo
Chipid : ***-**-**-*******
$ dmesg | sed '$!d;s|^[[ 0-9]+.[0-9]+] ||'
去掉dmesg的时间戳还可以 $ echo N | sudo tee /sys/module/printk/parameters/time
具体config-后跟的是什么,chipid是多少,dmesg的最后一条的时间戳其实都是噪音信息。
因为就这两天要把sd卡还给同学,所以打算睡觉前在nand上再编译一次,结果忘记编译前screen一下。
如果关掉工作站(省电)就会断开ssh, cb上的make就挂了。。。
终于编译完了,睡觉去。
关于$ make -C /usr/src/linux-headers-3.8.0-25-generic SUBDIRS=$PWD modules。
早上我只是发现和我自己编译时的方式不同:
$ touch Makefile # 至少得有一个空的Makefile
$ make -C "$KDIR" "M=$PWD" modules obj-m=hello.o
但当时我不记得这条命令的来源了。
来源在这: https://www.kernel.org/doc/Documentation/kbuild/modules.txt (而且还有将-D传入的方法)
$KDIR 可以是:
比如 https://github.com/maxnet/linux-allwinner-aufs34 的情况。
比如 $ sudo apt-get install "linux-headers-$(uname -r)" 的情况。
比如
$ apt-get download "linux-headers-$(uname -r)"
$ dpkg -x "linux-headers-$(uname -r)*.deb" "linux-headers-$(uname -r)"
$ cd "linux-headers-$(uname -r)/lib/modules/$(uname -r)/build"
$ export KDIR="$PWD"
apt-get download不需要root权限, 但我印象中deb解压后 ./usr/src/... 作KDIR是不行的, 软链接是无效的。 用./lib/... 是直接就可以:
$ make -C "$KDIR" "M=$PWD" modules obj-m=hello.o
但之前有遇见过需要到kernel里make module_prepare还是make scripts的情况。 忘了到底是以 usr 还是以 lib 作为KDIR, 也忘了是apt得到的还是cb的还是berryboot的kernel tree。
这些就是我说的清理工作的一部分。
最终虽然是弄出来了,但这个过程中犯过不少错,而且在弄出来之前也没有耐心和时间一个一个去排查,而是直接试下一个方法。
现在在有一些经验后回过头再去看那些错误也许就能解决,比如发现其实是自己某些步骤搞错了,或者是资料过时了。
虽然目前看来是没时间仔细做这个工作了,但至少得把7-8个conkeror里的打开的页面都再刷一遍吧?
比如: https://www.kernel.org/doc/Documentation/printk-formats.txt
其他语言里的format-string和C有些区别都还可以忍 —— 至少有运行时类型检查。
C里的format-string要是弄错了,编译时就靠gcc那点检查很弱,而运行时根本就没有。
再比如:http://unix.stackexchange.com/questions/24704/how-to-generate-module-symvers#24760
这家伙说$ make modules 就可以得到Module.symvers。
他说得没错,确实可以产生Module.symvers。 但通过这个产生的.ko插不进去。 为什么我也忘了, 反正当时已经耐心全无,直接 $ make 了事。
CONFIG_STRICT_DEVMEM会限制内存访问以及/proc/config.gz 是从这里知道的: https://bbs.archlinux.org/viewtopic.php?id=121964#p956271
但为什么ubuntu上没有 /proc/config.gz? 是哪个参数造成的?
而 $ make sun4i_aufs_defconfig 是从这里找到的: https://github.com/maxnet/berryboot/blob/berryboot2.0/rebuild-berryboot-a10.sh
还有 /proc/kallsyms, /proc/modules, /sys/module/$MODULE/parameters/ 等等这些货我到底是从哪知道的?
提供这些信息的网页上有没有更多相关的有用的信息 ?
诸如此类。
如果时间允许,再多花一些时间,把这些经历小结一下,再下一次遇见这些问题时(这是说不准的事,比如工作站上的wireless现在都没法用)就有门路,不会又无头绪的反复地问google。
不过等个10天半个月的去做这事我也能接受, 记忆力还没衰退到半个月的事完全记不住。 但长期记忆的话, 烂笔头更靠谱。