Ubuntu装Win7双系统

最近朋友老是推荐我装Win7,禁不住劝告就装了一下试试。一般来说要先装Windows再装Linux,这个地球人都知道。因为windows回覆盖MBR的引导记录,如果预先装了Linux那你就倒霉了(现在有了grub4dos情况好一点了)。反观Linux,因为有神器grub什么都能引导,那就不用怕覆盖了:)。

我已经装了Ubuntu,为了体验Win7就不能用普通方法安装了。

分区

首先第一步就是划分一个主分区给Win7(windows一定要装在主分区上,而不是逻辑分区)。我用Ubuntu Live CD启动,用了gparted无损分区软件搞定(特别适合分割调整分区,而且不用担心数据丢失,理论上是的)。最后的分区如下,/dev/sda4是给Win7的,分了40G的空间(Win7很耗空间)。其他要注意的是要去掉/dev/sda1的Boot标记(Linux用不到,主要是留给Windows用的),只有一个主分区需要Boot而且是/dev/sda4。

Device     Boot     Start      End       Blocks     Id  System
/dev/sda1            2048    20000767     9999360   83  Linux
/dev/sda2        20000768    20391935      195584   82  Linux swap / Solaris
/dev/sda3        20393982   894525439   437065729    5  Extended
/dev/sda4   *   894525440   976771071    41122816    7  HPFS/NTFS/exFAT
/dev/sda5        20393984   894523391   437064704   83  Linux

备份MBR

下一步是备份MBR,因为Win7会修改MBR,如果要找回之前的Ubuntu只能恢复MBR:

sudo dd if=/dev/sda of=./mbr.txt bs=512 count=1

这里扯一下MBR,用hexdump看看mbr.txt

hexdump mbr.txt

基本上Linux和Win7的分区表识别是相同的(4个分区,每个分区有分区类型:例如5表示扩展分区,其他的是什么文件系统),不同在于分区表前的446个字节。所以恢复是只要恢复MBR的446个字节。

装Win7

这个不用多说,地球人都会。

恢复MBR

装完了Win7当然进不去Ubuntu了,所以用Live CD启动进去恢复MBR了。

sudo dd if=./mbr.txt of=/dev/sda bs=446 count=1

更新Grub配置

恢复MBR后进入Ubuntu更新Grub配置,Grub会扫描分区从而识别Win7。

$ sudo update-grub
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.2.0-34-generic-pae
Found initrd image: /boot/initrd.img-3.2.0-34-generic-pae
Found linux image: /boot/vmlinuz-3.2.0-33-generic-pae
Found initrd image: /boot/initrd.img-3.2.0-33-generic-pae
Found linux image: /boot/vmlinuz-3.2.0-32-generic-pae
Found initrd image: /boot/initrd.img-3.2.0-32-generic-pae
Found memtest86+ image: /boot/memtest86+.bin
Found Windows 7 (loader) on /dev/sda4
done

OK,大功告成。重启电脑,按住Shift键进入Grub选择Win7就就去了。进了Win7才发现没有网卡驱动、无线驱动,偏偏我的Dell笔记本是个裸机,连官网都找不到Win7驱动-_-!!!,看来还是Linux好啊。

BTW:今天发现Win7的设备管理器里可以在线搜索驱动,这个比较创新啊:)。A卡驱动仍旧没着落,无法安装,暂时用了Intel的集成显卡驱动。

DNS其他

DNS服务器类型

  1. Cache only服务器
    这类没有自己负责解析的域名,只有一个DNS根服务器文件用来进行递归查询。

  2. Forwarding服务器(例如:dnsmasq)
    这类干脆连DNS根服务器文件列表也没有,有什么查询抛给上层DNS服务器处理。

查询域名托管DNS服务器

如果想知道域名放在哪个DNS服务器上,一般那个DNS服务器的域名会有NS记录表示当前放在DNS服务器域名。

$dig freezhongzi.info

;; AUTHORITY SECTION:
freezhongzi.info.   600 IN  NS  f1g1ns1.dnspod.net.
freezhongzi.info.   600 IN  NS  f1g1ns2.dnspod.net.

返回结果中有两条NS记录对应托管的DNS服务器。如果在dnspod停用那两条NS记录,则返回的结果就只有A记录了。

DNS反解:

反解查询首先要转化为IP.in-addr.arpa的格式(xxx.xxx.xxx.xxx.in-addr.arpa),流程跟上面一样,从DNS根服务器一直查到我的IP地址拥有方burst的DNS服务器:

dns.burst.net
dns1.burst.net

为了进行DNS反向查询,有专门的域名.in-addr.arpa进行转换,拥有IP地址的人进行设置(不是注册域名或VPS的人,而是申请IP地址的人)。

这有什么用呢,一般的邮件服务器为了验证垃圾邮件,都对发送方的IP地址进行反向解析看看是不是固定的IP地址,从而杜绝垃圾邮件。

查询网站主机提供商

比如要查看本站的VPS提供商:

$dig -x xxx.xxx.xxx.xxx

;; ANSWER SECTION:
xxx.xxx.xxx.xxx.in-addr.arpa. 14313 IN    PTR xxx.xxx.xxx.xxx.static.hostnoc.net.

;; AUTHORITY SECTION:
xxx.xxx.xxx.xxx.in-addr.arpa. 14313  IN  NS  NS2.HOSTNOC.EU.
xxx.xxx.xxx.xxx.in-addr.arpa. 14313  IN  NS  NS1.HOSTNOC.EU.
xxx.xxx.xxx.xxx.in-addr.arpa. 14313  IN  NS  dns1.burst.net.
xxx.xxx.xxx.xxx.in-addr.arpa. 14313  IN  NS  NS1.hostnoc.net.
xxx.xxx.xxx.xxx.in-addr.arpa. 14313  IN  NS  dns.burst.net.
xxx.xxx.xxx.xxx.in-addr.arpa. 14313  IN  NS  NS2.hostnoc.net.

可以发现NS记录中的有burst的dns,所以VPS是Burst。不要小看一个DNS,如果挖掘的够深,会有很多信息。

整个过程其实可以用dig完全看的清清楚楚:

$ dig +trace  www.freezhongzi.info

;; global options: +cmd
.           25684   IN  NS  f.root-servers.net.
.           25684   IN  NS  m.root-servers.net.
.           25684   IN  NS  d.root-servers.net.
.           25684   IN  NS  e.root-servers.net.
.           25684   IN  NS  k.root-servers.net.
.           25684   IN  NS  c.root-servers.net.
.           25684   IN  NS  j.root-servers.net.
.           25684   IN  NS  g.root-servers.net.
.           25684   IN  NS  h.root-servers.net.
.           25684   IN  NS  l.root-servers.net.
.           25684   IN  NS  a.root-servers.net.
.           25684   IN  NS  b.root-servers.net.
.           25684   IN  NS  i.root-servers.net.

info.           172800  IN  NS  c0.info.afilias-nst.info.
info.           172800  IN  NS  d0.info.afilias-nst.org.
info.           172800  IN  NS  b2.info.afilias-nst.org.
info.           172800  IN  NS  a2.info.afilias-nst.info.
info.           172800  IN  NS  b0.info.afilias-nst.org.
info.           172800  IN  NS  a0.info.afilias-nst.info.

freezhongzi.info.   86400   IN  NS  f1g1ns2.dnspod.net.
freezhongzi.info.   86400   IN  NS  f1g1ns1.dnspod.net.

www.freezhongzi.info.   600 IN  A   xxx.xxx.xxx.xxx
freezhongzi.info.   600 IN  NS  f1g1ns1.dnspod.net.
freezhongzi.info.   600 IN  NS  f1g1ns2.dnspod.net.

DNS初探

DNS是一个分布式系统,没有一个单独的主机知道所有的信息。

最简单的DNS系统就是/etc/hosts文件了,每行内容是”IP 主机名 主机名1 主机名2 …”。

域名(domain name)和主机名(hostname)组成完整的DNS标识,例如

www.freezhongzi.info,www是主机名,freezhongzi.info是域名,而

freezhongzi.info,freezhongzi是主机名,.info是域名。

以句号.结尾的域名,如www.freezhongzi.info.叫Fully Qualified Domain Name(FQDN),句号表示根域名,在DNS协议里用FQDN标识。

DNS递归查询(recursion query)

默认的递归查询都是由你的当前DNS服务器执行的,所以一般都设置RD位(例外是DNS根服务器是没有递归查询功能的,所以当DNS服务器向根服务器查询时不设置RD位)。

DNS查询的操作流程是:

  1. 客户端(linux/unix一般是gethostbyname和gethostbyaddr)向当前DNS服务器查询域名,一般查询A记录(IP地址)。
  2. DNS服务器收到客户端的请求之后,向DNS根服务器发送一样的A记录请求,因为DNS根服务器不支持递归查询,所以返回知道这个域名的DNS服务器列表(NS记录)和对应的IP地址。
  3. DNS服务器选择最靠前的下一跳DNS服务器(NS记录里)接着发送递归查询。
  4. 下一跳DNS服务器返回域名的IP地址,如果下一跳DNS服务器不支持递归查询而返回下下一跳DNS服务器列表重复步骤3。

从中可以看出递归查询与非递归查询的区别:

  • 非递归查询返回知道那个域名的DNS服务器地址,让你继续去查。
  • 递归查询是让DNS服务器一级级往下查直到查到IP地址为止,很像一个递归过程。

实例:

第一步:找出DNS根服务器:

查询DNS根的NS记录获得13个DNS根服务器域名和IP地址:

$dig . ns 或直接 $dig

;; AUTHORITY SECTION:
.           37383   IN  NS  b.root-servers.net.
.           37383   IN  NS  c.root-servers.net.
.           37383   IN  NS  f.root-servers.net.
.           37383   IN  NS  l.root-servers.net.
.           37383   IN  NS  i.root-servers.net.
.           37383   IN  NS  d.root-servers.net.
.           37383   IN  NS  e.root-servers.net.
.           37383   IN  NS  a.root-servers.net.
.           37383   IN  NS  k.root-servers.net.
.           37383   IN  NS  m.root-servers.net.
.           37383   IN  NS  g.root-servers.net.
.           37383   IN  NS  h.root-servers.net.
.           37383   IN  NS  j.root-servers.net.

;; ADDITIONAL SECTION:
k.root-servers.net. 3580415 IN  A   193.0.14.129
k.root-servers.net. 3581367 IN  AAAA    2001:7fd::1
a.root-servers.net. 3579080 IN  A   198.41.0.4
a.root-servers.net. 3567490 IN  AAAA    2001:503:ba3e::2:30
e.root-servers.net. 3580333 IN  A   192.203.230.10
d.root-servers.net. 3581308 IN  A   128.8.10.90
d.root-servers.net. 3530630 IN  AAAA    2001:500:2d::d
i.root-servers.net. 3580233 IN  A   192.36.148.17
i.root-servers.net. 3568782 IN  AAAA    2001:7fe::53
l.root-servers.net. 3579724 IN  A   199.7.83.42
l.root-servers.net. 3593302 IN  AAAA    2001:500:3::42
f.root-servers.net. 3580192 IN  A   192.5.5.241

上面的AAAA是IPv6地址记录。

而且貌似默认的电信DNS服务器的TTL(就是DNS服务器Cache时间)很不准(一下子15到515,不知道TTL到底是多少),而google的8.8.8.8很准一直从600秒(10钟)递减:)。

$dig www.freezhongzi.info @8.8.8.8
...
www.freezhongzi.info.   600 IN  A   xxx.xxx.xxx.xxx
...

$dig www.freezhongzi.info @8.8.8.8
...
www.freezhongzi.info.   576 IN  A   xxx.xxx.xxx.xxx
...

$dig www.freezhongzi.info @8.8.8.8
...
www.freezhongzi.info.   573 IN  A   xxx.xxx.xxx.xxx
...

第二步:随便选一个m.root-servers.net的IP地址执行递归查询:

$dig +norecurse www.freezhongzi.info @202.12.27.33

;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 12

;; QUESTION SECTION:
;www.freezhongzi.info.      IN  A

;; AUTHORITY SECTION:
info.           172800  IN  NS  b2.info.afilias-nst.org.
info.           172800  IN  NS  b0.info.afilias-nst.org.
info.           172800  IN  NS  a0.info.afilias-nst.info.
info.           172800  IN  NS  c0.info.afilias-nst.info.
info.           172800  IN  NS  d0.info.afilias-nst.org.
info.           172800  IN  NS  a2.info.afilias-nst.info.

;; ADDITIONAL SECTION:
a0.info.afilias-nst.info. 172800 IN A   199.254.31.1
a2.info.afilias-nst.info. 172800 IN A   199.249.113.1
b0.info.afilias-nst.org. 172800 IN  A   199.254.48.1
b2.info.afilias-nst.org. 172800 IN  A   199.249.121.1
c0.info.afilias-nst.info. 172800 IN A   199.254.49.1
d0.info.afilias-nst.org. 172800 IN  A   199.254.50.1
a0.info.afilias-nst.info. 172800 IN AAAA    2001:500:19::1
a2.info.afilias-nst.info. 172800 IN AAAA    2001:500:41::1
b0.info.afilias-nst.org. 172800 IN  AAAA    2001:500:1a::1
b2.info.afilias-nst.org. 172800 IN  AAAA    2001:500:49::1
c0.info.afilias-nst.info. 172800 IN AAAA    2001:500:1b::1
d0.info.afilias-nst.org. 172800 IN  AAAA    2001:500:1c::1

可以看到DNS根服务器不支持递归查询(没有RA标记)。

第三步:选择下一跳.info DNS服务器接着查询:

$dig www.freezhongzi.info @d0.info.afilias-nst.org.

;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;www.freezhongzi.info.      IN  A

;; AUTHORITY SECTION:
freezhongzi.info.   86400   IN  NS  f1g1ns2.dnspod.net.
freezhongzi.info.   86400   IN  NS  f1g1ns1.dnspod.net.

发现.info也不支持递归查询,返回的两个DNS服务器:

f1g1ns1.dnspod.net
f1g1ns2.dnspod.net

如果熟悉dnspod的会知道那是它的DNS服务器域名,我的freezhongzi.info就是由它托管的:)

最后一部就是向dnspod索要了:

$dig www.freezhongzi.info @f1g1ns1.dnspod.net

;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; ANSWER SECTION:
www.freezhongzi.info.   600 IN  A   xxx.xxx.xxx.xxx

;; AUTHORITY SECTION:
freezhongzi.info.   600 IN  NS  f1g1ns2.dnspod.net.
freezhongzi.info.   600 IN  NS  f1g1ns1.dnspod.net.

dnspod也不支持递归查询,但终于返回我要的IP地址了。

整个过程就是如图:

C++ trivial和non-trivial构造函数及POD类型

今天看书看到侯捷的《STL源码剖析》里提到trivial和non-trivial及POD类型,查了些资料理解了一下。

trivial意思是无意义,这个trivial和non-trivial是对类的四种函数来说的:

  • 构造函数(ctor)
  • 复制构造函数(copy)
  • 赋值函数(assignment)
  • 析构函数(dtor)

如果至少满足下面3条里的一条:

  1. 显式(explict)定义了这四种函数。
  2. 类里有非静态非POD的数据成员。
  3. 有基类。

那么上面的四种函数是non-trivial函数,比如叫non-trivial ctor、non-trivial copy…,也就是说有意义的函数,里面有一下必要的操作,比如类成员的初始化,释放内存等。

那个POD意思是Plain Old Data,也就是C++的内建类型或传统的C结构体类型。POD类型必然有trivial ctor/dtor/copy/assignment四种函数。

//整个T是POD类型
class T
{
    //没有显式定义ctor/dtor/copy/assignemt所以都是trivial
    int a; //POD类型
};

//整个T1是非POD类型
class T1
{
    T1() //显式定义了构造函数,所以是non-trivial ctor
    {}
    //没有显式定义ctor/dtor/copy/assignemt所以都是trivial
    int a;//POD类型
    std::string b; //非POD类型
};

那这有什么用处呢?

如果这个类都是trivial ctor/dtor/copy/assignment函数,我们对这个类进行构造、析构、拷贝和赋值时可以采用最有效率的方法,不调用无所事事正真的那些ctor/dtor等,而直接采用内存操作如malloc()、memcpy()等提高性能,这也是SGI STL内部干的事情。

比如STL的copy算法最基本的想法是这样的:

// 非POD重载指针数值
template <class T> void copy(T* source, T* destination, int n, __false_type)
{
    // 省略异常处理
    for (; n > 0; n--,source++,destination++)
    {
        // 调用source的复制构造函数
        constructor(source, *destination);
    }
}

// POD重载指针数值
template <class T> void copy(T* source, T* destination, int n, __false_type)
{
    // 省略异常处理
    memmove(source, destination, n);
}

当然实际的copy比这个复杂多了,有非常多的特化等,这个只是其中一方面而已。

换博客

博客建立一年了,一开始采用的是Python博客系统kukkaisvoima,好处是可以控制全局,喜欢怎么改就怎么改,不过改来改去仍显单调不好用,今天心血来潮试试传说中的Wordpress,只按了个markdown插件,以后的东西慢慢来吧。

下面是我那Python博客的第一篇博文,算缅怀过去,展望未来吧:)。

写与2011年10月20:

终于有了独立博客,先吐槽一下。网上用Python写的博客系统也太少了吧,好不容易才找到这个kukkaisvoima

今后多写写技术文章,提高一下写作能力,偶尔还可以玩玩服务器,很不错:)。

BTW:在这里缅怀一下刚去世的大师DMR, R.I.P。