я починил эту ос, теперь хотел понемногу добавлять C, т.к. на чистом ассемблере далеко не уйдешь. Если получится запустить хоть Hello, World! - буду очень благодарен
make run
и введя команду hello
в консоли внутри qemu.Может надо сделать их объектными elf файлами, затем скомпоновать и зачистить формат?
gcc
для компиляции исходников на С (*.c
) и ассемблере (*.S
), gcc
или ld
для линковки, objcopy
для преобразования ELF-файла с выхода линковщика в бинарник.Почему от добавления функций помимо main() в начало кода ядро перестает работать?
i686-elf-ld -Ttext 0x7E00 --oformat binary kernel.o -o kernel -e main
; Jump to the kernel's entry point
JMP 0x0000:0x7E00
-e main
?main()
. Чтобы поместить нужный код в нужное место собранного образа обычно используют скрипт линковщика.mem*()
или большинство функций str*()
), есть часть, зависимость которой от ОС реализована в терминах других функций libc (например printf()
может выделять память и может записывать в файл, но обе эти функции уже реализованы в других местах libc), а есть часть напрямую взаимодействующая с ОС.Нашел документацию по ISA Xtensa
В memory map esp8266 этот вектор заносится по адресу 0x40000050
Не уверен, конечно, что это так
изучаю разработку модулей ядра,попытался скомпилировать модуль использующий структуру file_operation - ошибка,как оказалось в моих хедерах ядра(/usr/include/linux/) нету данной структуры
Можете подсказать причину?
void test(char** array){ array = malloc(sizeof(char*)); array[0] = malloc(255 * sizeof(char)); strcpy(array[0], "Hello world!"); }
void test(char*** array){
*array = malloc(sizeof(char*));
(*array)[0] = malloc(255 * sizeof(char));
strcpy((*array)[0], "Hello world!");
}
char** array; test(array);
char** array;
test(&array);
как выполнить задержку не понимаю
io_uring_prep_timeout
, но кроме этого нужно сериализовать таймаут и все предыдущие команды (чтобы таймаут начинался после их окончания) и следующую после таймаута команду и сам таймаут (чтобы последующие команды не стартовали вместе с таймаутом). Сериализация делается установкой флага IOSQE_IO_DRAIN
для sqe, почитать об этом можно например здесь. У меня нарисовался следующий пример, который записывает в файл (stderr), делает паузу в одну секунду, а потом записывает ещё:#include <fcntl.h>
#include <liburing.h>
#include <stdio.h>
#include <sys/mman.h>
#define QUEUE_DEPTH 16
int main(int argc, char **argv)
{
int i;
struct io_uring ring;
struct io_uring_cqe *pcqe;
static const char msg0[] = "before timeout\n";
static const char msg1[] = "after timeout\n";
struct io_uring_sqe *sqe;
io_uring_queue_init(QUEUE_DEPTH, &ring, 0);
io_uring_prep_write(io_uring_get_sqe(&ring), 2, msg0, sizeof(msg0), 0);
sqe = io_uring_get_sqe(&ring);
io_uring_prep_timeout(sqe, (struct __kernel_timespec[]){{.tv_sec = 1}},
-1, IORING_TIMEOUT_ETIME_SUCCESS);
io_uring_sqe_set_flags(sqe, IOSQE_IO_DRAIN);
sqe = io_uring_get_sqe(&ring);
io_uring_prep_write(sqe, 2, msg1, sizeof(msg1), 0);
io_uring_sqe_set_flags(sqe, IOSQE_IO_DRAIN);
io_uring_submit(&ring);
for (i = 0; i < 3; ++i) {
int rv = io_uring_wait_cqe(&ring, &pcqe);
if (rv < 0) {
errno = -rv;
perror("io_uring_wait_cqe");
} else {
io_uring_cqe_seen(&ring, pcqe);
}
}
}
static button s1;
в заголовочном файле, а это значит, что каждая единица трансляции в которую ты подключил этот файл получит свой собственный, независимый экземпляр переменной s1. Функция ModesInit
инициализирует s1 из ModeDriver.o
, а s1 из main.o
останется неинициализированным.static
на extern
в заголовочном файле, а в одном из исходников добавив определение для переменной -- button s1;
. sizeof(dict)/sizeof(const char)
const char
а не на размер const char *
. Во избежание таких ошибок для вычисления размера массива обычно пишут sizeof(dict)/sizeof(dict[0])
. можно подумать, что при объявлении указателя, символ * относится к имени(не как часть, а как что-то зависящее от него), а не к типу.
const char *a, b;
можно превратить в const char (*a), b
, но нельзя превратить в const (char *a), b
или в char (const *a), b
.Компилирую gcc -o outfile source.c -lpthread. То есть собираю без всяких статиков, чтобы были зависимости к подключенным библиотекам. Далее запускаю процесс, чекаю /proc/pid/maps. Там нет ни единого упоминания к libpthread.
-lpthread
продолжали собираться, внутри пустая. Короче, ты выбрал неудачного кандидата для экспериментов. Почему в Си после main() не ставят ;?
;
между объявлением и телом функции, не только для main
, но и для любой другой функции. Согласно стандарту языка, например С99 приводит следующий синтаксис определения функции:function-definition:
declaration-specifiers declarator declaration-list<opt> compound-statement
declaration-list:
declaration
declaration-list declaration
extern int max(a, b)
int a, b;
{
return a > b ? a : b;
}
;
.эта строка работает на другом языке?