静下来,定好方向,好好干。
分类: LINUX
2007-11-15 17:17:16
elf->bin(image) amr-elf-objcopy
kernel+lib+rootfs
内核关键: mm, fs, driver, arch, net, ipc
uclinux2.4.18
du -sh 查看本地大小; find . -name *.c / wc -l
arm-elf-objcopy -O binary -R . note -R . comment -S linux image. ram
网络部分:
driver/net 硬件相关, 驱动
net 协议层相关
grub引导->内核启动
zcat/bzcat patch-2.4.19-rmk7. gz | patch -p1 -d linux-2.4.19
make menuconfig需要先安装ncurses-dev;
sudo route add default gw 192.168.0.1 增加默认网关
proc 内存文件系统, 读内核数据结构, 不存在磁盘上
ls -l /proc / cat /proc/interrupts 查看中断
romfs比较节省空间,/var/temp可写 buzybox小工具集
/etc/resolve.conf DNS设置
dir-->img->romfs.o->romfs.img---->romfsdir
linux2.4 + romfs.o ==>linux
SKYEYE: 1. target sim; 2. load; 3. b start_kernel or b *0x8000; 4. run
disassemble 0x8000 反汇编 si->step inside ir->info register
make dep->make lib_only->make user_only
arm-elf-gcc -o hello -elf2flt hello.c
sudo aptitude install vsftpd //anonymous /home/ftp //binary下载
开发板上eth0启用后, 可用ftp从主机下载执行程序. 下载后转换成执行模式; chmod 755 hello; 然后可以用;
mount -t romfs -o loop imges/romfs.img /tmp/
grep -nrs "r12" *
针对操作系统的可执行文件带格式; 针对CPU的可执行文件, 不带格式的;
elf2flt: elf, linux格式 flt, uclinux格式
romfs对于ext2: 索引区更小; 支持索引的代码区更小; 文件格式更省;
genromfs 把目录打包成romfs.img
dd if=/dev/zero of=test.img bs=512 count=524160
关于makefile:
unexport: 不输出标号
$(MAKE) all_targets
@ehco "starting. . ." 不显示命令
. depend filename 关于依赖的文件
@set -e: for i in $(SUBDIRS): do $(MAKE) -C $$i clean; done
>> 导出追加
启动文件: /etc/rc. local /ect/rcS romfs: /etc/rc启动脚本
若更改了romfs的内容, 则不能再make romfs, 否则内容被复原;
bootloader:
编写startup.s main.c c_entry等代码:
地址设为0x0, 0x4000
make生成axf文件, 再生成bin文件;
用sjf4510烧写flash;
windows+ads调试:
1. Ads创建project, 编写代码, addfiles加入project;
2. compile/make;
3. Banyan启动, 连接好JTAG+并口延长线;
4. 启动AXD后, 设option->Target, 选banyan;
5. load image, 调入Axf;
6. Go or step, 开始调试, reload image, 重新开始;
7. 用串口19200开始接受信息;
linux+minicom+tftp+vsftp
1. 板子bootloader上有tftpserver, 用minicom启动load或ap(带烧写);;;;;;;;;
2. PC上用tftp/binary传如image.rom给板子;
3. 选择Y, 运行;
bootloader+uclinux+app:
1. 将程序的读写目标文件放在var/tmp目录下;
2. chmod 777 var/tmp
server.c移植到uClinux的变化0920:
1. 改变makefile的编译器;
2. 去除文件的assert语句, 把类型定义放在函数开头;
3. 改var/tmp->777变成可读写;
4. 首先ftp下载运行, 再考虑烧写进flash; 注意, 程序中文件读写路径要改到var/tmp下;
5. 加上连接, 聊天亮灯程序;
6. 去除聊天记录;
makefile + -lpthread;
client变化: 登录给出默认值, 因为无法输入;
源程序改动, 需要执行以下操作:
make user_only /make romfs /rc更改 /make image /make linux
inode节点约为64字节, 索引/数据, 一个块可能包含若干inode, 数据区, 文件分块存, 每个块不能存2个文件;
超级块1024字节, 保存一些全局性信息;
硬连接, 指向同一个inode, 只是link_count + 1;
innode索引表+数据块bitmap+inode号bitmap+superblock全局信息;
开发板上运行httpd, PC上IE访问192.168.168.101;
============================================================
程序员看到的地址都是虚地址;
从原理图看地址空间;
CPU端一个地址一个字节, 如果存储器是8bit, 那么cpu的地址线与SRAM, 从A[15:0]<=>A[15:0]一一连接;
若SRAM是16bit, 则A[16:1]<=>A[15:0]一一连接;
数据宽度的设置要根据芯片的数据宽度来设置;
VA->PA的最小转换单位是4K=0x1000;
page directory( 1k) -> page table( 1k) -> page( 4k);
IO空间不能缓存; Volatile关键字, 指它的存储空间的数据不仅仅由程序决定, 可能被外界改变, 比如串口寄存器等, 编译器不会自动优化; 多线程的公共变量也可考虑volatile修饰;
寄存器映射空间( no cache);
mmu的功能: 地址转换, 权限检查;
mrc, mcr 操作CP15协处理器;
arm7是 冯诺依曼 体系, 指令与数据统一编址;
arm9是哈佛体系, 指令与数据独立编址;
C13=0, VA=MVA, MVA->Fast Context Switch ???
一级, 二级页面描述符, Page Descriptor
表项应存在mmu缓存里???
Domain是一组页表和页面的集合, 16个Domain; 1个domain就是一个权限检查单位;
linux Domain一般设为01, 再检查AP位;
交叉编译器, 注意版本匹配问题;
lib是用户层, 通过系统调用来进入内核态;
交叉编译器+lib+app;
kernel的入口是__init_begin;
kernel的主框架在main. c;
readelf -h vmlinux
nm vmlinux | grep "8000"
grep -nrs "^__init_begin" *
kernel/setup.c
sql语句/SQLITE内建命令>. help
回调函数是每条记录调一次;
DDL: database define language DML: database modify language
create drop select delete insert update
update employee set age=25 where name='dq';
delete from employee where name='zc';
insert into example value('zhang', 80);
select * from student order by scorea+scoreb desc/asc
thttpd-2.25 轻量级的web服务器 . /configure->sudo addgroup "www"->make->make install
libcgi-1.0.tar.gz CGI函数库 既要主机编译, 又要交叉编译 . /configure->make->make install
界面框架
ps -aux | grep 'thttpd'
libcgi.so 拷贝到 /usr/lib下, cgi即可使用
sudo mkdir /srv/www->chown user:user
sudo . /httpd -c thttpd. conf 以指定配置文件运行服务器
编译时带上-lcgi -lsqlite3
. + 空 + 文件名: 把文件的命令一条条执行, 在当前shell;
qtopia移植:
*. so文件的应用:
编译时: 查找-L指定的路径; 默认的查找路径;gcc --help->gcc --print-search-dir
运行时: 指定环境变量 LD_LIBRARY_PATH, EXPORT LD_LIBARARY_PATH=dir;
或零时LD_LIBRARY_PATH=dir . /demo
将程序添加到/etc/ldso. conf 然后执行ldconfig /lib/ld_2.5.so动态连接器
默认路径 /lib或/usr/lib
实用命令:
sudo fdisk -l
Alt+f2: update -manage -d 升级UBUNTU
/etc/default/rcS
/etc/ini.d/shell脚本
/etc/fstab配置硬盘启动脚本 末行+/dev/hdb4 /mnt ext2 defaults 0 0
mount可查看已挂载的分区
cp -a -d -f -R ???
sudo aptitude install zbliblg-dev???
sudo dpkg -reconfigure xserver-xorg
install mplayer->kmplayer->w32codecs
ADDRESS TRANSLATION:
DIRECTORY(31~22,10BIT)
TABLE(21~12,10BIT)
OFFSET(11~0,12BIT)
CP15 Coprocessor,有以下功能单元:
MMU内存管理单元,Cache缓存控制,WriteBuffer写缓冲控制,FastContextSwitch快速进程切换
CP15有16个Registers,指令格式为:
MCR/MRC{cond} P15,opcode_1,Rd,CRn,CRm,opcode_2;
如: mcr P15, 0, r0, c7, c7
TTB,Translation Table Base;
TLB,用于缓存VA-PA映射项,不仅保存物理地址,还保存着C, B位和权限位;
B位,写缓冲使能位;
C位,确定该物理内存页是否允许CACHE;
若C位有效,则用VA到Cache中以Cache Line(32bytes)为单位读取数据, 若Cache Hit,直接读取即可;
Fast Context Switch适用于0~32M以内的小型操作系统;???
Address Translation,每个表项4字节,32bit,所以页表占有内存要用//表项*4\\得出:
TTB Base->
/一级页表Section Base(4096表项*1M)
/粗页表Coarse Page Table Base(4096表项*256表项*[4k,64K])
/细页表Fine Page Table Base(4096表项*1K表项*[1K,4K,64K])
->sections(1M)/Large Page(64K)/Small Page(4K)/Tiny Page(1K)
段sections,[19:0]=1M
大页large pages,[15:0]=64K
小页small pages,[11:0]=4K
微小页tiny pages,[9:0]=1K
域domain的概念是一组有着相同的访问权限的段和页,这样可以不同的进程用一个特定的转换表,不同的程序之间又可以保护;
第一级页描述符:
最后2位是标识(00/FAULT/ 01/Coarse page table/ 10/Section/ 11/Fine page table/)表项性质;
4bit的domain标识;
段基址[31:20]/粗页表基址[31:10]/细页表基址[31:12]
段页表还有2bit的AP位,C,B位;
第二级页描述符:
最后2位是标识(00/FAULT/ 01/large page/ 10/small page/ 11/tiny page/)表项性质;
大页基址[31:16]/小页基址[31:12]/微小页基址[31:10]
还有4*2bit的AP位(tiny page是1*2bit的ap位),C,B位;
CR3是DOMAIN ACCESS CONTROL REGISTER,定义16个域的权限属性:
00/NO ACCESS
01/CLIENT,要check页描述符中的ap位来决定是不是能够访问;
10/RESERVED=NO ACCESS
11/MANAGER,不必检查AP位,完全可访问;
AP位与CR1中的S,R位合起来决定访问权限;
CR5,FAULT STATUS REGISTER,存放错误原因;
CR6,FAULT ADDRESS REGISTER,存放错误发生的数据地址;
FAULT CHECKING:
Alignment Fault: 数据访问所访问的地址未对齐;
Translation Fault: Page Descriptor的[1:0]为00(Fault);
Domain Fault: 相应的Domain位是00(no access)或10(reserved);
Permission Fault: 根据AP位和CR1的S,R位决定的访问权限禁止的访问;若Domain为11(manager)则跳过该权限检查;
External Abort: 总线异常,如此物理地址上无RAM芯片;
前面描述了VA->PA的一些寄存器,接下来是关于CACHE LINE的知识:
DIRECT MAPPED CACHE直接映射CACHE,是512条32byte的CACHE LINE,每16K就循环一周;
优点是查找快,缺点是相差16K的地址不能同时保存;
查找方法:根据VA[13:5]确定在那一条CACHE LINE,然后比较其TAG与VA[31:14]是否对应,若CACHE HIT,即可读取一条32bytes,VA[4:0]是偏移量;
格式:TAG(18bits)VA[31:14]///DATA(32bytes)VA[4:0]///
FULL ASSOCIATIVE CACHE全映射CACHE,是512条32byte的CACHE LINE,任意放置数据;
优点是任意地址都可同时保存,缺点是因为数据不是有序等间隔放置,所以需要一一比较,查找较慢;
查找方法:对512条CACHE LINE的TAG与VA[31:5]进行逐一比较,相等则CACHE HIT;
格式:TAG(27bits)VA[31:5]///DATA(32bytes)VA[4:0]///
64-WAY SET ASSOCIATIVE CACHE是64路组相连CACHE,是512条32byte的CACHE LINE,根据VA[7:5]分成8组,每组64条CACHE LINE;
优点是坚固前两种的优点,首先分8组可缩小查找范围,而且同一小组有64条可无序存放的空间,减小了同一小组冲突的可能;
查找方法:根据VA[7:5]确定在那一组,然后将该组里TAG与VA[31:8]逐一比较,相等则CACHE HIT;
格式:TAG(24bits)VA[31:8]///DATA(32bytes)VA[4:0]///
Write Back Cache: cache中的数据发生更改是并不立刻写回RAM,而是标记Dirty位,
当该Cache Line要被其他地址数据fill时候才Write Back到RAM;
Write Through Cache: 每当Cache中的数据发生更改就立刻写回RAM,Cache只是起到加速读取的作用;
Clean操作:将Cache中的数据写回RAM,清除Dirty位;
Invalidate操作:声明Cache中的数据无效,强制重新从RAM读取;
8组VA[7:5]*64行PA TAG格式: TAG(24BIT)VA[31:8]///DATA(32BYTES)VA[4:0]///PA TAG(27BITS)PA[31:5]///
Write Buffer,适用于不起用Cache的情况,CPU不必等待数据写入RAM就可以继续执行后面的指令;
CB,behavior
00,non-cached,non-buffered(NCNB)
01,non-cached buffered(NCB)
10,cached,write-through mode(WT)
11,cached,write-back mode(WB)
几点前提:
TTB就是0x0800 4000,用段地址的话,VA[31:20],也就是前12bits,就是偏移量;
内核代码加载地址是0xc000 8000(VA);
r4 = 0x0800 4000页表的起始地址
r5 = 0x0800 0000是RAM起始物理地址
r8 = 0x0000 0cle
代码:
首先清零0x0800 4000开始的16KB(=0x4000)的空间准备页表存放;
若0x8000 0000要映射到物理地址0x8000 0000上,应该如此设置:
add r3, r8, r5
add r0, r4, r5, lsr #18
str r3, [r0]
0x0800 4200地址的内容为0x0800 0cle
;若0xc000 0000要映射到物理地址0x8000 0000上,应该如此设置:
add r0, r4, #(0xc000 0000 & 0xfff0 0000) >> 18
; r0 = r4 + 0x3000 = 0x0800 7000
str r3, [r0], #4
;0x0800 7000地址的内容为0x0800 0cle
;若0xc000 0000要映射到物理地址0x8000 0000上,应该如此设置:
add r3, r3, #1 << 20
;r3 = 0x0810 0cle
str r3, [r0], #4
;0x0800 7004地址的内容为0x0810 0cle
设置好页表,再设置与MMU和CACHE有关的CP15寄存器;
最后用一条指令启用MMU:
MCR P15, 0, R0, C1, C0
=====================================================
MC2410E开发板实验:
安装交叉编译工具链:
sudo tar zxvf arm-linux-tools-20061213.tar.gz -C /
编译内核:
将内核释放到~/linux-2.6.17.14:
tar zxvf linux-2.6.17.14-aaa.tar.gz -C ~
cd ~/linux-2.6.17.14
make menuconfig
make
编译好的内核位于~/linux-2.6.17.14/arch/arm/boot/zImage
下载内核和根文件系统到开发板:
显示bootloader的参数: vivi> para show
设置IP的参数: vivi> para set ip "192.168.1.25"
设置HOST的参数: vivi> para set host "192.168.1.125"
设置GW的参数: vivi> para set gw "192.168.1.125"
保存参数设置: vivi> para save
删除分区: vivi> part del root
添加分区: vivi> part add root 0x00200000 0x03e00000 0
root: offset = 0x00200000, size = 0x03e00000, flag = 0;
执行命令,等待主机发送kernel: vivi> load flash kernel t
主机上执行命令: $ atftp -l ~/linux-2.6.17.14/arch/arm/boot/zImage -p 192.168.1.25(开发板IP)
执行命令,等待主机发送rootfs: vivi> load flash root t
主机上执行命令: $ atftp -l rootfs-basic.cramfs -p 192.168.1.25(开发板IP)
设置启动参数: vivi> para set linux_cmd_line "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"
启动linux: vivi> boot
接下来输入用户名密码登陆;
主机可以SSH登陆开发板: $ ssh
根文件系统制作:
解压基本根文件系统: $ tar -xvf rootfs-basic.tar -C ~
安装cramfs制作工具: $ sudo aptitude install cramfsprogs
制作文件系统映象: $ mkcramfs ~/rootfs rootfs.cramfs
设置开发板的启动方式NFS ROOT:
在主机上开启NFS服务器,把~/rootfs目录导出为NFS服务目录,使开发板一启动就自动加载主机的~/rootfs目录为根文件系统;便于开发;
主机上安装NFS服务器: $ sudo aptitude install nfs-kernel-server
修改配置文件: $ sudo vi /etc/exports,添加一行:/home/username/rootfs *(rw,sync,no_root_squash)
重新启动NFS服务: $ sudo /etc/init.d/nfs-kernel-server restart
修改开发板启动参数:
vivi> para set linux_cmd_line "noinitrd root=/dev/nfs rw ip=192.168.1.25:192.168.1.125::255.255.255.0:::off nfsroot=/home/username/rootfs init=/linuxrc console=ttySAC0"
配置YAFFS文件系统:
cramfs是只读文件系统,在flash上压缩存储,解压并加载到RAM运行.
jffs和yaffs是可读写的文件系统;yaffs文件系统与ext2不同,不需要格式化,只需要全部擦除并mount上来就可以了;
flash_eraseall不是busybox中的命令,而是从mtd的源代码()中交叉编译得来的;
首先,用NFS启动系统;
开发板上:
flash_eraseall /dev/mtd3
mount -t yaffs /dev/mtdblock3 /mnt
ls /mnt (lost+found)
现在把根文件系统中的所有文件拷贝到flash分区:
开发板上:
cp -a bin etc lib linuxrc opt sbin srv tmp usr var /mnt/
mkdir /mnt/proc /mnt/sys /mnt/dev /mnt/mnt
mknod /mnt/dev/console -m 600 c 5 1
umount mnt (此时已经把根文件系统写入到mtdblock3)
reboot
重启目标系统后进入vivi,修改启动参数从root分区启动:
vivi> para set linux_cmd_line "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"
vivi> boot
===================================================
sqlite的发展:2000年由D.Richard Hipp开始开发;2001年发布2.0V,2004发布3.0V;
优点是内存占用小;比mysql快;ACID兼容,支持视图,子查询,触发器;单个库文件,不依赖其他库;C/C++,Perl,PHP等应用提供接口;免费;
缺点是并发性不好;用户管理/安全,不能通过数据库本身对权限进行设置;
$ sqlite3 test.db
sqlite> create table employee(id integer primary key, name text, gender text, age integer );
sqlite> .import data.txt employee
sqlite> select * from employee where id > 2;
sqlite的安装:
可以用aptitude安装libsqlite3-0,libsqlite3-dev,sqlite3,sqilte3-doc软件包;
用源码包编译并安装:
$ tar -zxvf sqlite-3.4.0.tar.gz -C ~
$ mkdir ~/host-build
$ cd ~/host-build
$ ../sqlite-3.4.0/configure
$ make
$ sudo make install
编译生成的libsqlite3.so.0.8.6放在/usr/local/lib下,
将编译生成的sqlite3工具程序放在/usr/local/bin下,
将sqlite3.h放在/usr/local/include下;
$ vi hello.c
$ gcc -o hello hello.c -L/usr/local/lib -lsqlite3 -I/usr/local/include
交叉编译sqlite(编译在目标板上运行的程序):
$ mkdir ~/target-build
$ cd ~/target-build
$ ../sqlite-3.4.0/configure --host=arm-linux
$ make
生成的sqlite共享库在target-build/.libs目录中,手动拷贝到根文件系统:
$ cp -d ~/target-build/.libs/libsqlite3.so* ~/rootfs/usr/lib
交叉编译hello.c
$ arm-linux-gcc -o hello hello.c -L/home/username/rootfs/usr/lib -lsqlite3 -I/usr/local/include
$ arm-linux-strip hello
将hello和test.db数据库拷贝到根文件系统中,在开发板上运行即可;
===========================================================================
Qtopia Core交叉编译:
下载qtopia core的源代码qtopia-core-opensource-src-4.2.2.tar.gz并解包;
使用qtopia core的许多组件(比如:xxx)的配置都有三种选择:
使用qtopia自带的库支持,配置-qt-libxxx
使用系统的共享库,配置-system-libxxx
不支持该组件,配置-no-libxxx
编译qt源代码:
$ ./configure -embedded arm -DQT_QLOCALE_USES_FCVT -qt-mouse-pc -no-freetype -no-cups -no-nis -no-iconv -no-qdbus -no-libjpeg -no-libpng -no-gif -no-zlib -no-rpath -no-qt3support -no-largefile -no-accessibility -no-stl -no-libmng -little-endian -prefix /opt/QtPalmtop -system-sqlite
make
sudo make install
安装到主机/opt/QtPalmtop目录下;
从中挑选有用的文件拷贝到开发板的根文件系统:
$ mkdir -p ~/rootfs/opt/QtPalmtop/lib/fonts
$ cp -dp /opt/QtPalmtop/lib/* ~/rootfs/opt/QtPalmtop/lib
$ cp /opt/QtPalmtop/lib/fonts/fontdir ~/rootfs/opt/QtPalmtop/lib/fonts
$ cp /opt/QtPalmtop/lib/fonts/wenquanyi_120_50.qpf ~/rootfs/opt/QtPalmtop/lib/fonts
$ cp -a /opt/QtPalmtop/plugins ~/rootfs/opt/QtPalmtop
字体拷贝了一种,中文的文泉驿字体的qpf格式,轻量级不可缩放字体;
由于设置了-system-sqlite,在plugin/sqldrivers目录下有个libqsqlite.so,这个文件较小,只是系统sqlite库的一个外壳而不是完整库.
把一个Qt工程目录拷贝到qtopia core的源码目录中(必须已经做过交叉编译):
$ cp -a hello ~/qtopia-core-opensource-src-4.2.2
$ cd ~/qtopia-core-opensource-src-4.2.2/hello
$ qmake
$ make
将交叉编译生成的程序hello拷贝到根文件系统;
开发板:
启动开发板系统,更新ld.so:
确保开发板上/etc/ld.so.conf文件中有/opt/QtPalmtop/lib路径,然后执行ldconfig;
然后就可以测试运行hello:
./hello -qws
qws表示启动类似于x windws服务;若再运行其他qtopia程序就不需要qws选项了;
一些例程:
/*student.c*/
#include
#include
#include
#include
static count;
static int rscallback(void *p, int argc, char **argv, char **argvv)
{
int i;
int sum;
printf ("%d\t", ++count);
for (i = 0; i < argc; i++)
{
printf("%s\t", argv[i] ? argv[i] : "NULL");
}
sum = atoi(argv[2]) + atoi(argv[3]) + atoi(argv[4]);
printf ("%d\n", sum);
return 0;
}
int main(void)
{
sqlite3 *db;
char *err = 0;
char sc;
char name[10];
char upname[10];
char gender[10];
char sqlstr[100];
char c_scorea[10];
char c_scoreb[10];
char c_scorec[10];
int scorea, scoreb, scorec;
int ret = 0;
ret = sqlite3_open("./test.db", &db);
if(ret == SQLITE_OK)
{
printf("open success\n");
ret = sqlite3_exec(db, "create table student(name text primary key, gender text, scorea integer, scoreb integer, scorec integer);", rscallback, 0, &err);
}
else
{
sqlite3_close(db);
exit(1);
}
while(1)
{
/*start to get the order*/
printf ("----------------\n");
printf ("1. Insert Record\n");
printf ("2. Delete Record\n");
printf ("3. Update Record\n");
printf ("4. Sort\n");
printf ("Please Select [1-4]: ");
do
{
scanf ("%c", &sc);
}while(sc == '\n' || sc == ' ');
switch(sc)
{
case '1':
/*action to the order*/
printf ("Now Inserting Record...\n");
printf ("Input Name: ");
scanf ("%s", name);
printf ("Input Gender: ");
scanf ("%s", gender);
printf ("Input ScoreA: ");
scanf ("%s", c_scorea);
printf ("Input ScoreB: ");
scanf ("%s", c_scoreb);
printf ("Input ScoreC: ");
scanf ("%s", c_scorec);
strcpy(sqlstr, "insert into student values('");
strcat(sqlstr, name);
strcat(sqlstr, "','");
strcat(sqlstr, gender);
strcat(sqlstr, "',");
strcat(sqlstr, c_scorea);
strcat(sqlstr, ",");
strcat(sqlstr, c_scoreb);
strcat(sqlstr, ",");
strcat(sqlstr, c_scorec);
strcat(sqlstr, ");");
//printf ("sql = %s\n", sqlstr);
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
printf("Record Inserted\n");
}
else
printf("Record Insert ERR\n");
/*action over*/
break;
case '2':
/*action to the order*/
printf ("Now Delete Record...\n");
printf ("Input Name: ");
scanf ("%s", name);
strcpy(sqlstr, "select * from student where name='");
strcat(sqlstr, name);
strcat(sqlstr, "';");
//printf ("%s\n",sqlstr);
count = 0;
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
//printf ("count = %d\n", count);
if (count > 0)
{
strcpy(sqlstr, "delete from student where name='");
strcat(sqlstr, name);
strcat(sqlstr, "';");
//printf ("sql = %s\n", sqlstr);
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
printf("Record Deleted\n");
}
else
printf("Record Delete ERR\n");
/*action over*/
}
else
printf("No Such Record\n");
}
else
printf("Record Search ERR\n");
/*action over*/
break;
case '3':
/*action to the order*/
printf ("Now Update Record...\n");
printf ("Input Name: ");
scanf ("%s", upname);
strcpy(sqlstr, "select * from student where name='");
strcat(sqlstr, upname);
strcat(sqlstr, "';");
//printf ("%s\n",sqlstr);
count = 0;
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
//printf ("count = %d\n", count);
if (count > 0)
{
printf ("Input Name: ");
scanf ("%s", name);
printf ("Input Gender: ");
scanf ("%s", gender);
printf ("Input ScoreA: ");
scanf ("%s", c_scorea);
printf ("Input ScoreB: ");
scanf ("%s", c_scoreb);
printf ("Input ScoreC: ");
scanf ("%s", c_scorec);
strcpy(sqlstr, "update student set name='");
strcat(sqlstr, name);
strcat(sqlstr, "',gender='");
strcat(sqlstr, gender);
strcat(sqlstr, "',scorea=");
strcat(sqlstr, c_scorea);
strcat(sqlstr, ",scoreb=");
strcat(sqlstr, c_scoreb);
strcat(sqlstr, ",scorec=");
strcat(sqlstr, c_scorec);
strcat(sqlstr, " where name='");
strcat(sqlstr, upname);
strcat(sqlstr, "';");
//printf ("sql = %s\n", sqlstr);
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
printf("Record Updated\n");
}
else
printf("Record Update ERR\n");
/*action over*/
}
else
printf("No Such Record\n");
}
else
printf("Record Search ERR\n");
/*action over*/
break;
case '4':
/*action to the order*/
printf ("Now Sort Record...\n");
count = 0;
printf ("NO.\tName\tGender\tScoreA\tScoreB\tScoreC\tSum\n");
printf ("=====================================================\n");
ret = sqlite3_exec(db, "select * from student order by scorea+scoreb+scorec desc;", rscallback, 0, &err);
if(ret == SQLITE_OK)
{
printf("Record Sorted\n");
}
else
printf("Record Sort ERR\n");
/*action over*/
break;
default:
printf("Please input a num between 1~4!\n");
break;
};
}
sqlite3_close(db);
return 0;
}
CGI编程:
#makefile
CC = gcc
all : sort.cgi update.cgi delete.cgi insert.cgi
sort.cgi : sort.c
$(CC) -o $@ $^ -L/usr/local/lib -lsqlite3 -lcgi -I/usr/local/include
update.cgi : update.c
$(CC) -o $@ $^ -L/usr/local/lib -lsqlite3 -lcgi -I/usr/local/include
delete.cgi : delete.c
$(CC) -o $@ $^ -L/usr/local/lib -lsqlite3 -lcgi -I/usr/local/include
insert.cgi : insert.c
$(CC) -o $@ $^ -L/usr/local/lib -lsqlite3 -lcgi -I/usr/local/include
/*update.c*/
#include
#include
#include
#include
#include "cgi.h"
static count;
static int rscallback(void *p, int argc, char **argv, char **argvv)
{
int i;
int sum;
++count;
return 0;
}
int main(void)
{
sqlite3 *db;
char *err = 0;
char sc;
char name[10];
char gender[10];
char sqlstr[100];
char c_scorea[10];
char c_scoreb[10];
char c_scorec[10];
int scorea, scoreb, scorec;
int ret = 0;
ret = sqlite3_open("./test.db", &db);
if(ret == SQLITE_OK)
{
// printf("open success\n");
ret = sqlite3_exec(db, "create table student(name text primary key, gender text, scorea integer, scoreb integer, scorec integer);", rscallback, 0, &err);
}
else
{
sqlite3_close(db);
exit(1);
}
cgi_init();
cgi_process_form();
cgi_init_headers();
puts(""
""
""
""
" "
" "
" "
" "
"
" "
" "
"");
/***************************************************************/
/* // NAME
if (cgi_param("name"))
printf("Name: %s
", cgi_param("name"));
else
puts("Name: Empty
");
*/
/*action to the order*/
strcpy(sqlstr, "select * from student where name='");
strcat(sqlstr, cgi_param("NameToUpdate"));
strcat(sqlstr, "';");
//printf ("%s\n",sqlstr);
count = 0;
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
//printf ("count = %d\n", count);
if (count > 0)
{
strcpy(sqlstr, "update student set name='");
strcat(sqlstr, cgi_param("Name"));
strcat(sqlstr, "',gender='");
strcat(sqlstr, cgi_param("Gender"));
strcat(sqlstr, "',scorea=");
strcat(sqlstr, cgi_param("ScoreA"));
strcat(sqlstr, ",scoreb=");
strcat(sqlstr, cgi_param("ScoreB"));
strcat(sqlstr, ",scorec=");
strcat(sqlstr, cgi_param("ScoreC"));
strcat(sqlstr, " where name='");
strcat(sqlstr, cgi_param("NameToUpdate"));
strcat(sqlstr, "';");
//printf ("sql = %s\r\n", sqlstr);
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
printf("Record Updated\n");
}
else
printf("Record Update ERR\n");
/*action over*/
}
else
printf("No Such Record\n");
}
else
printf("Record Search ERR\n");
/*action over*/
puts(""
"
"
""
"");
cgi_end();
/*****************************************************************/
sqlite3_close(db);
return 0;
}
/*sort.c*/
#include
#include
#include
#include
#include "cgi.h"
static count;
static int rscallback(void *p, int argc, char **argv, char **argvv)
{
int i;
int sum;
printf (" \r\n", sum);%d ", ++count);
for (i = 0; i < argc; i++)
{
printf("%s ", argv[i] ? argv[i] : "NULL");
}
sum = atoi(argv[2]) + atoi(argv[3]) + atoi(argv[4]);
printf ("%d
return 0;
}
int main(void)
{
sqlite3 *db;
char *err = 0;
char sc;
char name[10];
char gender[10];
char sqlstr[100];
char c_scorea[10];
char c_scoreb[10];
char c_scorec[10];
int scorea, scoreb, scorec;
int ret = 0;
ret = sqlite3_open("./test.db", &db);
if(ret == SQLITE_OK)
{
//printf("open success\n");
ret = sqlite3_exec(db, "create table student(name text primary key, gender text, scorea integer, scoreb integer, scorec integer);", rscallback, 0, &err);
}
else
{
sqlite3_close(db);
exit(1);
}
cgi_init();
cgi_process_form();
cgi_init_headers();
puts(""
""
""
""
" "
" "
" "
" "
"
" "
" "
"");
/***************************************************************/
/* // NAME
if (cgi_param("name"))
printf("Name: %s
", cgi_param("name"));
else
puts("Name: Empty
");
*/
/*action to the order*/
printf ("Now Sort Record...
\r\n");
count = 0;
puts("");
");
puts(" ");NO. Name Gender ScoreA ScoreB ScoreC Sum
ret = sqlite3_exec(db, "select * from student order by scorea+scoreb+scorec desc;", rscallback, 0, &err);
puts("
if(ret == SQLITE_OK)
{
printf("Record Sorted\r\n");
}
else
printf("Record Sort ERR\r\n");
/*action over*/
puts(""
""
""
"");
cgi_end();
/*****************************************************************/
sqlite3_close(db);
return 0;
}
/*insert.c*/
#include
#include
#include
#include
#include "cgi.h"
static count;
static int rscallback(void *p, int argc, char **argv, char **argvv)
{
int i;
int sum;
++count;
return 0;
}
int main(void)
{
sqlite3 *db;
char *err = 0;
char sc;
char name[10];
char gender[10];
char sqlstr[100];
char c_scorea[10];
char c_scoreb[10];
char c_scorec[10];
int scorea, scoreb, scorec;
int ret = 0;
ret = sqlite3_open("./test.db", &db);
if(ret == SQLITE_OK)
{
//printf("open success\n");
ret = sqlite3_exec(db, "create table student(name text primary key, gender text, scorea integer, scoreb integer, scorec integer);", rscallback, 0, &err);
}
else
{
sqlite3_close(db);
exit(1);
}
cgi_init();
cgi_process_form();
cgi_init_headers();
puts(""
""
""
""
" "
" "
" "
" "
"
" "
" "
"");
/***************************************************************/
/* // NAME
if (cgi_param("name"))
printf("Name: %s
", cgi_param("name"));
else
puts("Name: Empty
");
*/
/*action to the order*/
strcpy(sqlstr, "insert into student values('");
strcat(sqlstr, cgi_param("Name"));
strcat(sqlstr, "','");
strcat(sqlstr, cgi_param("Gender"));
strcat(sqlstr, "',");
strcat(sqlstr, cgi_param("ScoreA"));
strcat(sqlstr, ",");
strcat(sqlstr, cgi_param("ScoreB"));
strcat(sqlstr, ",");
strcat(sqlstr, cgi_param("ScoreC"));
strcat(sqlstr, ");");
//printf ("sql = %s\n", sqlstr);
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
printf("Record Inserted\n");
}
else
printf("Record Insert ERR\n");
/*action over*/
puts(""
""
""
"");
cgi_end();
/*****************************************************************/
sqlite3_close(db);
return 0;
}
/*delete.c*/
#include
#include
#include
#include
#include "cgi.h"
static count;
static int rscallback(void *p, int argc, char **argv, char **argvv)
{
int i;
int sum;
++count;
return 0;
}
int main(void)
{
sqlite3 *db;
char *err = 0;
char sc;
char name[10];
char gender[10];
char sqlstr[100];
char c_scorea[10];
char c_scoreb[10];
char c_scorec[10];
int scorea, scoreb, scorec;
int ret = 0;
ret = sqlite3_open("./test.db", &db);
if(ret == SQLITE_OK)
{
//printf("open success\n");
ret = sqlite3_exec(db, "create table student(name text primary key, gender text, scorea integer, scoreb integer, scorec integer);", rscallback, 0, &err);
}
else
{
sqlite3_close(db);
exit(1);
}
cgi_init();
cgi_process_form();
cgi_init_headers();
puts(""
""
""
""
" "
" "
" "
" "
"
" "
" "
"");
/***************************************************************/
/* // NAME
if (cgi_param("name"))
printf("Name: %s
", cgi_param("name"));
else
puts("Name: Empty
");
*/
/*action to the order*/
strcpy(sqlstr, "select * from student where name='");
strcat(sqlstr, cgi_param("Name"));
strcat(sqlstr, "';");
//printf ("%s\n",sqlstr);
count = 0;
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
//printf ("count = %d\n", count);
if (count > 0)
{
strcpy(sqlstr, "delete from student where name='");
strcat(sqlstr, cgi_param("Name"));
strcat(sqlstr, "';");
//printf ("sql = %s\n", sqlstr);
ret = sqlite3_exec(db, sqlstr, rscallback, 0, &err);
if(ret == SQLITE_OK)
{
printf("Record Deleted\n");
}
else
printf("Record Delete ERR\n");
/*action over*/
}
else
printf("No Such Record\n");
}
else
printf("Record Search ERR\n");
/*action over*/
puts(""
""
""
"");
cgi_end();
/*****************************************************************/
sqlite3_close(db);
return 0;
}