Я не вижу потребности в веб-разработчике использовать Windows для разработки. Хотя Вы все еще захотите платформу Windows для тестирования. Какой btw Вы не включаете в Вас список инструментов. У Вас должна быть своего рода автоматизированная тестовая среда для нескольких различных платформ, но это может все быть сделано в VM.
Я не использовал бы IDE как Spket, но изучу один из основных и (обычно говорящий) очень программируемые редакторы: emacs, vi, или затмение.
Я также использовал бы Подвижный на стороне клиента для всего кода.
Они - на самом деле просто это - интерфейсы. Закодированный "главным" и "незначительным" числом они предоставляют рычаг ядру.
Они прибывают в две разновидности (хорошо, три, но именованные каналы вне объема этого объяснения на данный момент): Устройства посимвольного ввода-вывода и Блочные устройства.
Блочные устройства имеют тенденцию быть устройствами хранения, способными к буферизации вывода и хранить данные для более позднего извлечения.
Устройства посимвольного ввода-вывода являются вещами как звуковые карты или видеокарты или устройства ввода данных как клавиатура и мышь.
В каждом случае, когда ядро загружает корректный драйвер (или во время начальной загрузки, или с помощью программ как udev) это сканирует различные шины, чтобы видеть, присутствуют ли какие-либо устройства, обработанные тем драйвером на самом деле, в системе. Если так, это настраивает устройство, которое 'слушает' на соответствующем главном/незначительном числе.
(Например, Цифровой сигнальный процессор первой звуковой карты, найденной Вашей системой, получает главную/незначительную пару числа 14/3; второе добирается 14,35, и т.д.),
Это до udev для создания записи в /dev
именованный dsp
поскольку устройство посимвольного ввода-вывода отметило главные 14 незначительных 3.
(В значительно более старом или версиях минимального места Linux, /dev/
может не быть динамично загружен, но просто содержать все возможные файлы устройств статически.)
Затем когда программа пространства пользователя пытается получить доступ к файлу, это отмечено как 'символьный специальный файл' с соответствующим главным/незначительным числом (например, Ваш аудиоплеер, пытающийся отправить цифровое аудио в /dev/dsp
), ядро знает, что эти данные должны быть переданы через драйвер, к которому присоединено главное/незначительное число; по-видимому, упомянутый драйвер знает, что сделать с ним в свою очередь.
Каждый файл, устройство или иначе, поддерживает 6 основных операций в VFS:
Кроме того, файлы устройств поддерживают Управление ввода-вывода, которое позволяет другие разные операции, не покрытые первыми 6.
В случае символьного специального предложения ищите и скажите, не реализованы, так как они поддерживают интерфейс потоковой передачи. Таким образом, читая или при записи непосредственно тех, которые сделаны с перенаправлением в оболочке:
echo 'foo' > /dev/some/char
sed ... < /dev/some/char
«Символ за раз» является неправильным термином (как и идея о том, что символьные устройства обязательно не поддерживают поиск и определение). На самом деле, "блочные" (т.е. строго ориентированные на запись, такие как ленточный накопитель*) устройства должны быть символьными устройствами. Такова же идея, что символьное устройство обязательно должно быть недоступным для поиска - драйверы символьных устройств определяют полную структуру file_operations
, которая может свободно определять llseek или нет в зависимости от того, поддерживает ли устройство операцию. Символьные устройства, которые большинство людей считают примерами, — это null, urandom, устройства TTY, звуковая карта, мышь и т. д., которые невозможно найти из-за специфики этих устройств, но /dev/vcs, /dev/fb0 и /dev/kmem также являются символьными устройствами, и все они доступны для поиска.
Как я уже упоминал, драйвер символьного устройства определяет структуру file_operations, которая имеет указатели функций для всех операций, которые кто-то может захотеть вызвать с файлом — поиск, чтение, запись, ioctl и т. д. — и каждая из них вызывается один раз, когда соответствующий системный вызов выполняется при открытом файле устройства. И поэтому чтение и запись могут делать со своими аргументами все, что захотят — они могут отказаться принимать запись, которая слишком велика, или писать только то, что подходит; он может прочитать только данные, соответствующие одной записи, а не все запрошенное количество байтов.
Итак, что такое блочное устройство? По сути, блочные устройства представляют собой дисковые накопители. Ни одно другое устройство (кроме виртуальных дисков, таких как ramdisk и loopback) не является блочным устройством.Они интегрированы в систему запросов ввода/вывода, уровень файловой системы, систему буферов/кэшей и систему виртуальной памяти таким образом, что символьные устройства не интегрированы, даже когда вы обращаетесь, например. /dev/sda из пользовательского процесса. Даже «необработанные устройства», упомянутые на этой странице в качестве исключения , являются символьными устройствами.
*Некоторые системы UNIX реализовали так называемый «режим с фиксированными блоками», который позволяет ядру группировать и разделять запросы ввода-вывода, чтобы соответствовать сконфигурированным границам блоков более или менее таким же образом, как это делается для дисковых накопителей. как блочное устройство. Символьное устройство необходимо для «режима переменного блока», который сохраняет границы блока из пользовательской программы, поскольку одиночный вызов write(2) записывает один блок, а одиночный вызов read(2) возвращает один блок. Поскольку переключение режимов теперь реализовано как ioctl, а не как отдельный файл устройства, используется символьное устройство. Ленточные накопители с переменной записью в основном не поддерживают поиск, поскольку поиск включает подсчет количества записей, а не количества байтов, а собственная операция поиска реализована как ioctl.
Минимальная работоспособность file_operations
пример
Когда вы видите минимальный пример, все становится очевидным.
Ключевые идеи:
file_operations
содержит обратные вызовы для каждого системного вызова, связанного с файлом mknod <path> c <major> <minor>
создает символьное устройство, которое использует этиfile_operations
cat /proc/devices
character_device.ko
модуль ядра:
#include <asm/uaccess.h> /* copy_from_user, copy_to_user */
#include <linux/errno.h> /* EFAULT */
#include <linux/fs.h> /* register_chrdev, unregister_chrdev */
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/printk.h> /* printk */
#include <uapi/linux/stat.h> /* S_IRUSR */
#define NAME "lkmc_character_device"
MODULE_LICENSE("GPL");
static int major;
static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
size_t ret;
char kbuf[] = {'a', 'b', 'c', 'd'};
ret = 0;
if (*off == 0) {
if (copy_to_user(buf, kbuf, sizeof(kbuf))) {
ret = -EFAULT;
} else {
ret = sizeof(kbuf);
*off = 1;
}
}
return ret;
}
static const struct file_operations fops = {
.owner = THIS_MODULE,
.read = read,
};
static int myinit(void)
{
major = register_chrdev(0, NAME, &fops);
return 0;
}
static void myexit(void)
{
unregister_chrdev(major, NAME);
}
module_init(myinit)
module_exit(myexit)
Программа тестирования пользовательской среды:
insmod /character_device.ko
dev="lkmc_character_device"
major="$(grep "$dev" /proc/devices | cut -d ' ' -f 1)"
mknod "/dev/$dev" c "$major" 0
cat /dev/lkmc_character_device
# => abcd
rm /dev/lkmc_character_device
rmmod character_device
GitHub QEMU + Buildroot восходящей ветки с шаблонным кодом, чтобы запустить его:
Более сложные примеры:
read
, write
, lseek
с внутренним буфером фиксированного размера и на debugfs вместо символьного устройства:https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/fops.cpoll
:https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/poll.cioctl
:https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/poll.canon_inode_getfd
связывает file_operations
с дескриптором файла без какого-либо файла файловой системы:https://stackoverflow.com/questions/4508998/what-is-anonymous-inode/44388030#44388030