我看过的unix/linux世界的好书

"Advanced Programming in the Unix Environment" Volum I 2nd Edition 大名鼎鼎的  apue 作者是享誉 unix 世界的大牛 Richard Stevens.全书分两卷。第一卷我看了两遍, 第二卷翻了翻目录,不想看。

"Linux Device Drivers" 3rd Edition 简称LDD.这本书的中文版翻译的奇烂无比。果断读影印版的,要么就别看了。

"Managing Projects with GNU make" 讲GNU make的书. make这个古老的build工具。怎么 说呢。至少我觉得语法设计的非常不友好。无奈的历史问题。

"Version Control with Git" 讲git的书.混了个眼熟。一个人单独做小规模开发用不到那 么多特性咯。

<Linux内核设计与实现> 很薄的一本讲linux kernel的书。这本书看的中文版。陈莉君翻 译的还不错。只有很少错误。

<Unix编程艺术> 这本书我有中文版和英文版。先买了英文版看看不懂,于是买了中文版看 。除非你的英文水平接近有native speaker的水平并且词汇量超大,至少在一万以上吧。 否则还是看中文版吧。中文版译得很不错。英文版哥看得非常吃力。5。哥的词汇量接近一万 对自己的英文水平看技术类书还是很自信的,但是写这本书的作者是一位极具个性,极具 争议的unix hacker,行文风格尽显不羁个性。同样这本书也是争议颇多。支持的奉为圣经 ,反对的嘲笑作者见识短浅。

"Advanced Bash programming Guide"  讲编写bash脚本的。看的网上的电子版。太多内容了,基本上bash的特性面面惧到。很多内容看了就忘了。

<鸟哥的私房菜 基础篇>据说是中文书里算入门的好书了。网上的口啤不错。个人感觉讲的 内容非常之浅,不过确实是本入门的好书。但不觉得有收藏价值。这套书还有服务器部分,没有看过。没兴趣也不需要看. 

正在看 Richard Stevens 的另一本bible,“Unix network Programming” Volumn I 3 rd Edition。 看完了一半。一定要在寒假结束前看完。和apue一样,虽然最新版都是由新 的作者在原来的基础上更改的,但仍然保持了Richard Stevens的行文风格用语简练不花哨 ,详细细致易懂的风格。 明年争取啃下 "Understanding Linux Kernel". 计划选择性看部分"Essential Linux Device Drivers". 顺便提一下Richard Steven写的另一套久负盛名的书Tcp/ip详解,共三卷。简单的过了一下第一卷。没有认真看。

copyright ykyi.net

linux的soname,链接库的问题.

第一次看到soname是读<程序员的自我修养.第一册:链接库>看来的。顺便说一下,这本书确实是本好书吖,国内出的难得技术好书。后来在公司的项目中把它从windows平台下移植到linux下,写makefile时用到过。

 

再后来又忘记了。今天再次看到soname的时候就有点记不起来了。又只好搜索了一些资料看。趁热打铁把学会的东西记下来。

linux为尝试解决动态链接库版本冲突的问题(windows平台下称之为DLL HELL),引入了soname进制。linux的动态链接库的扩展名约定为.so 即shared object的缩写。下面的makefile语句来自于哥今年上半年写的makefile文件:

VERSION_NUM := 1.0.0
soname = lib$(dirname).so.$(firstword $(subst ., ,$(VERSION_NUM)))
LINKFLAGS := -shared -Wl,-soname,$(soname) -L. -lpthread -lrt -lpentagon -lcross_platform
其中的变量$(soname)会被替换为eibcomm.so.1。再看看LINKFLAGS变量指定的几个选项. -shared 表示要生成一个shared object,即动态共享库. -pthread -lrt -lpentagon -lcross_platform 是要链接其它几个库,thread和linux的posix线程库,rt是一个和实时系统相关的库它提供了高精度的时间函数。

比较奇怪的是 -Wl,-soname,$(soname) 它们之前用逗号分开,而不是用空格分开。实际上这几个东东会被gcc传给ld(linux下的链接器)作为链接器的参数。gcc规定的写法就是这样的。指定的soname会被链接器写入到最终生成的elf文件中(linux下的可执行文件格式)。要查看elf文件的段布局什么的,可以用readelf工具。

 

最终生成的文件将命名为 libname.so.x.y.z 的形式。soname是libname.so.x的格式(也不尽然,这只是一个convetion,并非在语法或机制上强行要求)。接着把生成的so文件拷贝到/usr/lib 或者 /lib,这两个文件夹是系统用来放置动态链接库的地方。debian下没有把/usr/local/lib作为默认的动态链接库文件夹.可以通过改/etc/ld.so.conf 文件把更多的路径加入。再运行 ldconfig,更新cache中的库文件信息。为什么要用cache呢,有人就问了!因为library实在太多了咯,cache就被引用了。cache是个好东西啊!!!

这个时候依赖 libname.so.x 的文件就可以找到这个library并加载起来了。但是编译程序时还是找不到呢.编译程序时通常会写 -lname 这个时候会先找 libname.so 再找 libname.a 文件,结果找不到。link就会抱怨没有找到这个库文件。为了让编译通过,于是你就用 ln -sf libname.so libname.so.x.y.z (这个是realname,版本号部分可能只有x.y两个部分) 建一个软链接!搞定!

copyright ykyi.net

initramfs 和 initrd 的区别

Linux 2.6内核引入了一个新的feature叫做initramfs。与initrd相比,initramfs有几个好处。
initrd模拟一个磁盘(这就是它的名字的由来,initramdisk或initrd)。模拟磁盘也就同时引入了Linux的块IO子系统的开销,比如缓存(caching),而initramfs从根本上把cache也装载(mounted)成filesystem(因此叫做initramfs).

Initramfs建立在page cahce之上,和page cache一样,会动态地自动增长和缩减尺寸来减入内存的使用量,而initrd做不到这点。
另外,不像initrd需要文件系统驱动(filesystem driver)的支持,比如EXT2 driver,如果你的initrd使用ext2。而initramfs则不需要文件系统的支持,initramfs的实现代码很简单,只是基于page cache的简单一层。

copyright ykyi.net

Linux的开机启动顺序

对于x86机器的Linux的启动顺序,BIOS首先从启动设备载入MBR(Master Boot Record).存在MBR里的代码就去找分区表,从活动分区读入Linux的bootloader,最常用的像Grub,其它的有LILO,SYSLINUX。
Bootloader把压缩格式的内核映象载入并把控制权交给内核映像。
内核映像自解压,启动内核!

x86处理器有两种工作模式。实模式和保护模式。在实模式,你只能够寻址1M内存。保护模式下,就复杂得多,可以作到使用处理器的很多高级特性比如分页。CPU必须从实模式转到保护模式是一个单行通道(one-way street)。你不能从保护模式退入实模式。

内核第一阶段的内核初始化是在实模式中完成的。接下来从init/main.c 中定义的 start_kernel()函数进入你保护模式。start_kernel()先初始化CPU subsystem。接下来启动存储器和进程管理。然后启动外围总线和IO设备。启动序列的最后一个阶段便是init进程被启动。这个进程是所有的Linux进程的祖先。Init进程执行用户空间的脚本。这些脚本被用来启动必要的内核服务程序。Init最后spawn一个控制台给你。于是启动就完成了。

copyright ykyi.net