编程

VC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

main(){
int a = 1;
int b = 2;
int c;
__asm{
mov eax,a
mov ebx,b
mov ecx,1h
add eax,ebx
mov c,ecx
}
printf("%x\n", c);
}

GCC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>

main(){
int a = 1;
int b = 2;
int c;
asm(
"add %2,%0" //1
:"=g"(c) //2
:"0"(a),"g"(b) //3
:"memory" //4
);
printf("%x\n", c);
}

VmWare默认的镜像格式是.vmdk格式的,VirtualBox则默认是.vdi格式的。其实这在VirtualBox新建虚拟机的过程中是可选的。

导入.vmdk格式的镜像到VirtualBox只需要新建一个虚拟机,并且不创建虚拟硬盘。如下图:

无视警告,继续:

创建好之后,在设置里面把.vmdk格式的虚拟硬盘添加进去:

这样就可以了。

如果遇到windows虚拟机起不开的情况,尝试更改下下面这个选项,启用I/O APIC试试。

1
2
3
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_40
set path=%path%;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
set classpath=%classpath%;.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar

Linux内核编程一直是我很想掌握的一个技能。如果问我为什么,我也说不上来。
也许是希望有一天自己的名字也出现在内核开发组的邮件列表里?或是内核发行文件的CREDITS上?
也许是吧。其实更多的,可能是对于底层的崇拜,以及对于内核的求索精神。
想到操作系统的繁杂,想到软件系统之间的衔接,内心觉得精妙的同时,更是深深的迷恋。
所以从这篇文章开始,我要真正的走进Linux内核里了,让代码指引我,去奇妙的世界一探究竟。

在这篇文章中,一起来对内核说Hello World。

本次的编程环境:

  • CentOS 6.8
  • Linux centos 2.6.32-573.8.1.el6.x86_64

没有安装内核的,可能需要安装一下内核源码包

  • kernel-devel-2.6.32-642.4.2.el6.x86_64

    yum install kernel-devel-2.6.32-642.4.2.el6.x86_64

安装好之后,这个版本内核可以在/usr/src/linux找到。

然后话不多说,首先看代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//20160904
//kernel_hello_world.c

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

static int __init lkp_init(void){
printk("Hello,World! --from the kernel space...\n");
return 0;
}

static void __exit lkp_cleanup(void){
printk("Goodbye,World! --leaving kernel space...");
}

module_init(lkp_init);
module_exit(lkp_cleanup);

以上代码是kernel_hello_world.c内容。
作为内核模块,在编译的时候,Makefile文件这样写:

1
2
#File:Makefile
obj-m += kernel_hello_world.o

然后可以通过这条命令来编译:

1
make -C /usr/src/linux SUBDIRS=$PWD modules

编译好以后,目录下面的文件可能是这样子:

kernel_hello_world.ko.unsigned  kernel_hello_world.o  Module.symvers
kernel_hello_world.c   kernel_hello_world.mod.c        Makefile
kernel_hello_world.ko  kernel_hello_world.mod.o        modules.order

有这么多文件被生成,其中kernel_hello_world.ko就是本次编译出来的内核模块文件,在Linux内核中有很多这样的模块,它们可能充当着不同的角色,可能是驱动,也可能是各种设备。

这个模块会在/var/log/message文件中打印一行字,即Hello,World! –from the kernel space…

可以使用insmod kernel_hello_world.ko来将这个模块载入到内核,使用lsmod来查看是否已经加载,使用rmmod kernel_hello_world.ko来卸载这个模块。

可以tail /var/log/message来看一下是否成功执行了呢?

Hello,Kernel.

建立热点:

@echo off
netsh wlan set hostednetwork mode=allow
netsh wlan set hostednetwork ssid=热点名 key=密码
netsh wlan start hostednetwork

关闭热点

netsh wlan set hostednetwork mode=disallow

默认安装的MySQL数据库,无法远程连接。
登录MySQL之后,运行

1
SELECT user,host from mysql.user;

如果只有一条记录,说明是这个原因。
将下面的脚本保存成user.sql,登录MySQL,运行:

1
2
3
use mysql;
source user.sql;
flush privileges;

Notice: 会重置MySQL user表,并且将root用户密码设置为空。

脚本内容: 点这里直接下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `user`
-- ----------------------------
USE mysql;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
`User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
`Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
`Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',
`ssl_cipher` blob NOT NULL,
`x509_issuer` blob NOT NULL,
`x509_subject` blob NOT NULL,
`max_questions` int(11) unsigned NOT NULL DEFAULT '0',
`max_updates` int(11) unsigned NOT NULL DEFAULT '0',
`max_connections` int(11) unsigned NOT NULL DEFAULT '0',
`max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges';

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('localhost', 'root', '', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', '0', '0', '0', '0');
INSERT INTO `user` VALUES ('127.0.0.1', 'root', '', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', '0', '0', '0', '0');
INSERT INTO `user` VALUES ('%', 'root', '', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', '0', '0', '0', '0');
flush privileges;

Windows中搭建Ruby On Rails环境

步骤如下

  1. 安装ruby (我选择的版本是ruby 2.2.3p173)
  2. 安装rails gem
    在这之前建议先把gem的源换成淘宝的源,速度快点。
    1
    2
    3
    4
    5
    6
    7
    8
    gem sources --add https://ruby.taobao.org/ --remove https://rubygems.org/
    gem sources -l
    *** CURRENT SOURCES ***

    https://ruby.taobao.org
    # 请确保只有 ruby.taobao.org

    gem install rails

之后:

1
2
gem install rails
gem install bundler
  1. 安装devkit
    下载地址 http://rubyinstaller.org/downloads

如果是win10,选择 DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe 这个版本。

然后运行,并选择解压到c:\devkit

进入c:\devkit目录
运行

ruby dk.rb init

之后修改config.yml

添加下面三行

1
2
3
---
- C:/Ruby22-x64
- C:/Ruby22-x64

注意把路径换成当前ruby的安装路径,-前后各有一个空格不可忽略。
然后运行

ruby dk.rb install

最后进入需要建立工程的目录,使用如下命令新建rails项目

rails new testapp

如果在此过程中报错,则进入testapp中
使用

bundler install

来安装所需要的依赖包。

如果还报错,修改testapp目录中的Gemfile

将第一行的sources源内容改为

source 'https://ruby.taobao.org/'

然后再执行bundler install命令

Debian中搭建Ruby On Rails开发环境

假设你已经安装好ruby了

接下来安装rvm

$ curl -L https://get.rvm.io | bash -s stable

某些情况下,可能需要编译一下rvm的初始化脚本

我的位置是在/etc/profile.d/rvm.sh,所以运行这一句:

$source /etc/profile.d/rvm.sh

接着安装bundler

gem install bundler

然后安装rails

gem install rails

如果这地方出现错误,尝试使用rvm切换ruby的版本:

rvm install 2.0.0
rvm 2.0.0 --default

CentOS中搭建ruby on rails开发环境

1
2
3
4
5
6
curl -L https://get.rvm.io | bash -s stable
source /usr/local/rvm/bin/rvm
rvm install 2.0.0
rvm 2.0.0 --default
gem install bundler
gem install rails

创建项目

1
rails new BootstrapProject

创建模型

1
rails g scaffold xxx --skip-stylesheets

运行迁移

1
rake db:migrate

如果项目和模型都已经建立好了并已经运行了迁移,那么可以省略以上步骤,直接进入下面的流程

在Gemfile中添加bootstrap,这里使用twitter-bootstrap-rails

1
2
3
4
gem 'jquery-rails'
gem 'less-rails'
gem 'therubyracer'
gem 'twitter-bootstrap-rails'

bundle

1
bundle install

安装bootstrap

1
rails g bootstrap:install

在模型上运用bootstrap

1
rails g bootstrap:themed xxx -f

注:xxx可以是任意的模型,例如模型名称是Article,那么这里的语句就是:

1
rails g bootstrap:themed Articles 

还要在application.js中加上引用,否则bootstrap的一些按钮会失效:

1
2
//= require jquery
//= require twitter/bootstrap

Enjoy it~

最近手上多了一个树莓派2代,于是折腾就这么开始了。
因为总是得要个显示屏或者路由器或者插根网线才能玩,有点麻烦,所以有了此文。

设备清单:

树莓派2代
EDUP EP-N8508GS无线网卡(USB)
普通网线一根

最终实现的效果是树莓派的有线网卡用来作为wan口,无线网卡建立热点
笔记本可以通过连接wifi连接上树莓派进行操作

下面说说过程:
首先我参考了

http://elinux.org/RPI-Wireless-Hotspot

这篇文章中的方法,但是并没有成功。后来看到文章的末尾才知道,是驱动对不上号,文章末尾明确标明默认的hostapd程序不支持rtl8188系列网卡,而我的usb网卡就是rtl8188cus系列。
所以在开始之前,建议先用lsusb命令看一下网卡的型号再考虑进行下一步。

如果你的网卡不是rtl8188系列那你可以参考上面文章中的方法来配置,如果是那么可以参考我的方法。

根据那篇文章最后给出的连接,找到了这个驱动:

https://github.com/lostincynicism/hostapd-rtl8188

然而当编译好驱动重新运行之后仍然是不行,还是不支持。

最后还是参考了这篇文章:

http://wangye.org/blog/archives/845/?_t_t_t=0.7382462719884554

原因可能就是因为我这个系列网卡比较特殊。但是最后在这个文章中发现了编译好的第三方驱动,虽然有点不满意,但还是凑合着用了。
http://www.daveconroy.com/turn-your-raspberry-pi-into-a-wifi-hotspot-with-edimax-nano-usb-ew-7811un-rtl8188cus-chipset/
具体步骤:
先切换为root用户,可以省去很多不必要的麻烦。
所以以下操作都是以root用户:
1.安装hostapd和udhcpd服务并且更换hostapd程序

apt-get install udhcpd hostapd
wget http://www.daveconroy.com/wp3/wp-content/uploads/2013/07/hostapd.zip
unzip hostapd.zip
mv /usr/sbin/hostapd /usr/sbin/hostapd.bak
mv hostapd /usr/sbin/hostapd.edimax
ln -sf /usr/sbin/hostapd.edimax /usr/sbin/hostapd
chown root.root /usr/sbin/hostapd
chmod 755 /usr/sbin/hostapd

2.编辑/etc/udhcpd.conf文件,配置dhcp服务:
确保文件当中有下列内容

start 192.168.1.2
end 192.168.1.254
interface wlan0
remaining yes
opt dns 223.5.5.5 223.6.6.6
opt subnet 255.255.255.0
opt router 192.168.1.1
opt lease 864000 #

相信一般都能看懂,其中的interface需要根据情况来写。
3.编辑/etc/default/udhcpd 文件,将下面这行注释掉。

DHCPD_ENABLED="no"

4.将无线网卡wlan0的ip设为192.168.1.1

ifconfig wlan0 192.168.42.1

5.修改/etc/network/interfaces文件,添加下面的内容

iface wlan0 inet static
  address 192.168.1.1
  netmask 255.255.255.0

并且将下面这两条注释掉

wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet manual

6.接着就正式开始配置无线相关的选项了,编辑/etc/hostapd/hostapd.conf,如果没有这个文件就自行创建它。

interface=wlan0
driver=rtl871xdrv
ssid=无线名称
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=无线密码
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

7.在/etc/default/hostapd文件中指定hostapd服务的配置文件,内容如下

DAEMON_CONF="/etc/hostapd/hostapd.conf"

8.更改系统的转发规则和iptables规则,依次运行下列命令:

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
iptables-save > /etc/iptables.nat
service hostapd start
service udhcpd start
update-rc.d hostapd enable
update-rc.d udhcpd enable

9.最后一点点收尾工作:
编辑/etc/network/interfaces文件,在末尾加上着一条:

up iptables-restore < /etc/iptables.nat

以及/etc/sysctl.conf文件,确保下面的选项存在

net.ipv4.ip_forward=1

到此为止就全部完成了,用手机,电脑等无线设备都可以连接上树莓派了。
为后续的折腾打下基础。

折腾的整个过程还挺复杂的,需要修改多处文件,而且每一处修改都会微妙的影响到最后路由器的运行,小小的改变都有可能造成瘫痪或者影响性能。由此可见,想DIY一款高性能的个性无线路由器还是很有挑战性的。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×