URL: http://groundwavesimulation.com/Torterra/ 最近正在忙毕业设计和毕业论文。之前怕不能如期毕业,所以我不得不给之前做的地波雷达的项目做个“壳”。现在看来美国教授也很吃这一套,弄个B/S的壳后,我终于能够顺利毕业了:) 该项目可以理解为是尝试用ns-2来仿真地波雷达。整个仿真系统是搭建在Linux下。先通过Grwave计算Path Loss然后再带到ns-2中做仿真。 整个项目后续计划是加入Dynamic Spectrum access,并用gh_noise计算噪声。--》但愿老板能够给点钱:) 有钱才有动力。 现有的前端GUI部分是一个星期赶工的结果,用的技术也是2年前的老技术了。没啥创新... 希望下次能够有机会尝试下令人激动人心的新技术,比如Tornado,Redis :)

Greed is never good. - Linus Torvalds

下一版本的操作系统已经制作好,但是我在后续的开发上面遇到了困难(移植bash和gcc),我正在抓紧时间解决问题。等我先把需要学习的东西看懂并把手头的问题解决了,再继续发布教程。 另外,最近买了一个das的青轴机械键盘,非常不错:)

我们需要做的第一件事是在自己的电脑上搭建一个操作系统的开发环境。然后写个能显示"Hello World"的操作系统。

下面是我们需要准备的东西: 1、一个你操作熟练的编辑器,比如Vim 2、编辑C语言代码的gcc和binutils 3、用于自动化编译和链接的GNU Make 4、一个用于运行我们的操作系统的虚拟机,推荐使用Bochs。

安装上面的软件非常容易。在我的archlinux系统上面只需要一行命令

yaourt -S vim gcc binutils make bochs

就瞬间全部搞定了。 Ubuntu和Fedora系统安装这些工具应该也非常容易,如果有问题,大家自己用百度Google下就行了。 都安装好后,我们就要分析下下面需要做的事情了。我们已经有了Bochs作为虚拟机,而这个虚拟机可以通过模拟插入软盘或硬盘然后引导启动。我们可以把Bochs看作是一台电脑——事实上我们真的可以用一台电脑来代替它,只是在一开始的阶段,使用Bochs更方便于开发调试。 有了“电脑“后我们需要开发的第一个东西就是启动引导程序(Boot Loader),也就是让电脑在通电后通过引导程序运行我们的操作系统。但是这个Boot Loader的开发非常复杂,需要用到大量汇编知识。在这里我要介绍下UIUC的SigOps uBoot System。 这个uBoot系统是我们初学者的一个神器,它可以让你跳过令人头疼的Boot Loader的开发,而直接进入到下一阶段。它的用法很简单,使用一个bootmaker程序编译elf或者是其它文件然后创建一个SBBB (SigOps Bitchin' Boot Block 哈哈)的启动映像。然后我们就可以利用我们的Bochs来运行这个SBBB的启动映像了——这实在是太强大的一个工具了! 下面我来叙述下过程。 首先下载下面的文件

http://os-quake.googlecode.com/files/kernel_0_0_f.tar.gz

解压后我们看到里面有8个文件。其中main.c是我们写的"hello world"的主程序,bloader.h是对应的头文件,Makefile是对应的make文件,helloworld.ini是配置文件。bochsrc是我们所用的虚拟机bochs的配置文件,bootmaker我之前介绍过了。kernel.elf和helloworld.img是我们编译时才会生成的文件,我刚刚打包的时候一并打包进去了,你可以删掉然后让它重新生成。 再进行下一步之前,我们先熟悉下这些文件。首先看下main.c

#include "bloader.h"
int main();

/*Global Variables BAD BAD:) */
unsigned int oldEBP;
struct boot_dir *viewableDirectory;
int totalMem;
char * passedParams;
/*end global vars */

void _start(int memSize, char *parms, struct boot_dir *loadedfiles)
{
	asm("mov %%ebp, %0":"=m"(oldEBP));
	viewableDirectory = loadedfiles; /*make file mem locations global*/
	totalMem = memSize; /*make mem of system global*/
	passedParams = parms; /*make paramaters passed to system global*/
	main();

	asm("hlt");		/* this halts the machine, solving the problem of triple-faults on 
							some machines, but also making it impossible to return to DOS */
}

int main()
{
	char *vidmem = (char *) 0xb8000;
	
	/* "Hello " */
	vidmem[0] = 'H';
	vidmem[1] = 0x7;
	vidmem[2] = 'H';
	vidmem[3] = 0x7;
	vidmem[4] = 'e';
	vidmem[5] = 0x7;
	vidmem[6] = 'l';
	vidmem[7] = 0x7;
	vidmem[8] = 'l';
	vidmem[9] = 0x7;
	vidmem[10] = 'o';
	vidmem[11] = 0x7;

	/* "World " */
	vidmem[12] = 'W';
	vidmem[13] = 0x7;
	vidmem[14] = 'o';
	vidmem[15] = 0x7;
	vidmem[16] = 'r';
	vidmem[17] = 0x7;
	vidmem[18] = 'l';
	vidmem[19] = 0x7;
	vidmem[20] = 'd';
	vidmem[21] = 0x7;
	vidmem[22] = ' ';
	vidmem[23] = 0x7;

	/* "OS" */
	vidmem[24] = 'O';
	vidmem[25] = 0x7;
	vidmem[26] = 'S';
	vidmem[27] = 0x7;

	return 0;
}

main.c只有60多行,仔细看下。void start()应该就是我们的C程序和SigOps提供的bootloader之间的桥接函数,也就是我们使用bootmaker为我们的程序添加bootloader外壳时,它会让我们的程序从start()开始运行。事实上,实现这一点并不难。 我们可以通过类似下面的代码来实现一个类似的内核的main函数,并实现汇编和C之间的链接。 kernel_asm.asm

[bits 32] ; hey, we're in PMode

[global start]
[extern _kernel_main] ; always add a "_" in front of a C function to call it

start:
  call _kernel_main
  jmp $ ; halt

kernel_c.c

kernel_main()
{
     k_init();
     k_sayhello();
     ...
};

void _start()函数一开始做了一些初始化的工作,然后就直接跳转到main()函数。char vidmem = (char )0xb8000是CGA显示卡显示内存的地址(确切来说是 0XB800-0XBC00),一般的IBM PC在这一部分使用了统一编址的方式。因此若要让一个彩色字符显示在屏幕上,我们可以直接使用内存操作指令往这个内存区域执行写操作即可。0x7是一个控制字符,它用来设置字体的颜色为黑底白字。你可以查阅相关资料把它替换为其它颜色。(相关资料见 《Linux 内核完全剖析--基于0.12内核》 赵炯编著 机械工业出版社 2009.1 第24页 2.4.6 “显示控制”一节) Makefile没什么稀奇的,调用gcc把main.c编译为main.o 然后调用bootmaker读取helloworld.ini中的配置文件,bootloader生成一个包含bootloader的kernel.elf,然后利用ld命令把main.o和kernel.elf链接到一起生成helloworld.img。

好了,在了解了我们的程序之后,我们需要做的就是启动bochs虚拟机加载helloworld.img这个映像文件,然后启动。 下面是我们动手操作下,先输入命令make,生成helloworld.img映像文件,然后再用bochs加载它。

$ make $ bochs -f bochsrc

之后我们根据提示一路回车就可以看到我们的"Hello world"了! 就在屏幕的左上方,仔细找下 :)

如果运行起来有问题的话,请检查下虚拟机的配置文件里面的内容是否正确。确保里面romimage和varomimage的目录确实在对应的目录下。

好了,我们的"hello world"已经完成了。下面我们需要做的是要为它添加一些基础的功能,比如初学者最喜欢的printf()。

本系列文章旨在一步步指导读者完成一个操作系统的编写。不同于于渊大牛的《Orange's 一个操作系统的实现》,本系列文章将直接用C语言开始编写自己的内核,略过较为艰涩的汇编内容。因为作者我也是第一次尝试编写内核,所以文章中的错误应该不少,希望大家能够及时留言指正。

本系列文章使用的UIUC的SIGOPS代码。先向UIUC的大牛们致敬!

- 前言: 能够自己动手写一个操作系统是很多编程爱好者的梦想。不过,我们不得不承认,编写操作系统还是要比编写日常的程序要困难一些。因为这次你所编写的是操作系统,而这个系统要能够运行别人编写的日常程序。一个操作系统的创建,是一个白手起家的过程,你除了硬件和对应的手册,其他什么都没有。在我们操作系统开发的初期,我们会面临缺乏各种常用库,调试器和各种常用代码的窘境。好在现在我们有了互联网,网上丰富的资料把一切都变得简单了。

所需知识和设备: C or C++的语法知识 对计算机体系结构的了解,了解汇编语言。因为我们使用了SigOPS,而它已经提供了一个i386的结构,所以读者不需要一上来就陷入到汇编和计算机体系结构的细节当中去。我们会在后面根据需要逐步介绍。 一台装了Linux的机器:我只喜欢使用Linux。 坚持坚持坚持坚持坚持坚持坚持坚持

最终目标: 我希望在系列教程的最后,我们能够完成一个非常NX的操作系统。虽然在写下这段文字的我还没有达到这一目标,但是我会不断努力的。 我所说的NX的操作系统至少要具备: 能运行多个程序 能够有进程调度程序 有系统调用 有硬件中断....等等

好了 坑已经挖好了。下面开始动工!

这个脚本是根据图书的isbn号来抓取对应的图书评分信息的。data.csv是一个包含图书的isbn的列表文件,每一行是一个图书的isbn号。 这个版本只使用了单线程抓取,并且只能从csv文件中读取数据。因为是朋友拜托抓取的,数据量不大,以后如果有需要再慢慢改进好了。 整个Python脚本很简单,主要使用了BeautifulSoup进行html的内容提取。

P.S.最近手头还有几个非常有趣的项目正在制作,希望我能够早日搞定它们 :)

import urllib,urllib2
import re
import BeautifulSoup

def isbn_2_score(isbn):
    url = 'http://www.douban.com/subject_search?search_text='
    try:
        response = urllib2.urlopen(url+isbn)
    except Exception,e:
        return 0.0
    doc = response.read()
    soup = BeautifulSoup.BeautifulSoup(''.join(doc))
    try:
        book_info = soup.find("a",{"class":"nbg"})
    except Exception,e:
        return 0.0
    if isinstance(book_info,BeautifulSoup.Tag):
        url_book_info = book_info['href']
        try:
            response = urllib2.urlopen(url_book_info)
        except Exception,e:
            return 0.0
        book_page = response.read()
        soup = BeautifulSoup.BeautifulSoup(''.join(book_page))
        score_info = soup.find('strong','ll rating_num')
        if isinstance(book_info,BeautifulSoup.Tag):
            score = score_info.string
            return score
        return 0.0
    return 0.0

def read_file(file_name):
    file_handler = open(file_name,'r')
    return file_handler

def return_isbn(file_handler):
    isbn = file_handler.readline()
    return isbn


if __name__ == '__main__':
data = read_file('data.csv')
	f = open('dump','w')
	k = return_isbn(data)
	while k is not None:
    	score = isbn_2_score(k)
    	result = k[0:-1]+":"+str(score)+"\n"
    	print result
    	f.write(result)
    	k=return_isbn(data)
	f.close()

项目地址:https://github.com/quake0day/douban_crawler