How do I get an equivalent of /dev/one in Linux
Solution 1
Try this:
dd if=<(yes $'\01' | tr -d "\n") of=file count=1024 bs=1024
Substitute $'\377'
or $'\xFF'
if you want all the bits to be ones.
Solution 2
tr '\0' '\377' < /dev/zero | dd bs=64K of=/dev/sdx
This should be much faster. Choose your blocksizes (or add counts) like you need at. Writing ones to a SSD-Disk till full with a blocksize of 99M gave me 350M/s write performance.
Solution 3
Well, you could do this:
dd if=/dev/zero count=1024 bs=1024 |
tr '\000' '\001' > file
Solution 4
pv /dev/zero |tr \\000 \\377 >targetfile
...where \377
is the octal representation of 255
(a byte with all bits set to one). Why tr
only works with octal numbers, I don't know -- but be careful not to subconsciously translate this to 3FF.
The syntax for using tr
is error prone. I recommend verifying that it is making the desired translation...
cat /dev/zero |tr \\000 \\377 |hexdump -C
Note: pv
is a nice utility that replaces cat
and adds a progress/rate display.
Solution 5
I created a device driver in my github. Installing it creates a file /dev/one
that is writing only bits set to 1.
The c file called one.c (the only interesting part is in 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);
The Makefile
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"
The instalation is long (3min) due to the driver signature enforcement. Froget this part if you disabled it in your 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
- A blue screen (MOK manager) will appear
- Choose "Enroll MOK"
- Choose "Continue"
- Choose "Yes" (when asked "Enroll the key")
- Enter the password you gave at
make sign
- Choose "Reboot" (again)
sudo make load # Load
sudo make device # Create /dev/one
make test # Test if all is ok
Related videos on Youtube
Ankur Agarwal
Updated on July 11, 2022Comments
-
Ankur Agarwal almost 2 years
You can use
dd if=/dev/zero of=file count=1024 bs=1024
to zero fill a file.
Instead of that I want to one fill a file. How do I do that?
There is no
/dev/one
file, so how can I simulate that effect via on bash shell?-
נשמה קשוחה about 12 yearsWrite a C program to do it, should be trivial.
-
-
Neil about 12 yearsOne fill would be '\377', no?
-
larsks about 12 yearsHmm, I guess it depends on what you want. This will fill a file with bytes of value
1
(01 01 01 01 ...
). Using\377
gets you all bits set to 1 (soFF FF FF FF ...
). Depends on the OP's requirements. -
Skippy le Grand Gourou over 10 yearsI confirm this is at least twice as fast as the accepted solution. However I didn't notice any noticeable performance improvement from varying the blocksize (though there is a huge decrease of performance without the bs argument).
-
Brent Bradburn over 7 yearsNote: If you are trying to fill an entire device, it's probably better to avoid
dd
since that will slow things down (by a lot) if you don't manually select an optimumbs
value. -
Brent Bradburn over 7 years
pv
will also give an estimate of time remaining if it has enough information to do so. -
Brent Bradburn over 7 yearsWhile you're at it, maybe prefix with
time
andnice
. -
Matt Sephton almost 6 yearsFor others: on macOS you will need to set environment variable LANG="C" to get
tr
to behave in the way that makes this command work -
SourceSeeker almost 6 years@MattSephton: I just tested it on MacOS Sierra and it works fine for me without changing
LANG
(mine is en_US.UTF-8). -
Matt Sephton almost 6 yearsInteresting. I was changing \00 to \xFF and was getting something other than \xFF until I used LANG="C"
-
SourceSeeker almost 6 years@MattSephton: Anything
\x80
or above. Evidently it doesn't like the 8th bit set unlessLANG=C
. For those that might not be aware, you can do that for just the environment oftr
:dd if=<(yes $'\xFF' | LANG=C tr -d "\n") of=file count=1024 bs=1024
and it doesn't affect the general environment. -
Chris Stryczynski over 5 yearsThis gives me an error of:
dd: failed to open '/dev/fd/63': No such file or directory
-
SourceSeeker over 5 years@ChrisStryczynski: Did you run it using
sudo
? That's one possible reason for that error. If so, then this is one way to make it work:sudo bash -c 'dd if=<(yes $'\01' | tr -d "\n") of=file count=1024 bs=1024'
-
Chris Stryczynski over 5 years@DennisWilliamson yes was using sudo. The
bash -c ...
works however! -
SourceSeeker over 5 years@ChrisStryczynski: The process substitution creates a file descriptor which
sudo
then closes making it unavailable. Wrapping the whole thing inbash -c
delays the creation of the file descriptor until aftersudo
starts. -
Johnny Wong almost 3 yearsThanks. I successfully used this modified command to one-fills my 2GB micro SD:
tr '\0' '\377' < /dev/zero | pv | sudo dd bs=512K of=/dev/sdx
with speed ~8MB/s. The commandpv
shows you how many bytes are done, and the speed. You may need to install it, but it's very useful.