您可以使用
dd if=/dev/zero of=file count=1024 bs=1024
将文件归零。
而不是我想填写一个文件。我怎么做?
没有 /dev/one 文件,那么如何通过 bash shell 模拟这种效果?
tr '\0' '\377' < /dev/zero | dd bs=64K of=/dev/sdx
这应该快得多。选择您需要的块大小(或添加计数)。以 99M 的块大小将它们写入 SSD 磁盘直到满,给了我 350M/s 的写入性能。
试试这个:
dd if=<(yes $'\01' | tr -d "\n") of=file count=1024 bs=1024
替换$'\377'
,或者$'\xFF'
如果您希望所有位都为 1。
好吧,你可以这样做:
dd if=/dev/zero count=1024 bs=1024 |
tr '\000' '\001' > file
pv /dev/zero |tr \\000 \\377 >targetfile
...其中\377
是255
(所有位都设置为 1 的字节)的八进制表示。为什么tr
只适用于八进制数,我不知道——但请注意不要下意识地将其翻译为3FF。
使用的语法tr
很容易出错。我建议验证它是否正在进行所需的翻译...
cat /dev/zero |tr \\000 \\377 |hexdump -C
注意:pv
是一个很好的实用程序,可以替换cat
并添加进度/速率显示。
我在我的github创建了一个设备驱动程序。安装它会创建一个/dev/one
只写入设置为 1 的位的文件。
名为 one.c 的 c 文件(唯一有趣的部分在 中device_file_read
):
// File Driver to create a devince /dev/one like the /dev/zero
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
MODULE_LICENSE("GPL");
static int device_file_major_number = 0;
static const char device_name[] = "one";
static ssize_t device_file_read(
struct file *file_ptr,
char __user *user_buffer,
size_t count,
loff_t *position) {
printk( KERN_NOTICE "One: Device file is read at offset = %i, read bytes count = %u\n" , (int)*position , (unsigned int)count );
// Allocate Kernel buffer
char* ptr = (char*) vmalloc(count);
// Fill it with one, byte per byte
// -- Note that byte is the smallest accesible data unit
memset(ptr, 0xFF, count);
char res = copy_to_user(user_buffer, ptr, count);
if (res != 0){ return -EFAULT; }
// Return number of byte read
return count;
}
static struct file_operations simple_driver_fops = {
.owner = THIS_MODULE,
.read = device_file_read,
};
int register_device(void) {
int res = 0;
printk( KERN_NOTICE "One: register_device() is called.\n" );
res = register_chrdev( 0, device_name, &simple_driver_fops );
if( res < 0 ) {
printk( KERN_WARNING "One: can\'t register character device with error code = %i\n", res );
return res;
}
device_file_major_number = res;
printk( KERN_NOTICE "One: registered character device with major number = %i and minor numbers 0...255\n", device_file_major_number );
return 0;
}
void unregister_device(void) {
printk( KERN_NOTICE "One: unregister_device() is called\n" );
if(device_file_major_number != 0) {
unregister_chrdev(device_file_major_number, device_name);
}
}
static int my_init(void) {
register_device();
return 0;
}
static void my_exit(void) {
unregister_device();
return;
}
// Declare register and unregister command
module_init(my_init);
module_exit(my_exit);
生成文件
TARGET_MODULE:=one
BUILDSYSTEM_DIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
obj-m := $(TARGET_MODULE).o
# See: https://stackoverflow.com/questions/15910064/how-to-compile-a-linux-kernel-module-using-std-gnu99
ccflags-y := -std=gnu99 -Wno-declaration-after-statement
build:
# run kernel build system to make module
$(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) modules
clean:
# run kernel build system to cleanup in current directory
$(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) clean
rm -f MOK.priv MOK*.der
key:
echo "Creating key"
openssl req -new -x509 -newkey rsa:2048 -days 36500 -keyout MOK.priv -outform DER -out MOK.der -nodes -subj "/CN=TinmarinoUnsafe/"
#
echo "\e[31;1mPlease enter a password you will be asked for on reboot:\e[0m"
mokutil --import MOK.der
echo "\e[31;1mNow you must: 1/ reboot, 2/ Select Unroll MOK, 3/ Enter password you previously gave\e[0m"
sign:
cp one.ko one.ko.bck
/usr/src/linux-headers-$(shell uname -r)/scripts/sign-file sha256 MOK.priv MOK.der one.ko
load:
insmod ./$(TARGET_MODULE).ko
unload:
rmmod ./$(TARGET_MODULE).ko
create:
mknod /dev/one c $(shell cat /proc/devices | grep one$ | cut -d ' ' -f1) 0
delete:
rm /dev/one
test:
[ "$(shell xxd -p -l 10 /dev/one)" = "ffffffffffffffffffff" ] \
&& echo "\e[32mSUCCESS\e[0m" \
|| echo "\e[31mFAILED\e[0m"
由于驱动程序签名强制执行,安装时间很长(3 分钟)。如果您在 UEFI 中禁用它,请忽略此部分。
git clone https://github.com/tinmarino/dev_one.git DevOne && cd DevOne # Download
make build # Compile
make key # Generate key for signing
sudo make sign # Sign driver module to permit MOK enforcement (security)
sudo reboot now # Reboot and enable Mok
make sign
sudo make load # Load
sudo make device # Create /dev/one
make test # Test if all is ok
/dev/one
您可以在没有特殊设备的情况下使用 FIFO + printf
(在循环中;慢速)或yes
(快速)模拟:
mkfifo ddfifo
dd if=ddfifo of=<file> iflag=fullblock count=1024 bs=1024 status=progress & while printf '\1'; do printf '\1'; done > ddfifo
或者:
mkfifo ddfifo
dd if=ddfifo of=<file> iflag=fullblock count=1024 bs=1024 status=progress & yes "" | tr '\n' '\1' > ddfifo
如果您想要所有位都设置为 1 的字节,请'\1'
交换'\377'
.