Makefile tutorial

工作中主要是通过ndk交叉编译生产arm平台的可执行程序及库,但实际调试代码时还是在x86上会更方便一些,因此对于自己编写或者移植过来的代码中没有makefile的就需要自己编写makefile来进行编译。

(一)单目录多文件Makefile编写

目录机构如下:

├── Libusb.c
├── Libusb.h
├── main.c
├── makefile
├── Makefile
├── mybluetooth.c
├── mybluetooth.h
├── obex.c
├── ObexDef.h
├── obex.h
├── ObexPack.c
└── ObexPack.h

一、 执行gcc分别编译

CFLAGS:= -g #-fshort-wchar

all : main
main : main.o mybluetooth.o Libusb.o obex.o ObexPack.o
    gcc $(CFLAGS) -o main main.o mybluetooth.o Libusb.o obex.o ObexPack.o -lbluetooth `pkg-config --cflags --libs libusb-1.0` -lusb

main.o : main.c
    gcc $(CFLAGS) -c main.c

Libusb.o: Libusb.c
    gcc $(CFLAGS) -c Libusb.c `pkg-config --libs --cflags libusb-1.0` -lusb

mybluetooth.o : mybluetooth.c
    gcc $(CFLAGS) -c mybluetooth.c -lbluetooth

obex.o: obex.c
    gcc $(CFLAGS) -c obex.c 

ObexPack.o: ObexPack.c
    gcc $(CFLAGS) -c ObexPack.c

clean:
    rm -rf *.o main .*.swp

二、使用makefile的自动推导功能

CC = gcc
CFLAGS = -g -Wall -I/usr/include/libusb-1.0  -lusb-1.0 -lusb -lbluetooth

OBJS= Libusb.o  main.o  mybluetooth.o  obex.o  ObexPack.o

main: $(OBJS)
    $(CC) -o main $(OBJS) $(CFLAGS)

#以下可以不用写
#main.o: ObexDef.h
#obex.o: obex.h
#ObexPack.o: ObexPack.h ObexDef.h
#Libusb.o: Libusb.h
#mybluetooth.o: mybluetooth.h

.PHONY: clean
clean:
    rm $(OBJS) main

(二)多目录多文件makefile编写

以下引用自博客园多目录下多文件 makefile编写
在编写多目录的makefile时,一般会用到如下的几个函数和变量;
函数:

wildcard 这是扩展通配符函数,功能是展开成一列所有符合由其参数描述的文 件名,文件间以空格间隔;比如:罗列出src下的所有.c文件:$(wildcard ${SRC}/*.c)

patsubst 这是匹配替换函数, patsubst ( 需要匹配的文件样式,匹配替换成什么文件,需要匹配的源文件)函数。比如:用src下的*.c替换成对应的 *.o文件存放到obj中:$(patsubst  %.c, ${OBJ}/%.o, $(notdir $(SOURCE)))

notdir 这是去除路径函数,在上面patsubst函数中已经使用过,去除SOURCE中文件的所有目录,只留下文件名;

变量:

$@:表示目标文件;一般是在规则中这么用:gcc  -o $@  $(object);

$^:表示所有依赖文件;一般是在规则中这么用:gcc -o $@  $^  ;用所有依赖文件链接成目的文件;

$<:表示第一个依赖文件;在规则中使用:gcc -o $@ -c $< ;其实这个时候就是每个依赖文件生成一个目的文件;

makefile模板:

#把所有的目录做成变量,方便修改和移植   
 BIN = ./bin  
 SRC = ./src  
 INC = ./include  
 OBJ = ./obj  

#提前所有源文件(即:*.c文件)和所有中间文件(即:*.o)  
 SOURCE = $(wildcard ${SRC}/*.c)  
 OBJECT = $(patsubst %.c,${OBJ}/%.o,$(notdir ${SOURCE}))  

#设置最后目标文件  
 TARGET = main  
 BIN_TARGET = ${BIN}/${TARGET}  

 CC = gcc   
 CFLAGS = -g -Wall -I${INC}   

#用所有中间文件生成目的文件,规则中可以用 $^替换掉 ${OBJECT}  
 ${BIN_TARGET}:${OBJECT}  
     $(CC) -o $@ ${OBJECT}  

#生成各个中间文件  
 ${OBJ}/%.o:${SRC}/%.c   
     $(CC) $(CFLAGS) -o $@ -c $<  

 .PHONY:clean  
 clean:  
     find $(OBJ) -name *.o -exec rm -rf {} \; #这个是find命令,不懂的可以查下资料  
     rm -rf $(BIN_TARGET)  

cmds_daily_use

split大文件分割与合并

分割:
split -b 800M VS2012_ULT_chs.iso VS2012_ULT_chs.iso
1.6G Jun 24 10:54 VS2012_ULT_chs.iso
800M Jun 24 17:16 VS2012_ULT_chs.isoaa
768M Jun 24 17:16 VS2012_ULT_chs.isoab
合并:
cat VS2012_ULT_chs.isoa* > VS2012_ULT_chs.iso

ubuntu apt install software

apt-cache search xxx
sudo apt-get install xxx

search cmd belond to which package

dpkg -S `cmd`

dpkg -S \`which ls\`
coreutils: /bin/ls

dpkg -L coreutils
/.
/bin
/bin/sync
/bin/cp
/bin/dir
/bin/mknod
/bin/cat
/bin/rm
/bin/rmdir
/bin/sleep
/bin/date
/bin/ls

打包压缩

tar cvf xxx.tar xxx
tar zcvf xxx.tar.gz xxx tar cvf xxx.tar xxx; gzip xxx.tar
tar jcvf xxx.tar.bz2 xxx tar cvf xxx.tar xxx; bzip2 -z xxx.tar

解包解压

tar xvf xxx.tar
tar zxvf xxx.tar.gz gizp -d xxx.tar.gz; tar xvf xxx.tar
tar jxvf xxx.tar.bz2 bzip2 -d xxx.tar.bz2; tar xvf xxx.tar

查看内容

tar tvf xxx.tar
tar ztvf xxx.gz
tar jtvf xxx.bz2

zip 加密

zip -e secure.zip -r files_to_incrypt

sed advanced usage

sed 'G' file        #行间插入空行
sed '$!G' file      #don't insert to the endline

sed ‘/^$/d; $!G’ file #first delete all space lines and the insert a space line

sed '=' file            #add line number
sed '=' file | sed 'N; s/\n/ /' #add line number to line start

sed -n '$p' file # print last line

sed ‘{:start; $q; N; 11,$D; b start}’ file #首先检查是不是数据流中的最后一行,如果是,quit命令会停止循环N命令会将下一行附加到模式空间的当前行后,如果当前行在第10行后面,11,$D命令会删除模式空间中的第一行。

sed '/./,/^$/!d' #区间开始会匹配任何含有至少一个字符的行,区间的结束地址会匹配一个空行,在这个区间内的行不会被删除。用于删除多余空白行,只保留一个空白行

sed '/./,$!d' #删除顶部空白行,从含有字符行开始,一直到数据流结束,之间的行都不会被删除。

sed ‘{:start; /^\n*$/{$d; N; b start}}’ #删除行尾空白行

sed 's/<[^>]*>//g' #删除HTML标签

Gitolite README

===============

about this README

Which is copied from gitolite’s repo.

(Github-users: click the “wiki” link before sending me anything via github.)

This is a minimal README for gitolite, so you can quickly get started with:

  • installing gitolite on a fresh userid on a Unix(-like) machine
  • learning enough to do some basic access control

For anything more, you need to look at the complete documentation, at:
http://gitolite.com/gitolite
. Please go there for what/why/how, concepts,
background, troubleshooting, more details on what is covered here, advanced
features not covered here, migration from older gitolite, and many more
topics.

Assumptions

  • You are familiar with:

    • OS: at least one Unix-like OS
    • ssh: ssh, ssh keys, ssh authorized keys file
    • git: basic use of git, bare and non-bare remotes
  • You are setting up a fresh, ssh-based, installation of gitolite on a Unix
    machine of some sort.

  • You have root access, or someone has created a userid called “git” for you
    to use and given you a password for it. This is a brand new userid (or
    you have deleted everything but .bashrc and similar files to make it
    look like one!)

  • If your server is not connected to the internet, you know how to clone the
    gitolite source code by using some in-between server or “git bundle”.

Installation and setup

server requirements

  • any unix system
  • sh
  • git 1.6.6 or later
  • perl 5.8.8 or later
  • openssh 5.0 or later
  • a dedicated userid to host the repos (in this document, we assume it is
    “git”, but it can be anything; substitute accordingly)
  • this user id does NOT currently have any ssh pubkey-based access
    • ideally, this user id has shell access ONLY by “su - git” from some
      other userid on the same server (this ensure minimal confusion for ssh
      newbies!)

steps to install

First, prepare the ssh key:

  • login to “git” on the server
  • make sure ~/.ssh/authorized_keys is empty or non-existent
  • make sure your ssh public key from your workstation has been copied as
    $HOME/YourName.pub

Next, install gitolite by running these commands:

git clone git://github.com/sitaramc/gitolite
mkdir -p $HOME/bin
gitolite/install -to $HOME/bin

Finally, setup gitolite with yourself as the administrator:

gitolite setup -pk YourName.pub

If the last command doesn’t run perhaps “bin” is not in your “PATH”. You can
either add it, or just run:

$HOME/bin/gitolite setup -pk YourName.pub

If you get any other errors please refer to the online documentation whose URL
was given at the top of this file.

adding users and repos

Do NOT add new repos or users manually on the server. Gitolite users,
repos, and access rules are maintained by making changes to a special repo
called “gitolite-admin” and pushing those changes to the server.

To administer your gitolite installation, start by doing this on your
workstation (if you have not already done so):

git clone git@host:gitolite-admin

NOTE: if you are asked for a password, something went wrong.. Go hit
the link for the complete documentation earlier in this file.


Now if you “cd gitolite-admin”, you will see two subdirectories in it: “conf”
and “keydir”.

To add new users alice, bob, and carol, obtain their public keys and add them
to “keydir” as alice.pub, bob.pub, and carol.pub respectively.

To add a new repo “foo” and give different levels of access to these
users, edit the file “conf/gitolite.conf” and add lines like this:

repo foo
    RW+         =   alice
    RW          =   bob
    R           =   carol

Once you have made these changes, do something like this:

git add conf
git add keydir
git commit -m "added foo, gave access to alice, bob, carol"
git push

When the push completes, gitolite will add the new users to
~/.ssh/authorized_keys on the server, as well as create a new, empty, repo
called “foo”.

help for your users

Once a user has sent you their public key and you have added them as
specified above and given them access, you have to tell them what URL to
access their repos at. This is usually “git clone git@host:reponame”; see
man git-clone for other forms.

NOTE: again, if they are asked for a password, something is wrong.

If they need to know what repos they have access to, they just have to run
“ssh git@host info”.

access rule examples

Gitolite’s access rules are very powerful. The simplest use was already
shown above. Here is a slightly more detailed example:

repo foo
    RW+                     =   alice
    -   master              =   bob
    -   refs/tags/v[0-9]    =   bob
    RW                      =   bob
    RW  refs/tags/v[0-9]    =   carol
    R                       =   dave

Here’s what these example rules say:

  • alice can do anything to any branch or tag — create, push,
    delete, rewind/overwrite etc.

  • bob can create or fast-forward push any branch whose name does
    not start with “master” and create any tag whose name does not
    start with “v”+digit.

  • carol can create tags whose names start with “v”+digit.

  • dave can clone/fetch.

Please see the main documentation linked above for all the gory details, as
well as more features and examples.

groups

Gitolite allows you to group users or repos for convenience. Here’s an
example that creates two groups of users:

@staff      =   alice bob carol
@interns    =   ashok

repo secret
    RW      =   @staff

repo foss
    RW+     =   @staff
    RW      =   @interns

Group lists accumulate. The following two lines have the same effect as
the earlier definition of @staff above:

@staff      =   alice bob
@staff      =   carol

You can also use group names in other group names:

@all-devs   =   @staff @interns

Finally, @all is a special group name that is often convenient to use if
you really mean “all repos” or “all users”.

commands

Users can run certain commands remotely, using ssh. Running

ssh git@host help

prints a list of available commands.

The most commonly used command is “info”. All commands respond to a
single argument of “-h” with suitable information.

If you have shell on the server, you have a lot more commands available to
you; try running “gitolite help”.

LICENSE

contact and support

Please see http://gitolite.com/gitolite/#contact for mailing list and IRC
info.

license

The gitolite software is copyright Sitaram Chamarty and is licensed under the
GPL v2; please see the file called COPYING in the source distribution.

Please see http://gitolite.com/gitolite/#license for more.


NOTE: GIT is a trademark of Software Freedom Conservancy and my use of
“Gitolite” is under license.


scm command line

scm command line usage

这里介绍下工作中经常使用的到的代码管理工具svn 和git的常用命令, 本人对svn使用的比较少,工作中主要使用git。

svn command line

将文件从服务器更新到本地版本库:
svn checkout path (path 为svn仓库路径)
例如:

svn checkout file:///F:/svn_test
svn co http://xx.xx.xx.xx/svn/svn_test

添加文件到版本库
svn add file(folder)
例如:

svn add test.c

查看文件或者目录状态
svn status path(file)

svn st test.c

将改动的文件提交到版本库
svn commit -m “LogMessage“ [-N] [—no-unlock] PATH(如果选择了保持锁,就使用–no-unlock开关)
例如:

svn ci -m "update test.c" test.c

更新版本库
svn update
svn update如果后面没有目录,默认将当前目录以及子目录下的所有文件都更新到最新版本。
svn update -r 200 test.c(将版本库中的文件test.c还原到版本200)
svn update test.c(更新,于版本库同步。如果在提交的时候提示过期的话,是因为冲突,需要先update,修改文件,然后清除svn resolved,最后再提交commit)
例如:

svn up

删除文件
svn delete file -m “delete file”
例如:

svn del test.c
svn ci -m "delete test.c"

查看日志

svn log path

查看文件信息

svn info path

比较差异

svn diff path

git command line

初始化纯仓库

mkdir project.git && cd project.git
git init --bare

初始化仓库并添加到服务器

cd myproject
git init 
git add .
git commit -m "initialize repo"
git remote add origin xxx/project.git
git push origin master

克隆仓库

git clone xxx/project.git 
or
git clone xxx/project.git mywork

查看远端分支

git branch -r

新建并切换到远端对应的分支:

git checkout -b new_branch

分支操作

git branch develop    #创建一个名为develop的本地分支
git checkout develop    #切换到本地的develop分支上
git push origin develop     #创建远端develop分支
git checkout --track origin/develop #拉取远端develop分支
git push origin develop:develop    #提交分支到远端
git push origin :develop#删除远端develop分支
git fetch --prune    #删除已经不存在的远端分支

标签操作

git tags        #显示已有标签
git tag v1.1.09     #创建轻量级标签
git tag -a v1.1.0 -m “comments for the tag”the#创建含附注标签
git push origin v1.1.06     #将标签推送到远端服务器
git push origin --tags#一次推送所有本地新增标签
git push origin :refs/tags/v1.1.06#删除远端v1.1.0标签
git tag -d v1.1.06      #删除本地v1.1.0标签

添加.gitignore
通常将不需要纳入git管理,又不希望总是出现在未跟踪文件列表里的文件(如编译过程中生成的文件等等),通过创建.gitignore文件来忽略它们,规则请google。
若.gitignore失效,可如下操作

git rm -rf --cached .
git add .
git commit -m “now .gitignore should working”

服务器地址变更后,工作目录做如下操作

git remote set-url origin git@xxx.xxx.xxx.xxx:/home/git/repositories/project.git
git remote show origin  #查看变更后的远程仓库信息

git仓库服务器迁移

git clone --bare git@oldserver:project.git  #从原服务器获取纯仓库
cd project.git
git push --mirror git@newserver:newproject.git #以镜像方式将仓库推送到新的服务器 

分支工作流程

git pull#获取服务器最新的代码
git checkout -b foobar#创建并切换到一个本地分支
… hack hack hcak …创建并切换到一个本地分支#在本地的该分支上做开发
git status#查看修改
git checkout --files        #取消修改
git add files#暂存修改
git reset HEAD xxx#取消暂存
git add xxx     #暂存修改
git commit    #提交
git checkout master#切换到本地master分支
git merge --no-ff foobar#将foobar分支的merge到master分支
git push origin master#更新到远端master分支
git branch -d foorbar#删除本地foobar分支
git branch -D foobar#若要删除未merge的foobar分支使用-D

撤销未更新到远端的commit

git log    #查看提交的commit
git reset --mixed  commit#回到待add状态
git reset --soft   commit#回到待commit状态
git reset --hard  commit#清楚所有修改 (注:会撤销所有的修改)

撤销已更新到远端的commit(注:该操作会丢掉所有该commit之后的更新),若有其他人已更新,则也需要在其工作目录回退到对应的commit。

git log    #查看提交的commit
git reset --hard commit#回退到某个commit状态
git push origin develop -foobar#强制更新到远端服务器 

撤销已更新到远端的提交:(git revert ,当执行过git push后,想安全撤销该次的push操作)

git log    # 1.查看该次提交的sha1值
    commit 2996d7ff2b345c826b51da922b63e8efadb6b146
    Author: Wonfee <dasifly@gmail.com>
    Date:   Thu Jul 2 08:16:52 2015 +0800
    remove useless file

git revert 2996d7ff2b345c826b51da922b63e8efadb6b146 # 2.执行revert操作
git push   # 3.更新到远端仓库
这样就可以将上次的commit安全的撤销

stash 使用
当你在某个分支进行的开发工作还没完成时,此时主分支发现有bug必须立即去修复,而此时又不想提交还没完成的分支开发,可以使用stash来储存你的开发。

… hack hack hack …
git stash
fix emergency bugs
git commit
git stash popcontinue hacking …

rebase使用

git checkout -b feature_dev dev
bala bala …
git add xxx
git commit -a “xxxx”xxxx        #在临时分支上做开发提交
git checkout dev                #切回本地dev分支
git pull origin develop        #将远程dev分支更新到本地
git checkout  feature_dev       #切回临时开发分支
git rebase dev                  # 执行 rebase操作
git checkout dev                #切回本地dev分支
git merge --no-ff  feature_dev  #合并临时分支
git push origin dev             #更新到服务器
git branch -d  feature_dev      # 删除临时分支

其他常用命令

gitk图形化工具,方便查看项目的更新情况
git diff xxx            查看修改的差异
git log                 查看提交的commit
git tag                 查看所有的tag
git checkout commit     切换到某个commit
git checkout tag    切换到某个标签

推荐书籍:
progit.zh.pdf
Git权威指南.pdf

linux_driver_module

linux device driver tutorial

The first driver:

loading and removing the driver in user space
nothing.c

#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");

Makefile

obj-m := nothing.o

compile and test:

$make -C /usr/src/linux-headers-3.16.7-ckt5my-very-own-kernel M=`pwd` modules

或者

make -C /lib/modules/`uname -r`/build M=`pwd` modules

out:

make: Entering directory `/usr/src/linux-lts-utopic-3.16.0'
  CC [M]  /home/wonfee/wonfee/linux/driver-tutorial/nothing/nothing.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/wonfee/wonfee/linux/driver-tutorial/nothing/nothing.mod.o
  LD [M]  /home/wonfee/wonfee/linux/driver-tutorial/nothing/nothing.ko

  sudo insmod nothing.ko
  lsmod |grep nothing
  nothing                 8255  0
  sudo rmmod nothing

The “Hello world” driver:

loading and removing the driver in kernel space
hello.c

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

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
    printk(KERN_DEBUG "Hello World !!!\n");
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_DEBUG "Bye bye !!!\n");
}

module_init(hello_init);
module_exit(hello_exit);

make -C /usr/src/linux-headers-3.16.7-ckt5my-very-own-kernel M=`pwd` modules

make: Entering directory `/usr/src/linux-lts-utopic-3.16.0'
  CC [M]  /home/wonfee/wonfee/linux/driver-tutorial/helloworld/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: "mcount" [/home/wonfee/wonfee/linux/driver-tutorial/helloworld/hello.ko] undefined!
  CC      /home/wonfee/wonfee/linux/driver-tutorial/helloworld/hello.mod.o
  LD [M]  /home/wonfee/wonfee/linux/driver-tutorial/helloworld/hello.ko
make: Leaving directory `/usr/src/linux-lts-utopic-3.16.0'

sudo insmod hello.ko

insmod: ERROR: could not insert module hello.ko: Unknown symbol in module

dmesg |tail

...
[21684.565795] hello: Unknown symbol mcount (err 0)

加载内核模块出错,网上说是gcc 版本问题,当前使用的gcc是软链接到gcc-4.4,这是之前为了编译android源码时将gcc从4.8降到了4.4,重新将gcc链接到4.8:
gcc -v

gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

make -C /usr/src/linux-headers-3.16.7-ckt5my-very-own-kernel/ M=`pwd` modules

make: Entering directory `/usr/src/linux-lts-utopic-3.16.0'
  CC [M]  /home/wonfee/wonfee/linux/driver-tutorial/helloworld/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/wonfee/wonfee/linux/driver-tutorial/helloworld/hello.mod.o
  LD [M]  /home/wonfee/wonfee/linux/driver-tutorial/helloworld/hello.ko
make: Leaving directory `/usr/src/linux-lts-utopic-3.16.0'

sudo insmod hello.ko
dmesg |tail -n 1

[22644.697688] Hello World !!!

sudo rmmod hello
dmesg |tail -n 1

[22663.379104] Bye bye !!!

Makefile

//------------ General Makefile------------------
 obj-m := hello.o
 KERNELDIR := /lib/modules/$(shell uname -r)/build
 PWD := $(shell pwd)
 modules:
     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

编译模块,可以使用如下两种方式:

$make -C /usr/src/linux-xxx M=`pwd` modules

$make -C /lib/modules/uname -r/build M=pwd modules

两者效果相同, 只是使用的源码路径不一样,usr/src目录下那个源代码一般是我们自己下载后解压的或者系统更新时下载的,而lib目录下的则是在编译时自动copy过去的,两者其实是完全一样的。

hexo install

搭建 hexo blog

标签(空格分隔): other


安装 hexo:

mkdir hexo && cd hexo
sudo apt-get install npm
npm install hexo --save
npm install hexo-server --save
npm install hexo-deployer-git --save

tree -L 1
.
├── _config.yml
├── db.json
├── node_modules
├── package.json
├── public
├── scaffolds
├── source
└── themes


js node_modules/hexo/bin/hexo init

本地测试:

js node_modules/hexo/bin/hexo g
js node_modules/hexo/bin/hexo s
http://localhost:4000/

github 测试:

vim _config.yml

deploy:
  type: git
  repo: git@github.com:Wonfee/wonfee.github.io.git
  branch: master

npm install hexo-deployer-git --save
js node_modules/hexo/bin/hexo g
js node_modules/hexo/bin/hexo d

写博客:

js node_modules/hexo/bin/hexo n "My First Post"

编辑生成的 .md文件:

source/_posts/My-First-Post.md
js node_modules/hexo/bin/hexo g
js node_modules/hexo/bin/hexo d

My Home Page

推荐博文编辑工具:
Cmd Markdown
简书

Linux-0.11 compile

Linux-0.11 编译

参考链接: 泰晓科技

编译环境

cat /etc/issue
Ubuntu 14.04.2 LTS
uname -a
Linux wonfee-ThinkPad-T540p 3.16.7-ckt5my-very-own-kernel #1 SMP Fri Feb 27 23:04:29 CST 2015 x86_64 x86_64 x86_64 GNU/Linux
gcc -v
gcc version 4.4.7 (Ubuntu/Linaro 4.4.7-8ubuntu1)
qemu-x86_64 -version
qemu-x86_64 version 2.0.0 (Debian 2.0.0+dfsg-2ubuntu1.10), Copyright (c) 2003-2008 Fabrice Bellard 

下载:

git clone https://gitlab.com/tinylab/linux-0.11.git

编译:

cd linux-0.11 && make

硬盘启动:

make start-hd

硬盘启动调试:

make debug-hd
gdb images/kernel.sym
(gdb) target remote :1234
(gdb) b main
(gdb) c

查阅文档
[README.md]

 make help 
<<<<This is the basic help info of linux-0.11>>>

Usage:
     make --generate a kernel floppy Image with a fs on hda1
     make start -- start the kernel in vm (qemu/bochs)
     make start-fd -- start the kernel with fs in floppy
     make start-hd -- start the kernel with fs in hard disk
     make debug -- debug the kernel in qemu/bochs & gdb at port 1234
     make debug-fd -- debug the kernel with fs in floppy
     make debug-hd -- debug the kernel with fs in hard disk
     make disk  -- generate a kernel Image & copy it to floppy
     make cscope -- genereate the cscope index databases
     make tags -- generate the tag file
     make cg -- generate callgraph of the default main entry
     make cg f=func d=dir|file b=browser -- generate callgraph of func in file/directory
     make clean -- clean the object files
     make distclean -- only keep the source code files

Note!:
     * You need to install the following basic tools:
          ubuntu|debian, qemu|bochs, ctags, cscope, calltree, cflow, graphviz 
          vim-full, build-essential, hex, dd, gcc 4.3.2...
     * Becarefull to change the compiling options, which will heavily
     influence the compiling procedure and running result.

Author:
     * 1991, linus write and release the original linux 0.95(linux 0.11).
     * 2005, jiong.zhao<gohigh@sh163.net> release a new version 
     which can be used in RedHat 9 along with the book 'Explaining 
     Linux-0.11 Completly', and he build a site http://www.oldlinux.org
     * 2008, falcon<wuzhangjin@gmail.com> release a new version which can be
     used in ubuntu|debian 32bit|64bit with gcc 4.3.2, and give some new 
     features for experimenting. such as this help info, boot/bootsect.s and
     boot/setup.s with AT&T rewritting, porting to gcc 4.3.2 :-)
     * 2011, tigercn<moonlight.yang@gmail.com> port to new system and gcc.
     * 2012, yuanxinyu<yuanxinyu.hangzhou@gmail.com> add Mac OS X support.
     * 2015, falcon <wuzhangjin@gmail.com> back reorganize and maintain it.

<<<Be Happy To Play With It :-)>>>

生成函数调用关系图:

sudo apt-get install graphviz
make cg
display callgraph/main.__init_main_c.svg

Markdown 常用语法

Markdown 语法讲解

标题使用 :
只需要在文本前面加上#即可,同理、你还可以增加二级标题、三级标题、四级标题、五级标题和六级标题,总共六级,如下所示:

一级标题

二级标题

三级标题

四级标题

五级标题

六级标题

备注: “#” 和 [标题] 之间留有一个空格,次为markdown标准语法

列表使用:
在 Markdown 中,你只需要在文字前面加上 - 就可以了,例如:

  • 文本1
  • 文本2
  • 文本3

链接和图片使用:
链接:
简书
Cmd Markdown
图片:

备注:插入图片的语法和链接的语法很像,只是前面多了一个 !

引用:
在 Markdown 中,只需要在希望引用的文字前面加上 >就可以引用他人的文字, 如:

一盏灯, 一片昏黄; 一简书, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。

诗歌引用:

大漠孤烟直
长河落日圆

粗体和斜体:
Markdown 的粗体和斜体也非常简单,用两个 * 包含一段文本就是粗体的语法,用一个 * 包含一段文本就是斜体的语法。例如:
大漠孤烟直
长河落日圆

表格使用:

Tables Are Cool
col 3 is right-aligned $1600
col 2 is centered $12
zebra stripes are neat $1
dog bird cat
1 foo foo foo
2 bar bar bar

以上几种格式是比较常用的格式,Markdown 还有其他语法,如想了解和学习更多,可以参考这篇『Markdown 语法说明』