LINUX.ORG.RU

ЯП, ОС, архитектура процессоров, инструкции

 , , , ,


1

3

Заглянув за кулисы своего компьютерного мирка, получил кучу мозаичных кусочков.
1. Вот есть у нас процессор со своей архитектурой, будь то X86 или ARM. Под нее портируют компиляторы топовых языков программирования путем использования процессорных инструкций вроде SSE. Что есть оптимизации компилятора? Вот написан код, компилятор его перековеркал для лучшей производительности на определенной архитектуре при использовании тех или иных инструкций процессора. Но всегда ли выбранный компилятором способ коверканья определенного куска кода можно считать оптимальным? Есть оптимизации на потребление оперативной памяти, производительности, размера кода, да что уж там - всяких «волшебных ключиков» просто тьма, успевай только тестировать их. Обилие этих ключиков соединяются в группы оптимизаций по параметрам. ОС пишут на компиляторе ЯП, компилятор завязан на ОС для компилирования других проектов - иначе не было бы таких разделений вроде: «поддерживаемые платформы: MS Windows, Linux, Android» и т.п. Этот список поддерживаемых платформ есть даже у самого компилятора (rust, например). Вот хочу я, например, свой процессор изобрести с уникальной архитектурой, значит ли это, что мне, минимум, придется портировать компилятор того же С? А если написать операционную систему? Ее корень - ядро, его пишут на ЯП, компилятор которого уже завязан на поддерживаемых им платформах (читай: ОС), значит ли это, что написать свое ядро на том же расте невозможно?
2. Еще мне непонятна идея генерируемого кода компиляторами. Пару слов обо мне: шарпист заинтересовался растом, значит попытаюсь понять на его примере. Так вот, у нас есть компилятор раста, который генерирует безопасный исполняемый код. В том же C или C++ генерируется код, но его безопасность исполнения не гарантируется. В C# есть сборщик мусора как решение проблемы предыдущих языков программирования. В расте сборщика мусора нет, т.е. его компилятором генерируется то же самое, что и у C или C++, но в данном случае он безопасный «на слово», в конечном виде он выглядит как и небезопасный результат компиляторов прежних 2-ух ЯП? Или компилятор раста на стадии компиляции проверяет паршивость кода, но при этом то же самое происходит при выполнении программы и от результата какой-нибудь проверки может случиться что-то иначе? Сложновато объяснил, всё сводится к следующему вопросу: какими жертвами удалось добиться безопасности растом?


Ответ на: комментарий от tailgunner

на любовм говнишке есть такое нечто. и чо?

anonymous
()
Ответ на: комментарий от anonymous

Тут не нужны проверки.

Контекст. Вопрос был про проверки выхода за границу в рантайме сгенеренного кода. Мы же не синтаксис обсуждаем.

Ты итерируешься по существующей последовательности.

:)

sf ★★★
()
Ответ на: комментарий от tailgunner

я «украл» это из описания:

Pycorn is an interpreted operating system written in Python

так-то понятно, что вряд ли они осилили что-то хотя бы уровня Hurd. с другой стороны, что такое ОС? это же просто некая программная прослойка между железом и пользователем, позволяющая взаимодействовать с этим самым железом. а вообще, это я виноват, что сформулировал фразу слишком обобщенно.

CryAngel
()
Ответ на: комментарий от anonymous

А для for сделали по-другому.

Почему по-другому? Там просто нельзя указать тип. Если было бы можно, то выглядело бы точно так же:

for val: isize in ...
Честно говоря, в этом проблемы не вижу. Хотя, пожалуй, было бы более единообразно с остальным кодом.

Причем если говорить про C++, там можно написать: ... А в rust нет.

Тут я не понял идею, но в расте можно написать так же:

let f = |i| i + 1;
let v = f(1);
А можно и указать типы, всё (ну кроме цикла for, ок) точно так же как в С++ - хочешь указываешь, а хочешь нет:
let f = |i: i32| -> i32 { i + 1 };
let v: i32 = f(1);

DarkEld3r ★★★★★
()
Ответ на: комментарий от sf

Хорошо, сколько тут проверок?

«Смотря каких». Под (чего-то стоящими) проверками я подразумевал аналог плюсового at - при простом доступе по индексу раст делает похожие вещи.

А при проходе через итераторы у нас нет такого кода на каждой итерации:

if(pos >= size) {
    throw std::out_of_range();
}

DarkEld3r ★★★★★
()
Ответ на: комментарий от CryAngel

с другой стороны, что такое ОС? это же просто некая программная прослойка между железом и пользователем, позволяющая взаимодействовать с этим самым железом

ОС должна уметь пускать независимые от нее программы и предоставлять им некий API - я не увидел этого в pycorn. Впрочем, я только краем глаза глянул.

tailgunner ★★★★★
()
Ответ на: комментарий от German_1984

Завязка компилятора на ОС достаточно мала. Она выражается, ЕМНИП, в двух вещах:

1) Заголовок исполняемого файла. Его добавляет линковщик в последний момент и это легко изменить. Как пример - кросскомпиляция.

2) Соглашения о вызовах функций ОС. Тоже чисто механическая тасовка байтов.

Осталось собрать пазл воедино. Загрузчик имеет драйвер работы с ФС, грузит ядро с его драйверами в память -> появляется поддержка файловой системы-> заглушка для вызова ядра read -> возможность использования файловой системы скомпилированной программой. Т.е. ядро может работать с ФС при наличии заглушек для драйверов в самой же себе? Запутался. Как объяснить наличие нативных потоков в стандартной библиотеке раста? Были бы они зелеными - своей реализацией, но тут просто обертка над потоками ОС. Сюда же io, fs, net.

Dulze
() автор топика
Ответ на: комментарий от Dulze

Что-то этот пазл больше на кашу похож.

В случае с загрузчик/ядро ОС отличается от обычного бинарника тем что, во-первых, у них свой заголовок, отличающийся от обычных pe/elf, во-вторых, они не могут использовать внешние библиотеки.

Процесс начальной загрузки (bootstrapping) вообще тема достаточно интересная. В большинстве дистрибутивов Linux между включением ПК и началом исполнения кода ядра происходит загрузка 3-х промежуточных микроОС.

Про потоки - поясни пожалуйста, о чем речь, о thread или stream?

Хотя не суть, стандартная библиотека - хоть и часть дистрибутива ЯП, но все же библиотека. На каждой ОС она или использует родные API ОС или велосипедит свои решения, если в ОС таких функций нет или они реализованы совсем иначе.

Библиотека - это библиотека, она крайне сильно зависит от ОС. Думал что это очевидно.

German_1984 ★★
()

значит ли это, что написать свое ядро на том же расте невозможно?

Конечно! Нельзя написать ОС на языке программирования! ОС же никто никогда не писал. Линускы, Виндовсы и Макоси дарованы свыше сразу в виде бинарного кода.

но в данном случае он безопасный «на слово»

Скажу по секрету: любая безопасность - безопасность «на слово». Тезисы верны лишь пока их не опровергли. В том числе и сборщик мусора твоего C# может сломаться на каком-то хитром примере, про который разрабы еще не знают.

Aswed ★★★★★
()
Ответ на: комментарий от CryAngel

да, я знаю, что они так и называются - «модуль ядра». но мне не нравится сама формулировка «часть ядра» применительно к драйверам, т.к. подобное словосочетание легко трактовать как «входит в ядро, поставляется вместе с ядром»

Ещё раз - эта формулировка абсолютно правильная. Модуль - это код ядра который можно динамически загружать и выгружать, а как он поставляется не имеет никакого значения. Не вводите людей в заблуждение.

slovazap ★★★★★
()
Ответ на: комментарий от German_1984

Библиотека - это библиотека, она крайне сильно зависит от ОС. Думал что это очевидно.

Но эта самая библиотека и дает те самые преимущества раста: начиная от типов и заканчивая всякими абстракциями над операционными системами. Чем тогда оно лучше какого-нибудь qt или даже wxWidgets? Тот же огород. Раст содержит мощный статический анализатор кода, кто он без него? Те же штуки есть и для других ЯП, просто они не из коробки. Теперь понятно доминирование C в системном программировании - он везде. Я запутался, окончательно. И всё-таки, раст зависит от ОС, т.е. для написания своей ОС придется велосипедить то, что ненавелосипедили на расте разработчики этого ЯП?

Dulze
() автор топика
Ответ на: комментарий от Aswed

Скажу по секрету: любая безопасность - безопасность «на слово». Тезисы верны лишь пока их не опровергли. В том числе и сборщик мусора твоего C# может сломаться на каком-то хитром примере, про который разрабы еще не знают.

Я имел ввиду следующее. Если код работает через виртуальную машину, она всем управляет, всё контролирует, пытается по крайней мере. Код на C делает то, что написал программист: криво обратился к памяти - лови утечку и т.п. Так вот, раст пытается во время выполнения корректировать возникновение утечек, как виртуальная машина, или всё-таки в код заложено: идти налево можно (к утечке), но это «можно» скорректировано на стадии компиляции и поведение бинарного результата схоже с кривым кодом на C, однако заложены четкие границы допустимой работы с памятью? Если с этими границами что-нибудь произойдет с помощью внешних факторов - утечка. Для большего понимания приведу аналогию: дан лабиринт, C# проходит его с помощью GPS и карт, C идет наудачу и может заблудиться, Rust помнит все развилки лабиринта или Rust'а тоже что-то свыше направляет?

Dulze
() автор топика

Ради расширения сознания вам надо бы попробовать программировать микроконтроллер на ARM из-под обычного Линукса. Вы узнаете, что такое кросс-компиляция, и что такое работа софта на голом железе, без ОС и MMU, когда все лежит прямо в памяти по реальным адресам.

Deleted
()
Ответ на: комментарий от Dulze

Rust помнит все развилки лабиринта или Rust'а тоже что-то свыше направляет?

Rust знает хороший способ прохождения лабиринтов.

Deleted
()
Ответ на: комментарий от Dulze

Я запутался, окончательно. И всё-таки, раст зависит от ОС, т.е. для написания своей ОС придется велосипедить то, что ненавелосипедили на расте разработчики этого ЯП?

// kernel.rs
#![crate_type="staticlib"]
#![feature(no_std, core, lang_items, asm)]
#![no_std]

#[macro_use]
extern crate core;

use core::prelude::*;

const VGA: *mut u16 = 0xB8000 as *mut u16;
const COLS: usize = 80;
const ROWS: usize = 25;

#[no_mangle]
pub extern fn kernel_main(_magic: u32, _info: u32) -> ! {
    cls();
    puts("Hello, from Rust!");
    
    loop { halt() }
}

fn cls() {
    for i in 0 .. COLS * ROWS {
        unsafe { mmio_write_u16(VGA.offset(i as isize), 0); }
    }
}

fn puts(s: &str) {
    for (i, c) in s.chars().enumerate() {
        unsafe { mmio_write_u16(VGA.offset(i as isize), c as u16 | 0xB00); }
    }
}

fn halt() {
    unsafe { asm!("hlt") }
}

unsafe fn mmio_write_u16(p: *mut u16, n: u16) {
     asm!("movw $0, ($1)" : : "ri" (n), "ri" (p))
}

#[lang="stack_exhausted"]
extern fn stack_exhausted() -> ! {
    loop { halt() }
}

#[lang="eh_personality"]
extern fn eh_personality() -> ! {
    loop { halt() }
}

#[lang="panic_fmt"]
extern fn panic_fmt() -> ! {
    loop { halt() }
}
// boot.S
#define MULTIBOOT_HEADER_ALIGN 4
#define MULTIBOOT_HEADER_MAGIC 0x1badb002
#define MULTIBOOT_HEADER_FLAGS 0x00000003
#define MULTIBOOT_HEADER_CHECKSUM \
	-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

#define STACK_SIZE 0x4000

	.text
	.global _start
_start:
	jmp multiboot_entry
	
	.align MULTIBOOT_HEADER_ALIGN
multiboot_header:
	.long MULTIBOOT_HEADER_MAGIC
	.long MULTIBOOT_HEADER_FLAGS
	.long MULTIBOOT_HEADER_CHECKSUM

multiboot_entry:
	movl $stack_top, %esp
	
	pushl $0
	popfl
	
	// disable rust stack check
	movl $0, %gs:0x30
	
	pushl %ebx
	pushl %eax
	call kernel_main
	
	.bss
stack_bottom:
	.space STACK_SIZE
stack_top:
/* ldscript */
ENTRY(_start)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386)
TARGET(elf32-i386)

SECTIONS {
	. = 0x100000;
	.text : {
		boot.o(.text);
		*(.text*);
	}
	.rodata : {
		*(.rodata*);
	}
	.data : {
		*(.data*);
	}
	.bss : {
		*(.bss*);
	}
	/DISCARD/ : {
		*(.comment);
		*(.eh_frame);
	}
}
$ rustc --target=i686-unknown-linux-gnu -O kernel.rs
gcc -m32 -c boot.S
ld -n -T ldscript -o kern boot.o libkernel.a
qemu-system-x86_64 -kernel kern

За кулисами остались пару нюансов, которые ещё нужно сделать для полноценной разработки ОС на Rust.

anonymous
()

Кто асилил тред, скажите - это анонiмус, или просто вася ёбнутый?

anonymous
()
Ответ на: комментарий от Dulze

Раст содержит мощный статический анализатор кода, кто он без него? Те же штуки есть и для других ЯП

Это не совсем так. Раст предъявляет определённые требования к коду, иначе просто не скомпилится. То есть это свойство языка, иначе можно говорить, что в С++ «встроен анализатор» запрещающий писать невалидные конструкции.

DarkEld3r ★★★★★
()
Ответ на: комментарий от Dulze

C# проходит его с помощью GPS и карт, C идет наудачу и может заблудиться, Rust помнит все развилки лабиринта или Rust'а тоже что-то свыше направляет?

Может ты возьмёшь на почитаешь об языке? Чем выяснять через кривые аналогии уже давно успел бы это сделать. В расте есть как гарантии времени компиляции, так и рантаймовые проверки.

DarkEld3r ★★★★★
()
Ответ на: комментарий от Dulze

Нет, в расте нет VM. Она работает как С, только компилятор сам проставляет free(). Если, например, упадет с паникой поток один, то память за ним не вычищается. Так же, раст не умеет разруливать циклические ссылки в Rc и там тоже можно спровоцировать утечку. Это два общеизвестных узких места раста.

Aswed ★★★★★
()
Ответ на: комментарий от Dulze

Причина доминирования С в том что синтаксис языка максимально отделен от стандартной библиотеки. Ни один оператор языка не транслируется в вызов функции ОС. И в любой момент можно отказаться от стандартной библиотеки или заменить ее на свою.

В С++ это уже не так - операторы new и delete транслируются в вызовы функций стандартной библиотеки, которая связана с ОС. В С++ их еще можно переопределить, но это требует глубокого понимания и дополнительных усилий. Как с этим в Rust - не знаю, пока не щупал.

German_1984 ★★
()
Ответ на: комментарий от German_1984

В С++ это уже не так - операторы new и delete транслируются в вызовы функций стандартной библиотеки, которая связана с ОС.

LOL, а в С malloc и free на мане небесной работают. new и delete это по сути сахар на malloc + конструктор и деструктор + free.

anonymous
()
Ответ на: комментарий от anonymous

Не путай божий дар с яичницей операторы и функции.

В С ты должен явно вызвать malloc, slab_alloc, my_alloc или любую другую функцию. Или не вызвать вообще.

В С++ когда пишешь std::array<int,10> myarray; у тебя неявно вызывается new, который неявно вызывает malloc или что-то еще.

Когда пишешь обычное десктопное ПО то разница не очевидно. Когда пишешь для микроконтроллера или ядра ОС - разница огромна.

German_1984 ★★
()
Ответ на: комментарий от German_1984

Не путай божий дар с яичницей операторы и функции.

Это у тебя мозгов нет, чтоб понять, что в данном случае это одно и тоже. Посмотри что рождает линковщик, может поймешь разницу между new и «1 + 2», например.

В С ты должен явно вызвать malloc, slab_alloc, my_alloc или любую другую функцию. Или не вызвать вообще.
В С++ когда пишешь std::array<int,10> myarray; у тебя неявно вызывается new, который неявно вызывает malloc или что-то еще.

Еще раз LOL. Когда ты вызываешь «malloc, slab_alloc, my_alloc или любую другую функцию» у тебя неявно вызывает еще масса много чего, и С++ дает управляемость ровно до этого же уровня через аллокаторы и перегрузку new/delete.

Когда пишешь обычное десктопное ПО то разница не очевидно. Когда пишешь для микроконтроллера или ядра ОС - разница огромна.

Так ты ведь и не писал. А я вкладывался в 8Кб на С++. Ес-но без стандартных библиотек вообще.

anonymous
()
Ответ на: комментарий от German_1984

std::array<int,10>

А это вообще перл, тебя glib, например, не смущает, где тебе даже аллокатор не дают подсунуть? А еще, если использовать dmalloc вместо malloc из glibc, он может упасть подняв лапки. Вот тебе и очевидность в С.

anonymous
()
Ответ на: комментарий от German_1984

В С++ когда пишешь std::array<int,10> myarray; у тебя неявно вызывается new, который неявно вызывает malloc или что-то еще.

Не вызывается. std::array хранит обычный сишный массив в себе, без выделения памяти в куче.

Когда пишешь обычное десктопное ПО то разница не очевидно. Когда пишешь для микроконтроллера или ядра ОС - разница огромна.

Если ты знаешь C++, то разницы нет никакой. Ты всегда знаешь, что стоит за конструкцией, которую ты написал.

anonymous
()
Ответ на: комментарий от Deleted

и что такое работа софта на голом железе, без ОС и MMU, когда все лежит прямо в памяти по реальным адресам

читая это, словил оргазм

unt1tled ★★★★
()
Ответ на: комментарий от Aswed

Если, например, упадет с паникой поток один, то память за ним не вычищается.

Это не соответствует действительности. При панике деструкторы вызываются и память освобождается. Вот если возникла паника в деструкторе, который был вызван из-за паники, то да - ситуация будет как в С++.

Так же, раст не умеет разруливать циклические ссылки в Rc

Собственно, с циклическими ссылками везде проблемы, если ГЦ нет.

DarkEld3r ★★★★★
()
Ответ на: комментарий от German_1984

Ну и чтоб не быть голословным. Вот код на С++:

~$ cat ./test.cpp 
#include <list>
#include "myalloc.hpp"
using namespace std;

int main()
{
    list<int, myalloc<int>> l;
    l.push_back( 1 );
    l.push_back( 2 );
    l.push_back( 1 );
    l.remove( 1 );
}
~$ g++ -std=c++11 ./test.cpp 
~$ ./a.out 
allocate 1 element(s) of size 24
 allocated at: 0xacac20
allocate 1 element(s) of size 24
 allocated at: 0xacac40
allocate 1 element(s) of size 24
 allocated at: 0xacac60
deallocate 1 element(s) of size 24 at: 0xacac20
deallocate 1 element(s) of size 24 at: 0xacac60
deallocate 1 element(s) of size 24 at: 0xacac40

Я для одного экземпляра стандартного контейнера выставил свой аллокатор, могу собирать статистику, пул использовать для оптимизации, в stdout писать и т.д. Это подход С++. А подход С - это:

а) не дать тебе вообще нихрена подобного в стандартной библиотеке;
б) в сторонней библиотеке (типа glib), тупо использовать malloc без всякой возможности что-то поменять, кроме как глобально использовать свой malloc (который еще и может поломать glib);
в) когда настает грусть-печаль, ты садишься и пишешь свой велосипед, чтоб явно вставить my_alloc.

Если ты _это_ называешь контролем над исполнением, значит ты просто реально никогда так не делал и расписываешь свои теоретические представления.

anonymous
()
Ответ на: комментарий от anonymous

Я для одного экземпляра стандартного контейнера выставил свой аллокатор

А передать list<int, myalloc<int>> в функцию, которая принимает list<int>& - можешь?

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

А передать list<int, myalloc<int>> в функцию, которая принимает list<int> - можешь?

Нет, т.к. это уже другой тип, ты же не отдаешь map<string> вместо map<int>, или сишный указатель вместо list<int>. Если его нужно использовать в нескольких местах - делаешь typedef и используешь.

П.С. а другой тип это ради очевидной оптимизации, чтоб не было оверхеда в рантайме.

anonymous
()
Ответ на: комментарий от tailgunner

А передать list<int, myalloc<int>> в функцию, которая принимает list<int>& - можешь?

Ну и опять же, если тебе нужна функция для разных типов - есть шаблоны.

anonymous
()
Ответ на: комментарий от anonymous

А передать list<int, myalloc<int>> в функцию, которая принимает list<int> - можешь?

Нет

Вот именно. И в этом тоже «подход Си++». А в Си неважно, как ты выделил память, и да, это тоже контроль за исполнением.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Вот именно. И в этом тоже «подход Си++». А в Си неважно, как ты выделил память, и да, это тоже контроль за исполнением.

Подход С++ не плодить оверхед, иначе можно было бы обойтись и одним типом. А в Си действительно неважно. В С нет стандартных контейнеров в принципе. Есть Glist, например. Сможешь показать свой пример, как ты его создаешь поверх пула, а потом безопасно отдаешь в другое место? Конечно не сможешь. Итого у меня есть рабочий код, который делает, что мне надо и как надо, а у тебя нет ничего.

anonymous
()
Ответ на: комментарий от anonymous

Подход С++ не плодить оверхед

Выше приведен пример оверхеда.

Есть Glist, например. Сможешь показать свой пример, как ты его создаешь поверх пула, а потом безопасно отдаешь в другое место? Конечно не сможешь.

А ты уже не смог.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Выше приведен пример оверхеда.

Где именно?

А ты уже не смог.

Легко:

#include <list>
#include "myalloc.hpp"
using namespace std;

typedef list<int, myalloc<int>> my_list;

template<typename T>
void add_1( T& l )
{
    l.push_back( 1 );
}

void remove_1( my_list& l )
{
   l.remove( 1 );
}

int main()
{
    my_list l;
    add_1( l );
    l.push_back( 2 );
    add_1( l );
 
    remove_1( l );
}

Взял и передал. Можешь начинать рассказывать про недостатки, что где-то голодные дети в Африке ожидают почему-то именно list<int>, а не my_list. Ведь никто и никогда не использует свои типы внутри проекта, только стандартные.

Итого у меня 2 из 2, а у тебя 0 из 2.

anonymous
()
Ответ на: комментарий от anonymous

ведь никто и никогда не использует свои типы внутри проекта, только стандартные.

Наоборот же - все и везде используют свои типы и никогда - стандартные.

Итого у меня 2 из 2, а у тебя 0 из 2.

Ты соревнуешься со своим воображением.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Наоборот же - все и везде используют свои типы и никогда - стандартные.

Ну вот видишь, ты сам признал странность своего желания.

Ты соревнуешься со своим воображением.

Ну ты же в принципе не можешь код предоставить, т.к. задача не решается на голом libc и glib, потому - да.

anonymous
()
Ответ на: комментарий от anonymous

ты сам признал странность своего желания.

Твое воображение снова тебя обмануло.

Ну ты же в принципе не можешь код предоставить, т.к. задача не решается на голом libc и glib, потому - да.

Мне безразлично, какие проблемы у GList. Ты с ним воюешь, но я его не защищаю.

tailgunner ★★★★★
()

Годный вброс ;-)

Почитай Таненбаума «Современные ОС».

Еще пример ОС, которую давали в качестве образца для ознакомления на Яндекс.КИТ — http://pdos.csail.mit.edu/6.828/2012/xv6.html

Twissel ★★★★★
()
Ответ на: комментарий от tailgunner

Твое воображение снова тебя обмануло.

Зачем сразу воображение, я пользовался исключительно твоими словами, что свои типы - это нормально. list<int> в этом плане ничего не лучше list<int> с аллокатором, как и не лучше list<char> или иного другого типа.

Мне безразлично, какие проблемы у GList. Ты с ним воюешь, но я его не защищаю.

Отлично, безразлично, так безразлично.

anonymous
()
Ответ на: комментарий от tailgunner

Почитай хоть какой-нибудь учебник по ОС.

Какой бы вы могли посоветовать? Желательно современных ОС, а не говна мамонта.

anonymous
()
Ответ на: комментарий от Dulze

другое ядро с использованием поддержки железа от линукса?

что еще за железо от линукса?

по теме: на чистом си ядро не написано, оно использует некоторые спецефичные для платформы вещи, например запись и чтение портов ввода вывода, управление прерываниями, инициализация защищенного режима работы процессора (в случае x86) все это пишется на ассемблере под конкретную архитектуру, более высокоуровневые вещи: управление процессами (не низкоуровневая часть - сохранение регистров, переключение страниц ит.п. это снова ассемблер) пиши на чем угодно, файловая система на чем угодно (не работа с диском, это снова порты ввода вывода и прерывания, следовательно ассемблер), работа с сетью (работает по портам ввода и вывода и прерываниям, следовательно снова ассемблер), стек tcp/ip и т.п. пиши на чем угодно. Переключение из простанства пользователя в пространство ядра (когда библиотека си сделала свою работу и осталось сделать свою работу ядру) тоже на ассемблере, в общем бери книгу Таненбаум «современные операционные системы» и прочитай хотябы порехностно, будешь иметь представление. И если яснее выражать свои собственные мысли, то все становится на свои места в голове и никакого «железа от линукс» не будет

IvanR ★★★
()
Ответ на: комментарий от anonymous

Затем, что оно помешало тебе увидеть иронию.

А вот это уже твое воображение ;)

okay.jpg

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Почитай хоть какой-нибудь учебник по ОС.

Какой бы вы могли посоветовать? Желательно современных ОС, а не говна мамонта.

Я учился слишком давно, чтобы советовать современные учебники, но, полагаю, Танненбаума хватит всем (хотя Вахалия в некотором смысле даже лучше). Правда, Гугл на «OS textbook» выдает это - наверное, тоже хорошая книжка - профессора Йеля, 8 изданий, все дела.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)

Я тут подумал, C и Rust без проблем взаимодействуют друг с другом, значит переписываем стандартную библиотеку C на Rust и никаких ошибок 2000-ого года. Что скажете?

Dulze
() автор топика
Ответ на: комментарий от Dulze

вперед. пиши, выкладывай на гитхаб/гитлаб/кудато еще, а там может и еще желающие подтянутся. даже если никто им не будет пользоваться, хотя бы опыт какой-то получишь.

CryAngel
()
Ответ на: комментарий от Dulze

значит переписываем стандартную библиотеку C на Rust

Ты понимаешь, что это полная ересь переписывать стандартную библиотеку _С_ на не С? В том числе потому, что большая часть этой библиотеки в том или ином виде содержится в хедерах с массой гнутых атрибутов, макросов, условной компиляции, заинлайненого кода и т.п. Единственное, что можно написать альтернативную стандартную библиотеку не для С, а для ОС вообще, причем без оглядки на С.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.