busybox作用(busybox使用教程)

http://www.itjxue.com  2023-02-08 22:29  来源:未知  点击次数: 

ubuntu 12.0.4编译busybox出错,求解答

#我解压tarball后,在目录下建立了build文件夹,我在build目录里开始编译。

make KBUILD_SRC=../ -f ../Makefile defconfig

sed -e 's/.*FEATURE_PREFER_APPLETS.*/CONFIG_FEATURE_PREFER_APPLETS=y/' -i .config

sed -e 's/.*FEATURE_SH_STANDALONE.*/CONFIG_FEATURE_SH_STANDALONE=y/' -i .config

make

make install #我没有执行这个安装命令,因为我不需要这个软件。

#检测一下编译好的busybox

PATH= ./busybox ash #这条命令的作用是清空PATH系统环境变量,防止执行系统目录(/bin /usr/bin等)下的可执行文件 如 ls rm等。

这样,下面的ls命令,是来自busybox 的 ash shell,而非来自系统的bash shell。

/busybox/busybox-1.21.1/build $ ls

Makefile busybox_unstripped.out editors

applets console-tools findutils

archival coreutils include

busybox debianutils include2

busybox_unstripped docs init

busybox_unstripped.map e2fsprogs libbb

make过程的部分屏幕输出:

CC networking/ifplugd.o

CC networking/ifupdown.o

CC networking/inetd.o #编译 networking/inetd.o 可以正常通过

CC networking/interface.o

......

CC util-linux/volume_id/sysv.o

CC util-linux/volume_id/udf.o

CC util-linux/volume_id/util.o

CC util-linux/volume_id/volume_id.o

CC util-linux/volume_id/xfs.o

AR util-linux/volume_id/lib.a

LINK busybox_unstripped

Trying libraries: crypt m

Library crypt is not needed, excluding it

Library m is needed, can't exclude it (yet)

Final link with: m

DOC busybox.pod

DOC BusyBox.txt

DOC busybox.1

DOC BusyBox.html

你的问题是找不到头文件,那首先,你检查一下 gcc 的默认头文件搜索目录

echo "" | gcc - -xc -v -E

看输出是否包含/usr/include

#include ... 搜索从这里开始:

/usr/lib/gcc/i686-linux-gnu/4.6/include

/usr/local/include

/usr/lib/gcc/i686-linux-gnu/4.6/include-fixed

/usr/include/i386-linux-gnu

/usr/include

根据结果再做下一步判断。

字符型设备驱动如何编译

字符设备驱动程序框架

1、写出open、write函数

2、告诉内核

1)、定义一个struct file_operations结构并填充好

static struct file_operations first_drv_fops = {

.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

.open = first_drv_open,

.write = first_drv_write,

};

2)、把struct file_operations结构体告诉内核

major = register_chrdev(0, "first_drv", first_drv_fops); // 注册, 告诉内核

相关参数:第一个,设备号,0自动分配主设备号,否则为主设备号0-255

第二个:设备名

第二个:struct file_operations结构体

4)、register_chrdev由谁调用(入口函数调用)

static int first_drv_init(void)

5)、入口函数须使用内核宏来修饰

module_init(first_drv_init);

module_init会定义一个结构体,这个结构体里面有一个函数指针指向first_drv_init这个函数,当我们加载或安装一个驱动时,内核会自动找到这个结构体,然后调用里面的函数指针,这个函数指针指向first_drv_init这个函数,first_drv_init这个函数就是把struct file_operations结构体告诉内核

6)、有入口函数就有出口函数

module_exit(first_drv_exit);

最后加上协议

MODULE_LICENSE("GPL");

3、mdev根据系统信息自动创建设备节点:

每次写驱动都要手动创建设备文件过于麻烦,使用设备管理文件系统则方便很多。在2.6的内核以前一直使用的是devfs,但是它存在许多缺陷。它创建了大量的设备文件,其实这些设备更本不存在。而且设备与设备文件的映射具有不确定性,比如U盘即可能对应sda,又可能对应sdb。没有足够的主/辅设备号。2.6之后的内核引入了sysfs文件系统,它挂载在/sys上,配合udev使用,可以很好的完成devfs的功能,并弥补了那些缺点。(这里说一下,当今内核已经使用netlink了)。

udev是用户空间的一个应用程序,在嵌入式中用的是mdev,mdev在busybox中。mdev是udev的精简版。

首先在busybox中添加支持mdev的选项:

Linux System Utilities ---

[*] mdev

[*] Support /etc/mdev.conf

[*] Support subdirs/symlinks

[*] Support regular expressions substitutions when renaming device

[*] Support command execution at device addition/removal

然后修改/etc/init.d/rcS:

echo /sbin/mdev /proc/sys/kernel/hotplug

/sbin/mdev -s

执行mdev -s :以‘-s’为参数调用位于 /sbin目录写的mdev(其实是个链接,作用是传递参数给/bin目录下的busybox程序并调用它),mdev扫描 /sys/class 和 /sys/block 中所有的类设备目录,如果在目录中含有名为“dev”的文件,且文件中包含的是设备号,则mdev就利用这些信息为这个设备在/dev 下创建设备节点文件。一般只在启动时才执行一次 “mdev -s”。

热插拔事件:由于启动时运行了命 令:echo /sbin/mdev /proc/sys/kernel/hotplug ,那么当有热插拔事件产生时,内核就会调用位于 /sbin目录的mdev。这时mdev通过环境变量中的 ACTION 和 DEVPATH,来确定此次热插拔事件的动作以及影响了/sys中的那个目录。接着会看看这个目录中是否“dev”的属性文件,如果有就利用这些信息为 这个设备在/dev 下创建设备节点文件

重新打包文件系统,这样/sys目录,/dev目录就有东西了

下面是create_class的原型:

#define class_create(owner, name) /

({ /

static struct lock_class_key __key; /

__class_create(owner, name, __key); /

})

extern struct class * __must_check __class_create(struct module *owner,

const char *name,

struct lock_class_key *key);

class_destroy的原型如下:

extern void class_destroy(struct class *cls);

device_create的原型如下:

extern struct device *device_create(struct class *cls, struct device *parent,

dev_t devt, void *drvdata,

const char *fmt, ...)

__attribute__((format(printf, 5, 6)));

device_destroy的原型如下:

extern void device_destroy(struct class *cls, dev_t devt);

具体使用如下,可参考后面的实例:

static struct class *firstdrv_class;

static struct class_device *firstdrv_class_dev;

firstdrv_class = class_create(THIS_MODULE, "firstdrv");

firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */

class_device_unregister(firstdrv_class_dev);

class_destroy(firstdrv_class);

下面再来看一下应用程序如何找到这个结构体的

在应用程序中我们使用open打开一个设备:如:open(/dev/xxx, O_RDWR);

xxx有一个属性,如字符设备为c,后面为读写权限,还有主设备名、次设备名,我们注册时 通过register_chrdev(0, "first_drv", first_drv_fops)(有主设备号,设备名,struct file_operations结构体)将first_drv_fops结构体注册到内核数组chrdev中去的,结构体中有open,write函数,那么应用程序如何找到它的,事实上是根据打开的这个文件的属性中的设备类型及主设备号在内核数组chrdev里面找到我们注册的first_drv_fops,

实例代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static struct class *firstdrv_class;

static struct class_device *firstdrv_class_dev;

volatile unsigned long *gpfcon = NULL;

volatile unsigned long *gpfdat = NULL;

static int first_drv_open(struct inode *inode, struct file *file)

{

//printk("first_drv_open\n");

/* 配置GPF4,5,6为输出 */

*gpfcon = ~((0x3(4*2)) | (0x3(5*2)) | (0x3(6*2)));

*gpfcon |= ((0x1(4*2)) | (0x1(5*2)) | (0x1(6*2)));

return 0;

}

static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)

{

int val;

//printk("first_drv_write\n");

copy_from_user(val, buf, count); // copy_to_user();

if (val == 1)

{

// 点灯

*gpfdat = ~((14) | (15) | (16));

}

else

{

// 灭灯

*gpfdat |= (14) | (15) | (16);

}

return 0;

}

static struct file_operations first_drv_fops = {

.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

.open = first_drv_open,

.write = first_drv_write,

};

int major;

static int first_drv_init(void)

{

major = register_chrdev(0, "first_drv", first_drv_fops); // 注册, 告诉内核

firstdrv_class = class_create(THIS_MODULE, "firstdrv");

firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */

gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);

gpfdat = gpfcon + 1;

return 0;

}

static void first_drv_exit(void)

{

unregister_chrdev(major, "first_drv"); // 卸载

class_device_unregister(firstdrv_class_dev);

class_destroy(firstdrv_class);

iounmap(gpfcon);

}

module_init(first_drv_init);

module_exit(first_drv_exit);

MODULE_LICENSE("GPL");

编译用Makefile文件

KERN_DIR = /work/system/linux-2.6.22.6

all:

make -C $(KERN_DIR) M=`pwd` modules

clean:

make -C $(KERN_DIR) M=`pwd` modules clean

rm -rf modules.order

obj-m += first_drv.o

测试程序:

#include

#include

#include

#include

/* firstdrvtest on

* firstdrvtest off

*/

int main(int argc, char **argv)

{

int fd;

int val = 1;

fd = open("/dev/xyz", O_RDWR);

if (fd 0)

{

printf("can't open!\n");

}

if (argc != 2)

{

printf("Usage :\n");

printf("%s \n", argv[0]);

return 0;

}

if (strcmp(argv[1], "on") == 0)

{

val = 1;

}

else

{

val = 0;

}

write(fd, val, 4);

return 0;

}

docker中容器有必要挂载到主机上吗存储

例如docker run -it -v /data --name container1 busybox ); 和挂载到主机(例如docker run -it --name container1 -v /path/on/host:/datavol busybox )但是为了使容量在容器重启甚至容器交换(旧容器被删除,创build/启动新容器)中保持不变,这两种方法都不会将卷挂载到主机上吗? 换句话说,如果我没有通过“简单安装方法”明确地挂载到主机,那么卷的实际安装位置在哪里? 而且这个位置如何在容器交换中生存呢?而且,在这两种情况下,我都假定卷只是给定主机的本地卷,并且如果有一个Swarm或群集运行在多个主机上,则无法使用这些命令,以便在不同主机上运行的容器可以访问这些卷,是吗? (而且我猜这是Data Volume Containers发挥的作用,对吧?)提前致谢!这两种方法都不能将卷挂载到主机上?是的,这两种方法都基于容器生命周期中保存的主机目录。使用这些命令获取更多信息:docker volume ls docker volume inspect volume-id # and docker inspect container-id(方法1)实际安装量在哪里?做这个:docker inspect container-id你的答案在“来源”中:"Mounts": [ { "Type": "volume", "Name": "96f5e6531480cc716cd030f3f60f8927a55728a52d55ad55589752c2b89f2001", "Source": "/var/lib/docker/volumes/96f5e6531480cc716cd030f3f60f8927a55728a52d55ad55589752c2b89f2001/_data", "Destination": "/data", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ],请注意,如果您在OSX或Windows中,则该Source指的是运行docker的VM内部的本地目录。而且这个位置如何在容器交换中生存呢?他们生存,因为他们是基于主机的本地目录(他们是卷,因此它们存在)。如果在多个主机上运行Swarm或群集,则无法使用这些命令,以便运行在不同主机上的容器可以访问这些卷,是的?您对简单的卷configuration是正确的。 这是docker变得棘手,持久的地方。 您可以在主机文件系统级别实现共享目录,然后将其作为卷装载到容器中,以便跨群集主机获取共享卷。使用PHP在shell中运行docker运行或重新启动PostgreSQL映像后,Docker容器立即退出在CentOS7上暴露Docker Remote API v1.22在Docker上的terminal上安装Gambit绑定的文件夹的内容不可用Docker nginx错误在安assembly置文件Docker(带有SYSTEMCTL的CentOS 7):无法安装tmpfs&cgroup如何使用rabbitmq docker撰写yml文件来构builddocker镜像?Docker-Compose找不到新的节点模块MongoDB使用具有持久存储问题的docker分片群集在Docker中将“named volume”挂载为非root用户

如何正确的对安卓手机进行数据恢复

安卓手机的数据一般都是保存在手机自带内存或是手机SD卡中,丢失数据的存储介质不同,恢复方法也不同:

情况一:恢复手机内存卡SD卡中的数据

1. 将手机内存卡从手机中取出,然后通过读卡器接到电脑USB口。

2. 在电脑中安装数据恢复软件,然后运行软件。

3. 根据数据丢失原因选择数据恢复模块,例如,如果文件是被删除的,就选择“恢复已删除的文件”。

4. 选中丢失数据的内存卡,然后点击“下一步”按钮开始搜索文件。

5.?扫描完成后,选择需要恢复的文件,然后点击“恢复”按钮,将文件复制保存到电脑中。

情况二:恢复安卓手机自带内存丢失的数据

安卓手机自带内存这个部分存储空间比较特殊,直接使用上面的方法无法检测到手机内置存储空间,因此要按照下面的步骤进行恢复。

1. 将手机通过数据线与电脑连接好,然后开启手机的USB调试模式:设置-开发者选项-USB调试。

2. 在电脑中安装手机root软件,将需要恢复数据的手机root,取得手机的最高使用权限。

3. 在电脑中安装并运行手机数据恢复软件。

4. 在软件中找到并选择丢失的数据手机内置存储设备,然后点击“下一步”按钮。

5. 软件开始搜索丢失的数据,并将找到的文件列出来。

6. 在扫描结果中查找需要的文件,然后勾选文件并右击鼠标,选择“复制到指定文件夹”。将文件复制到电脑中即可。

(责任编辑:IT教学网)

更多