保护模式下段描述表分为全局描述符表(GDT)、中断描述表(IDT)、局部描述符表(LDT)。
linux使用以下段描述符:
.内核代码段
.内核数据段
.用户代码段
.用户数据段
.TSS段
.默认LDT段
GDT中的内核代码段(kernel code segment)描述表中的值如下:
.Base = 0x00000000
.Limit 0x00000000(2^32-1 = 4GB)
.G(颗粒标识) = 1,表示段的大小是以页为单位的
.S = 1,表示普通代码段或数据段
.Type = 0xa, 表示可以读取或者可以执行的代码段
.DPL = 0,表示内核模式
与这个段相关的线性地址是4GB, S=1 和type=0xa表示代码段,选择器在cs寄存器中,linux访问这个段选择器的宏是_KERNEL_CS.
Kernel data segment与上面的代码段相似,只是.Type的字段值为2,选择器在ds寄存器中,访问这个段选择器的宏是_KERNEL_DS
user code segment 由处于用户模式下的所有进程共享,存储在GDT中的对应段描述符的值如下:
.Base = 0x00000000
.Limit = 0xffffffff
.G = 1
.S = 1
.Type = 0xa
.DPL = 3 可使用_USER_CS访问 user data segment 中唯一不同的字段就是Type = 2,使用_USER_DS
除了以上的段描述表以外,GDT中还包含了用于创建每个进程的段描述 - TSS和LDT
每个TSS代表一个不同的进程,TSS中保存了每个CPU的硬件的上下文信息,它有助于切换上下文。
每个进程都有自己在GDT中存储器的对应的TSS描述符,其值如下:
.Base = &tss(对应进程描述符的TSS字段的地址,例如&tss_struct)
.Limit = 0xeb(TSS段的大小是236字节)
.Type = 9或11
.DPL = 0,用户模式不能访问TSS。G位被清除。
在linux下编程,最熟悉的不过是Makefile了。这个文件是用于自动连接和编译的,而且记录所有工程文件的修改信息,这样,这个工程在下次编译前会自动重新编译。
对应于target,”@” 是”argument”的简写。当你键入make foo的时候,”foo” 就是 argument,也就是@#(?).
与”$<”相类似,只不过它表示所有的的依赖的文件”^”记住嘛。
在依赖条件列表中的第一个输入文件。帮助记忆,”<”在shell中,这就是输入的”<”.
所有的比target新的依赖文件(input),”你在干什么,哪些文件必须改变?”
%的作用类似于”*“在shell的作用,也就是任意匹配
以上会衍生出$(@D) $(@F),也就是目录和文件的区别
main: main.o mytool1.o mytool2.o
gcc -o $@ $^
main.o: main.c mytool1.h mytool2.h
gcc -c $< # -c 只输出目标文件,不产生可执行文件
mytool1.o: mytool1.c mytool1.h
gcc -c $<
.c.o:
gcc -c $<
这个规则表示所有的 .o文件都是依赖对应的.c文件的,简化以后的Makefile
main: main.o mytool1.o mytool2.o
gcc -o $@ $^
.c.o:
gcc -c $<
Makefile中有很多的函数,这里,将碰到的一一记录下来,做个完善。
这个函数拾取特定目录下的文件通配符.比如我要将一个头文件.h三个源文件.c编译成 一个目标文件,那么,我就可以首先声明一个变量SRCS,然后将所有的源文件(包括头 文件)一起赋给它.
SRCS = $(wildcard *.c)
这样,变量SRCS就包括所有的源文件了
update 高级一点的用法,
$(patsubst %.c,%.o,$(wildcard))
这句话将所有文件名的后缀.c替换成.o,这样我们就可以得到当前目录下生成的可执行 文件。
hostname [none] display hostname
hostname -d #display machine belongs to the domain
hostname -f #display full name
hostname -i #display ip
ping [ip/address]
View network configure.
下面是我的ifconfig输出:
root@debian:/home/yubo/test/tmp/unix# ifconfig
eth0 Link encap:Ethernet HWaddr 08:9e:01:6d:08:4e
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:41 Base address:0x2000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:44786 errors:0 dropped:0 overruns:0 frame:0
TX packets:44786 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:22286992 (21.2 MiB) TX bytes:22286992 (21.2 MiB)
wlan0 Link encap:Ethernet HWaddr 80:9b:20:5c:23:04
inet addr:192.168.0.117 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::829b:20ff:fe5c:2304/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:94748 errors:0 dropped:0 overruns:0 frame:0
TX packets:208467 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:92813171 (88.5 MiB) TX bytes:22941747 (21.8 MiB)
root@debian:/home/yubo/test/tmp/unix# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 wlan0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
root@debian:/home/yubo/test/tmp/unix#
注意,我这里配合着route命令。
从上面的输出,我们可以了解到root主机上被激活的ip地址是wlan0,因为这是我在WIFI 条件下连接上网的。lo可以暂时忽略。eth0是以太网的连接。
由此说明,任何由root主机创建的IP包的源地址(source address) 是192.168.0.117. 类似的,任何由root主机收到的IP包的目的地址是192.168.0.117
用于无线网卡
从ip获得主机名或者从ip获得主机名
nsloopup google.com
查看数据包在提交到远程系统或者网站的时候所经过的ip,hoop,time
查看用户信息。
通过telnet协议连接目标主机,如果telnet连接可以在任一端口上完成即代表着两台主机间的连接良好。
telnet hostname port - 使用指定的端口telnet主机名。这通常用来测试主机是否在线或者网络是否正常。
有的发行版不带这些工具,需要我们自己去下载。
发现主机连接最有用最通用的Linux命令。你可以使用”netstat -g”查询该主机订阅的所有多播组(网络)
netstat -nap | grep port 将会显示使用该端口的应用程序的进程id
netstat -a or netstat –all 将会显示包括TCP和UDP的所有连接
netstat --tcp or netstat –t 将会显示TCP连接
netstat --udp or netstat –u 将会显示UDP连接
netstat -g 将会显示该主机订阅的所有多播网络。
iptables -L ## 查看
iptables -F ## 清空规则
控制进来的链接
转发。
root@debian:/home/yubo/test/tmp/unix# sudo iptables -L -v
Chain INPUT (policy ACCEPT 572K packets, 504M bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 1003K packets, 129M bytes)
pkts bytes target prot opt in out source destination
阻塞所有来自10.10.10.10的链接。
iptables -A INPUT -s 10.10.10.10 -j DROP
阻塞一个范围的网址:
iptables -A INPUT -s 10.10.10.0/24 -j DROP
链接到一个特别的端口, 阻塞来自于10.10.10.10的ssh链接
iptables -A input -p tcp --dport ssh -s 10.10.10.10 -j DROP
你可以使用其他协议将“ssh”或者其他端口号。”-p”是协议,如果你想阻塞UDP,则使用 “-p udp”.
如果你使用ssh链接主机,下面的命令慎用,危险!
iptables -A INPUT -p tcp --dport ssh -j DROP
ubuntu
sudo /sbin/iptables-save
Red Hat
/sbin/service iptables save
或者
/etc/init.d/iptables save
哪有什么起因啊,看着在linux kernel中大行其道的汇编代码,自己只能硬着头皮去找点资料来学习,不成想居然找到这么一个强悍的文章,如果你打算自己写一个编译器,那么这篇文章就是为你准备的,在这里
我们借助一个简单的例子,试着揭开linux下的真面目。
int main() { printf("hello,world\n"); return 0; }
在linux下使用 gcc -S test.c 就会产生test.s文件,我在自己机子上可能由于加了头文件,反正汇编后的代码和博客中的代码不太一样。
.file "test.c" .section .rodata .LC0: .string "hello,world!" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 andl $-16, %esp subl $16, %esp movl $.LC0, (%esp) call puts movl $0, %eax leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Debian 4.7.2-5) 4.7.2" .section .note.GNU-stack,"",@progbits
现在我们只需要关注三个不同的元素:
以__.开头的结构信息,.global main__说明main是一个全局符号可以被其他代码模块引用,.string 暗示一个可以插入到输出代码的字符常量。
以:结尾。它描述了名字和位置的联系。只要调用.LCO立马找到下面的字符串。main:被调用后,立即执行push %ebp(原文是这样表达的,但是我的不一样),在Labels前面用一个.开头的是一个由编译器临时产生的局部变量,其他的就是用户可见和全局变量,现在gcc默认是极大优化的)
如果我们把汇编代码弄成可执行代码,使用以下命令:
gcc -m32 test.s -o test
六个通用寄存器
%eax,%ebx,%ecx,%edx,%esi,%edi
两个堆栈寄存器
%esp,%ebp
bits:
%ah=%al ==> 8 bits. %ax ==>16 bits. %eax ==> 32 bits.
IA-32是 complex instruction set(CISC),so MOV has many different variants that move different types of data between different cells.
Suffix Name Size
B BYTE 8bits
W WORD 16 bits
L LONG 32 bits
在这里分为
global value
immediate value:($56)
register value:(%ebx)
indirect((%sp),也就是MASM中[bx]),
base-relative:(-12(%ecx))(这个语句是说这个值在%ecx暗示的地址(%ecx)下面12字节的内存中).
-12(%esi,%ebx,4): refers to the value at the address -12+%esi+%ebx*4
绝对跳转指令和返回指令需要加"*"
AT&T Intel 说明
Cbtw Cbw 把%al中的字节值符号扩展到%ax中
Cwtl Cwde 把%ax符号扩展到%eax中
Cwtd Cwd 把%ax符号扩展到%dx:%eax中
Cltd Cdq 把%eax符号扩展到%edx:%eaxAT&T
从linus那里pull,当然,前提是你先从linus那里clone一份代码树。
git pull
最好不用 `git pull`,使用`git fetch` 和 `git merge`来代替它.
撤销所有在本地的修改
git checkout -f
查看你所做的修改
git commit -a
撤销最近的提交
git reset HEAD~2
5.List all changes in working dir,in diff format
`git diff`
Dispaly changes since last commit
git diff HEAD
List all changeset descriptions
git log
追踪特定文件的changesets
git log net/ieee80211/ieee80211_module.c
List all branches
git branch
Make desired branch current in working dur
git checkout $branch
Create a new branch, and make it current
git checkout -b my-new-branch master
Examine which branch is current
git status
Obtain a diff between current branch with master branch
git diff master master..HEAD
Obtain a list of changes between current branch with master branch
git log master..HEAD
A one line summary of each changes
git shortlog master..HEAD
假设你在分支A,分支B上完成了工作,你需要把你的工作放进主分支M,
git checkout M
git merge A
git merge B
cd linux-source
git checkout -b tmp v2.6.22
cd linux-kernel-source
git am --utf8 --signoff /path/to/mbox
The –signoff option 暗示git am 在最后加上
Signed-off-by: Your Name <[email protected]>
The name and email are taken from the GIT_COMMITTER_NAME AND GIT_COMMITTER_EMAIL environment variables,(可以设定在.bash_profile 或者相似的文件)
git fetch --tags $URL
Tag a partical commit
cd linux-tree
git tag my-tag
#什麼是愛情