超时空要塞普罗多文明:BIOS启动过程分析 - 阿来的专栏 - CSDN博客
来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 09:36:22
1
对于电脑用户来说,打开电源启动电脑几乎是每天必做的事情,但计算机在显示这些启动画面的时候在做什么呢?大多数用户都未必清楚了。下面就向大家介绍一下从打开电源到出现Linux的登录窗口,计算机到底干了些什么工作,BIOS在其中起到什么作用。
电脑的启动过程中有一个非常完善的硬件自检机制。对于采用Award BIOS的电脑来说,它在上电自检那短暂的几秒钟里,就可以完成100多个检测步骤。
术语或缩写
描述
BIOS
基本输入/输出系统
CMOS
保存系统当前的硬件配置情况和用户的设定参数
POST
Power on self test, 加电自检
BIOS即基本输入/输出系统,它是被固化在计算机ROM芯片上的一组程序。它是微机系统软、硬件之间的一个可编程接口,通过跳线开关和系统配带的驱动程序盘,可以对ROM进行重写,方便地实现BIOS升级。
CMOS是一块可读写的RAM芯片,保存系统当前的硬件配置情况和用户的设定参数;BIOS中装有一个程序称为“系统设置程序”,设置CMOS中的参数;CMOS由电池供电,断电后数据会丢失;前16字节用于存储时间
、AWARD和PHONIX三大主流厂商
开发BIOS是一件技术含量很高的工作,从业人员也少;一流主板厂商的BIOS研发人员,年薪往往是以七位数字来计算的!
主要功能
BIOS的主要功能概括来说包括如下几部分:
1)POST
加电自检,检测CPU各寄存器、计时芯片、中断芯片、DMA控制器等
2)Initial
枚举设备,初始化寄存器,分配中断、IO端口、DMA资源等
3)Setup
进行系统设置,存于CMOS中。一般开机时按Del或者F2进入到BIOS的设置界面。
4)常驻程序
INT 10h、INT 13h、INT 15h等,提供给操作系统或应用程序调用。
5)启动自举程序
在POST过程结束后,将调用INT 19h,启动自举程序,自举程序将读取引导记录,装载操作系统。
源代码结构分析
代码结构分析
AMI BIOS的代码主要分成三大部分:核心代码、芯片代码和OEM代码。
核心代码目录结构如下:
代码结构分析
AWARD BIOS的源代码为进行目录分类,所有的源码、编译链接工具、生成的中间文件都在同一个目录中。没有AMI代码结构组织得好。
常驻程序介绍
开机自检程序运行完后,将撤出内存。BIOS提供了一组常驻程序,主要包括INT 10h,INT 13h,INT 15h等等中断服务例程,提供给操作系统或应用程序调用,下面介绍几个常用的中断服务例程。X86提供了256个中断,中断向量表在内存的起始地址1024byte上,每个中断向量地址占用4个字节。
中断例程
INT 13h为BIOS提供的对磁盘进行操作的中断例程,包括如下几种调用方式:
1)INT 13H,AH=00H 软、硬盘控制器复位;
2)INT 13H,AH=02H 读扇区说明;
3)INT 13H,AH=03H 写扇区;
4)INT 13H,AH=04H 检测扇区;
以上调用方法详细的说明请参考相关技术文档。
举例:读取软驱0面0道1扇区的内容到0:200
mov ax,0 /* 初始化ax寄存器为0 */
mov es,ax /* 将es置为0 */
mov bx,200h /* 将bx设置为200h ,此时es:dx = 0:200,为内存地址*/
mov al,1 /* al保存扇区数 */
mov ch,0 /* ch保存磁道号 */
mov cl,1 /* cl保存扇区号 */
mov dl,0 /* dl保存驱动器,0表示软驱A */
mov dh,0 /* dh保存磁头号 */
mov ah,2 /* ah保存int13要调用的功能号,2表示读 */
int 13h /* 调用int13中断 */
入口参数:
ah=int 13h的功能号
al=读取的扇区数
ch=磁道号
cl=扇区号
dh=磁头号(对于软盘即面号,因为一个面用一个磁头来读写)
dl=驱动器号 软驱从0开始,0:软驱A,1:软驱B;硬盘从80h开始,
80h:硬盘C,81h:硬盘D。
es:bx指向接收从扇区读入数据的内存区
返回参数:
操作成功:ah=0,al=读入的扇区数
操作失败:ah=出错代码
中断例程
屏幕I/O接口,切换各文字/图形模式,提供显示/绘图卷页服务。详细的调用方法可以参考相关的文档。例如00号功能:
功能号:00H
功能:设置显示模式
入口参数:AH=00H
AL=显示模式
显示模式列表:
显示模式 显示模式属性
00H 40×25 16色 文本
01H 40×25 16色 文本
02H 80×25 16色 文本
04H 320×200 4色
05H 320×200 4色
06H 640×200 2色
07H 80×25 2色 文本
08H 160×200 16色
09H 320×200 16色
0AH 640×200 4色
0BH 保留
0CH 保留
0DH 320×200 16色
0EH 640×200 16色
0FH 640×350 2色(单色)
10H 640×350 4色
11H 640×480 2色
12H 640×480 16色
13H 320×200 256色
中断例程
BIOS提供的键盘读取中断服务,功能如下表:
AH
功能
返回参数
0
从键盘读一字符
AL=字符码
AH=扫描码
1
读键盘缓冲区的字符
如ZF=0
AL=字符码
AH=扫描码
如ZF=1,缓冲区空
2
取键盘状态字节
AL=键盘状态字节
调用方法:
MOV AH,0 ; 读字符功能
INT 16H ; 键盘BIOS调用
工具获取中断例程的内存地址
在DOS模式下,进入DEBUG,输入
a100
int 10
t=100
得 0210:08A9
int 10h的中断服务程序入口地址存放在中断向量表中的物理地址是0000:0040H~0043H,指向CS:IP(0210:08A9),如下图执行结果:
系统开机启动的总体流程
启动过程概述
BIOS启动的过程主要包括POST过程和自举过程,其流程和执行指令地址的变化如下:
过程分析
POST过程在AWARD BIOS的源码中在BOOTROM.ASM文件中BootBlock_POST函数过程中实现,主要步骤如下:
1)初始化各种主板芯片组
2)初始化键盘控制器8042
3)初始化中断向量 ,中断服务例程.
4)初始化 VGA BIOS 控制器
5)显示BIOS的版本和公司名称
6)扫描软驱和各种介质容量
7)读取CMOS的启动顺序配置,并检测启动装置是否正常
8)调用INT 19h启动自举程序
以上每个过程都有大量的代码,在这不一一做仔细分析,请参考源代码。下面对第三步源码做一些分析。
中断向量表存储在内存的第一个1k空间里,本节主要分析AWARD BIOS中中断向量服务例程的初始化过程。
;[]==============================================================[]
;
; Initialize int. vectors (0-77h) to the spurious interrupt
; handler. Then initialize 00h-1fh to their proper places.
;
;[]==============================================================[]
POST_CODE 12
mov ax,cs
mov ds,ax
;
; Initialize vectors 00-77h to SPURIOUS_INT_HDLR
; 。。。。。。
。。。。。。
。。。。。。
;
; Initialize vectors 00-1fh to the real handlers
;
lea si,DGROUP:Int_Tbl
p10_21:
lodsb ;load next offset
cmp al,0ffh ;over?
je short Init_Vect_Over ;Yes,skip
movzx di,al ;get vector number
shl di,2 ;set to coresspond offset
movsw ;load offset from DS:[SI]
mov ax,cs ;get segment
stosw ;load segment
jmp short p10_21 ;next cycle
Init_Vect_Over:
mov al,10111100b ;Enable IRQ 0,1,6
out a8259+1,al
sti
看以上蓝色部分代码,为初始化中断服务例程,红色部分Int_Tb1为BIOS定义的中断服务例程列表,用于替换相应的中断服务。Int_Tb1的定义如下:
INT_TBL: db 2 ; INT02
DW OFFSET DGROUP:NMI_VECT ; INT02 offset
db 6 ; INT06
DW OFFSET DGROUP:LOADALL ; INVALID OP-CODE
db 8 ; INT08
DW OFFSET DGROUP:TIMER_VECT ; INT08 offset
db 9 ; INT09
DW OFFSET DGROUP:KBDINT_VECT ; INT09 offset
db 0eh ; INT0E
DW OFFSET DGROUP:DSKINT_VECT ; INT0E offset
db 11h ; INT11
DW OFFSET DGROUP:EQ_VECT ; INT11 offset
db 12h ; INT12
DW OFFSET DGROUP:MEM_SZ_VECT ; INT12 offset
db 13h ; INT13
DW OFFSET DGROUP:DSK_VECT ; INT13 offset
db 15h ; INT15
DW OFFSET DGROUP:Multi_Service ; INT15 offset
db 16h ; INT16
DW OFFSET DGROUP:KBD_VECT ; INT16 offset
db 19h ; INT19
DW OFFSET DGROUP:INT19_VECT ; INT19 offset
db 1Ah ; INT1A
DW OFFSET DGROUP:INT1A_VECT ; INT1A offset
db 1Eh ; INT1E
DW OFFSET DGROUP:FD_BIOS_PARMS ; INT1E offset
db 0ffh ; over
中断服务例程对应的函数也在Bootrom.asm文件中有实现。替换的中断服务例程总结如下。
中断号
BIOS中断例程
属性
备注
INT02
NMI_VECT
硬中断
None Maskable Interrupt,不可屏蔽中断
INT06
LOADALL
错误中断
非法,不支持的指令
INT08
TIMER_VECT
硬中断
IRQ0,系统定时器中断
INT09
KBDINT_VECT
硬中断
IRQ1,键盘中断
INT0E
DSKINT_VECT
硬中断
IRQ6,软盘驱动器读写中断
INT11
EQ_VECT
软中断
PC外围设备检查
INT12
MEM_SZ_VECT
软中断
PC主存储器大小检查
INT13
DSK_VECT
软中断
磁盘I/O接口(读写、复位等)
INT15
Multi_Service
软中断
卡带接口服务程序,AT扩展中断服务调用,程序多任务
INT16
KBD_VECT
软中断
键盘读取服务程序
INT19
INT19_VECT
软中断
激活操作系统的入口点
INT1A
INT1A_VECT
软中断
BIOS时间接口
INT1E
FD_BIOS_PARMS
软中断
软盘驱动器参数地址表
AWARD的其他中断服务调用未在BIOS中指定服务例程。
自举过程即为执行中断INT19的中断服务例程INT19_VECT的过程,该过程在AWARD的Bootrom.asm文件中实现,其主要功能为读取操作系统启动块,将其读入到内存0000:7C00h,并跳转至此处执行。下面分析一下操作系统启动块MBR是如何从磁盘中读取到内存0000:7C00h处的。
new_dsk:
mov es,dx ; set to load at 0:offset Boot
mov bx,offset Boot ; location to load boot sector
mov cx,1 ; set to read one sector
[U1]
int 13h ; reset disk
[U2]
int 13h ; read disk
jc short Boot_fail
[U3]
jc short Boot_fail ; invalid boot sector.
jmp far ptr Boot ; go to boot code
[U4]
lea ax,Bad_Disk_Msg ; boot failed
mov cx,Bad_Disk_Msg_Len
call Disk_Fail_Routine
[U5]
jmp short new_dsk
[U6]
mov dx,0ff01h
call Display_Str
;Beep out if no bootable media
mov bl,2 ; beep on override
mov cx,1700h
call SND_SPKR_TONE
xor cx,cx
loop short $
mov bl,5 ; beep on override
mov cx,3000h
call SND_SPKR_TONE
[U7]
endless:
xor ah,ah ;wait ENTER key
int 16h
cmp ah,1ch
jne short endless
ret
[U8]
流程图如下:
1)AMI和AWARD的BIOS源码
2)grub-0.97.tar.gz源码
3)AMI BIOS98 User Guide
4)AMI BIOS98 Technical Reference
5)《BIOS研发技术剖析》
6)网站搜索内容:
BIOS之家:www.bios.net.cn
Google
对于电脑用户来说,打开电源启动电脑几乎是每天必做的事情,但计算机在显示这些启动画面的时候在做什么呢?大多数用户都未必清楚了。下面就向大家介绍一下从打开电源到出现Linux的登录窗口,计算机到底干了些什么工作,BIOS在其中起到什么作用。
电脑的启动过程中有一个非常完善的硬件自检机制。对于采用Award BIOS的电脑来说,它在上电自检那短暂的几秒钟里,就可以完成100多个检测步骤。
术语或缩写
描述
BIOS
基本输入/输出系统
CMOS
保存系统当前的硬件配置情况和用户的设定参数
POST
Power on self test, 加电自检
BIOS即基本输入/输出系统,它是被固化在计算机ROM芯片上的一组程序。它是微机系统软、硬件之间的一个可编程接口,通过跳线开关和系统配带的驱动程序盘,可以对ROM进行重写,方便地实现BIOS升级。
CMOS是一块可读写的RAM芯片,保存系统当前的硬件配置情况和用户的设定参数;BIOS中装有一个程序称为“系统设置程序”,设置CMOS中的参数;CMOS由电池供电,断电后数据会丢失;前16字节用于存储时间
、AWARD和PHONIX三大主流厂商
开发BIOS是一件技术含量很高的工作,从业人员也少;一流主板厂商的BIOS研发人员,年薪往往是以七位数字来计算的!
主要功能
BIOS的主要功能概括来说包括如下几部分:
1)POST
加电自检,检测CPU各寄存器、计时芯片、中断芯片、DMA控制器等
2)Initial
枚举设备,初始化寄存器,分配中断、IO端口、DMA资源等
3)Setup
进行系统设置,存于CMOS中。一般开机时按Del或者F2进入到BIOS的设置界面。
4)常驻程序
INT 10h、INT 13h、INT 15h等,提供给操作系统或应用程序调用。
5)启动自举程序
在POST过程结束后,将调用INT 19h,启动自举程序,自举程序将读取引导记录,装载操作系统。
源代码结构分析
代码结构分析
AMI BIOS的代码主要分成三大部分:核心代码、芯片代码和OEM代码。
核心代码目录结构如下:
代码结构分析
AWARD BIOS的源代码为进行目录分类,所有的源码、编译链接工具、生成的中间文件都在同一个目录中。没有AMI代码结构组织得好。
常驻程序介绍
开机自检程序运行完后,将撤出内存。BIOS提供了一组常驻程序,主要包括INT 10h,INT 13h,INT 15h等等中断服务例程,提供给操作系统或应用程序调用,下面介绍几个常用的中断服务例程。X86提供了256个中断,中断向量表在内存的起始地址1024byte上,每个中断向量地址占用4个字节。
中断例程
INT 13h为BIOS提供的对磁盘进行操作的中断例程,包括如下几种调用方式:
1)INT 13H,AH=00H 软、硬盘控制器复位;
2)INT 13H,AH=02H 读扇区说明;
3)INT 13H,AH=03H 写扇区;
4)INT 13H,AH=04H 检测扇区;
以上调用方法详细的说明请参考相关技术文档。
举例:读取软驱0面0道1扇区的内容到0:200
mov ax,0 /* 初始化ax寄存器为0 */
mov es,ax /* 将es置为0 */
mov bx,200h /* 将bx设置为200h ,此时es:dx = 0:200,为内存地址*/
mov al,1 /* al保存扇区数 */
mov ch,0 /* ch保存磁道号 */
mov cl,1 /* cl保存扇区号 */
mov dl,0 /* dl保存驱动器,0表示软驱A */
mov dh,0 /* dh保存磁头号 */
mov ah,2 /* ah保存int13要调用的功能号,2表示读 */
int 13h /* 调用int13中断 */
入口参数:
ah=int 13h的功能号
al=读取的扇区数
ch=磁道号
cl=扇区号
dh=磁头号(对于软盘即面号,因为一个面用一个磁头来读写)
dl=驱动器号 软驱从0开始,0:软驱A,1:软驱B;硬盘从80h开始,
80h:硬盘C,81h:硬盘D。
es:bx指向接收从扇区读入数据的内存区
返回参数:
操作成功:ah=0,al=读入的扇区数
操作失败:ah=出错代码
中断例程
屏幕I/O接口,切换各文字/图形模式,提供显示/绘图卷页服务。详细的调用方法可以参考相关的文档。例如00号功能:
功能号:00H
功能:设置显示模式
入口参数:AH=00H
AL=显示模式
显示模式列表:
显示模式 显示模式属性
00H 40×25 16色 文本
01H 40×25 16色 文本
02H 80×25 16色 文本
04H 320×200 4色
05H 320×200 4色
06H 640×200 2色
07H 80×25 2色 文本
08H 160×200 16色
09H 320×200 16色
0AH 640×200 4色
0BH 保留
0CH 保留
0DH 320×200 16色
0EH 640×200 16色
0FH 640×350 2色(单色)
10H 640×350 4色
11H 640×480 2色
12H 640×480 16色
13H 320×200 256色
中断例程
BIOS提供的键盘读取中断服务,功能如下表:
AH
功能
返回参数
0
从键盘读一字符
AL=字符码
AH=扫描码
1
读键盘缓冲区的字符
如ZF=0
AL=字符码
AH=扫描码
如ZF=1,缓冲区空
2
取键盘状态字节
AL=键盘状态字节
调用方法:
MOV AH,0 ; 读字符功能
INT 16H ; 键盘BIOS调用
工具获取中断例程的内存地址
在DOS模式下,进入DEBUG,输入
a100
int 10
t=100
得 0210:08A9
int 10h的中断服务程序入口地址存放在中断向量表中的物理地址是0000:0040H~0043H,指向CS:IP(0210:08A9),如下图执行结果:
系统开机启动的总体流程
启动过程概述
BIOS启动的过程主要包括POST过程和自举过程,其流程和执行指令地址的变化如下:
过程分析
POST过程在AWARD BIOS的源码中在BOOTROM.ASM文件中BootBlock_POST函数过程中实现,主要步骤如下:
1)初始化各种主板芯片组
2)初始化键盘控制器8042
3)初始化中断向量 ,中断服务例程.
4)初始化 VGA BIOS 控制器
5)显示BIOS的版本和公司名称
6)扫描软驱和各种介质容量
7)读取CMOS的启动顺序配置,并检测启动装置是否正常
8)调用INT 19h启动自举程序
以上每个过程都有大量的代码,在这不一一做仔细分析,请参考源代码。下面对第三步源码做一些分析。
中断向量表存储在内存的第一个1k空间里,本节主要分析AWARD BIOS中中断向量服务例程的初始化过程。
;[]==============================================================[]
;
; Initialize int. vectors (0-77h) to the spurious interrupt
; handler. Then initialize 00h-1fh to their proper places.
;
;[]==============================================================[]
POST_CODE 12
mov ax,cs
mov ds,ax
;
; Initialize vectors 00-77h to SPURIOUS_INT_HDLR
; 。。。。。。
。。。。。。
。。。。。。
;
; Initialize vectors 00-1fh to the real handlers
;
lea si,DGROUP:Int_Tbl
p10_21:
lodsb ;load next offset
cmp al,0ffh ;over?
je short Init_Vect_Over ;Yes,skip
movzx di,al ;get vector number
shl di,2 ;set to coresspond offset
movsw ;load offset from DS:[SI]
mov ax,cs ;get segment
stosw ;load segment
jmp short p10_21 ;next cycle
Init_Vect_Over:
mov al,10111100b ;Enable IRQ 0,1,6
out a8259+1,al
sti
看以上蓝色部分代码,为初始化中断服务例程,红色部分Int_Tb1为BIOS定义的中断服务例程列表,用于替换相应的中断服务。Int_Tb1的定义如下:
INT_TBL: db 2 ; INT02
DW OFFSET DGROUP:NMI_VECT ; INT02 offset
db 6 ; INT06
DW OFFSET DGROUP:LOADALL ; INVALID OP-CODE
db 8 ; INT08
DW OFFSET DGROUP:TIMER_VECT ; INT08 offset
db 9 ; INT09
DW OFFSET DGROUP:KBDINT_VECT ; INT09 offset
db 0eh ; INT0E
DW OFFSET DGROUP:DSKINT_VECT ; INT0E offset
db 11h ; INT11
DW OFFSET DGROUP:EQ_VECT ; INT11 offset
db 12h ; INT12
DW OFFSET DGROUP:MEM_SZ_VECT ; INT12 offset
db 13h ; INT13
DW OFFSET DGROUP:DSK_VECT ; INT13 offset
db 15h ; INT15
DW OFFSET DGROUP:Multi_Service ; INT15 offset
db 16h ; INT16
DW OFFSET DGROUP:KBD_VECT ; INT16 offset
db 19h ; INT19
DW OFFSET DGROUP:INT19_VECT ; INT19 offset
db 1Ah ; INT1A
DW OFFSET DGROUP:INT1A_VECT ; INT1A offset
db 1Eh ; INT1E
DW OFFSET DGROUP:FD_BIOS_PARMS ; INT1E offset
db 0ffh ; over
中断服务例程对应的函数也在Bootrom.asm文件中有实现。替换的中断服务例程总结如下。
中断号
BIOS中断例程
属性
备注
INT02
NMI_VECT
硬中断
None Maskable Interrupt,不可屏蔽中断
INT06
LOADALL
错误中断
非法,不支持的指令
INT08
TIMER_VECT
硬中断
IRQ0,系统定时器中断
INT09
KBDINT_VECT
硬中断
IRQ1,键盘中断
INT0E
DSKINT_VECT
硬中断
IRQ6,软盘驱动器读写中断
INT11
EQ_VECT
软中断
PC外围设备检查
INT12
MEM_SZ_VECT
软中断
PC主存储器大小检查
INT13
DSK_VECT
软中断
磁盘I/O接口(读写、复位等)
INT15
Multi_Service
软中断
卡带接口服务程序,AT扩展中断服务调用,程序多任务
INT16
KBD_VECT
软中断
键盘读取服务程序
INT19
INT19_VECT
软中断
激活操作系统的入口点
INT1A
INT1A_VECT
软中断
BIOS时间接口
INT1E
FD_BIOS_PARMS
软中断
软盘驱动器参数地址表
AWARD的其他中断服务调用未在BIOS中指定服务例程。
自举过程即为执行中断INT19的中断服务例程INT19_VECT的过程,该过程在AWARD的Bootrom.asm文件中实现,其主要功能为读取操作系统启动块,将其读入到内存0000:7C00h,并跳转至此处执行。下面分析一下操作系统启动块MBR是如何从磁盘中读取到内存0000:7C00h处的。
new_dsk:
mov es,dx ; set to load at 0:offset Boot
mov bx,offset Boot ; location to load boot sector
mov cx,1 ; set to read one sector
[U1]
int 13h ; reset disk
[U2]
int 13h ; read disk
jc short Boot_fail
[U3]
jc short Boot_fail ; invalid boot sector.
jmp far ptr Boot ; go to boot code
[U4]
lea ax,Bad_Disk_Msg ; boot failed
mov cx,Bad_Disk_Msg_Len
call Disk_Fail_Routine
[U5]
jmp short new_dsk
[U6]
mov dx,0ff01h
call Display_Str
;Beep out if no bootable media
mov bl,2 ; beep on override
mov cx,1700h
call SND_SPKR_TONE
xor cx,cx
loop short $
mov bl,5 ; beep on override
mov cx,3000h
call SND_SPKR_TONE
[U7]
endless:
xor ah,ah ;wait ENTER key
int 16h
cmp ah,1ch
jne short endless
ret
[U8]
流程图如下:
1)AMI和AWARD的BIOS源码
2)grub-0.97.tar.gz源码
3)AMI BIOS98 User Guide
4)AMI BIOS98 Technical Reference
5)《BIOS研发技术剖析》
6)网站搜索内容:
BIOS之家:www.bios.net.cn
BIOS启动过程分析 - 阿来的专栏 - CSDN博客
Heapdump分析过程 - folin的专栏 - CSDN博客
bios启动过程分析
Grub 命令以及启动详解 - clozxy的专栏 - CSDN博客
ubuntu无法启动 - mayqlzu的专栏 - CSDN博客
技术,谁来负责? - wmnothing的专栏 - CSDN博客
bbbbbbj的专栏 - CSDN博客
bios启动过程
vc程序调用别人的dll报错的原因分析 - cay22的专栏 - CSDN博客
kernel panic Call Tree 分析方法 - unbutun的专栏 - CSDN博客
2.4内核(arm版)Makefile分析 - turlim的专栏 - CSDN博客
vc++ - lonelytreebjfu的专栏 - CSDN博客
ASCII码表 - heruibin的专栏 - CSDN博客
tcp cwnd - linweixuan的专栏 - CSDN博客
RTMP是什么 - Thinkor2k8的专栏 - CSDN博客
手机知识 - whpeace的专栏 - CSDN博客
指针Guide - chinahai的专栏 - CSDN博客
数据库触发器 - chinayuan的专栏 - CSDN博客
中国式管理 - wmnothing的专栏 - CSDN博客
IE捉迷藏 - bluesqsr的专栏 - CSDN博客
多核系统中三种典型锁竞争的加速比分析 - 周伟明的多核、测试专栏 - CSDN博客
USB有关的编程 - sanshao27的专栏 - CSDN博客
一篇很实用的入门教程 - ph9527的专栏 - CSDN博客
软件开发的效率 - wmnothing的专栏 - CSDN博客