Народ, подскажите, как и какой C-компилятор можно отвязать от генерации файлов PE/ELF форматов и сделать так, чтоб он генерировал чистый BIN-код. Мне нужно перевести процессор в защищенный режим (это я делаю с помощью asm) и уже в PM выводить картинки (VBE), обрабатывать мышь, клавиатуру и т. п. Вот эти последние пункты и хотелось бы сделать на С. И если можно, объясните, как указать этому компилятору, где какие селекторы, с каких смещений начинать.. Сама программа загружается при старте машины в 0x7c00, организует PM-сегменты, переводит проц в PM... а дальше хотелось бы С использовать.. Только как? И еще, сильно ли усложнится использование этого компилятора, если включить страничный режим? Всем спасибо
>Народ, подскажите, как и какой C-компилятор можно отвязать от генерации файлов >PE/ELF форматов и сделать так, чтоб он генерировал чистый BIN-код. несовсем понял но как вариант можно сделать модель памяти СМОЛЛ и конвернтуть потом в .com >Мне нужно перевести процессор в защищенный режим (это я делаю с помощью asm) и >уже в PM выводить картинки (VBE), обрабатывать мышь, клавиатуру и т. п. Вот эти >последние пункты и хотелось бы сделать на С. юзайте watcom C++ он уже в PM моде >И если можно, объясните, как указать этому компилятору, где какие селекторы, с каких >смещений начинать.. >Сама программа загружается при старте машины в 0x7c00, организует PM-сегменты, >переводит проц в PM... а дальше хотелось бы С использовать.. Только как? отдельно писать стаб и линковать дальше то что на С с тем что на asm токо модели памяти что бы сошлись ну или потом выравнивать >И еще, сильно ли усложнится использование этого компилятора, если включить >страничный режим? юзайте watcom уже и в страничном вообще я там и непонял какая цель всего этого потому что все что я ответил может оказаться чушью
Cтроничная одрисация ни чуть не влияет на компилятор. Разве только код услодниться понадобить эту самую страничную адресацию обслуживать. Зачем BIN? ELF и PE очень простые форматы, как помне проще загрузить PE чем мучиться с бинарником. watcom C++ и GNU C позволяют собрать любой Формат. Изучай опции компилятора и линкера. И их особенности.
simnet_ непонял причем тут компилятор. Оконечный файл делает линкер. MS, OW вам подойдут. Что и как читаем хелп + эксперименты. Вы имхо лепите что-то вроде своей оси. Посему вопросы не компилера и не линкера, а ваши. и очень не простые. компилятор ничего не знает ни о каких таких режимах. всем пожалуйста
Спасибо за ответы. Немного ситуация прояснилась, но.. Да, что-то вроде простейшей ОС Эти вопросы я уже решил. Осталось линкеру/компилятору объяснить, чего я хочу. На asm'е это написать могу, а вот как связать с high level не могу понять, хоть убейте... Я себе процесс написания представляю так: в первые пару секторов записываю оттранслированный fasm'ом двоичный код загрузчика ядра, который также содержит и базовые элементы инициализации системы - то есть выделяет, как уже писал, сегменты, заполняет таблицы IDT, GDT, и передает управление на Сишный оттранслированный код. Кажется, в таком случае связи между Си и asm'ом не требуется, кроме как знания адресов, где код С будет размещать свои переменные, код своих функций.. Ассемблер позволяет явно указать эти адреса. А вот С... Как вы писали, это задача линкера. Но как ему это объяснить, что данные находятся в третьем GDTE с лимитом FFFF, а данные - во втором? Я догадываюсь, что в оттранслированном С-шном модуле содержаться только относительные смещения, а реальные адреса корректирует загрузчик исполняемых файлов. Но.. Как Торвальдс писал ядро своей системы? Вроде, он же тоже в основном использовал С? Трудно поверить, что он писал нечто вроде COFF Loader'ов. Прошу прощения за подобные вопросы. Я б и сам себя послал на ... RTFM, но времени совсем нет. Хотя с удовольствием бы почитал многотомные доки по формату PE, теории операционных систем, принципу работы линкеров и т. п. Если б программирование на asm'е не было таким трудоемким... За С бы и не брался Может хотя бы статью подскажите? Или пример, как эти директивы указывать? Еще раз спасибо за то, что дочитали пост
почему трудно? Когда-то писал. Только не COFF, а ELF. Сейчас правда лоадер ядра уже не включается в код ядра, но когда-то он там был. Я такой вывод делаю глядя на arch/x86/boot/header.S, там есть такие строки: Код (Text): #... .code16 .section ".bstext", "ax" .global bootsect_start bootsect_start: # Normalize the start address ljmp $BOOTSEG, $start2 start2: movw %cs, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss xorw %sp, %sp sti cld movw $bugger_off_msg, %si msg_loop: lodsb andb %al, %al jz bs_die movb $0xe, %ah movw $7, %bx int $0x10 jmp msg_loop bs_die: # Allow the user to press a key, then reboot xorw %ax, %ax int $0x16 int $0x19 # int 0x19 should never return. In case it does anyway, # invoke the BIOS reset code... ljmp $0xf000,$0xfff0 .section ".bsdata", "a" bugger_off_msg: .ascii "Direct booting from floppy is no longer supported.\r\n" .ascii "Please use a boot loader program instead.\r\n" .ascii "\n" .ascii "Remove disk and press any key to reboot . . .\r\n" .byte 0 #...
зачем тебе это знать? все очень просто: в бутсекторе лежит асмовый код,который грузит вторую часть с диска. асмовый загрузчик считывает в память ядро (написанное на си), переходит в защищенный режим, включает страничную трансляцию и проецирует считанное ядро и передает ему управление. ядро представляет собой PE EXE, скомпилированный из сишных исходников. оно продолжает инициализацию. про код и функции тебе не надо знать НИЧЕГО. ты грузить ядро согласно таблице секций PE EXE и передаешь управление на AddressOfEntryPoint у меня сделано так (я щас пишу некое подобие полноценной ОС чисто ради опыта) и почти так с некоторыми отличиями сделано в Windows
Спасибо, так и представлял себе загрузку.. Но есть еще несколько вопросов Как быть с libc? С прологами/эпилогами? Это все можно/нужно как-то отключить? Насколько мне известно, их добавляет компоновщик Компилятор должен быть 32-разрядный, наподобие viual studio'вского cl и его же линкера link.exe, верно? Но ведь они привязывают код к функциям ОС.. То же самое и с досовскими 16-битными - к функциям in 0x21 и BIOS'а. Но ведь у меня защищенный режим уже включен. Какой вы здесь видели выход? Не использовать кучу С-шных функций? Или можно как-то явно указать в параметрах линкера эти ограничения? P.S., Если не трудно, подскажите, каким образом можно читать файлы/сектора в PM? Ведь при загрузке ядра можно считать только 1Мб из-за RM..
а как ты без них ядро писать собрался? я не знаю какой у тебя компилятор что к чему привязывает, наверное мы говорим о разных вещах. с чем ты задашь линковать - к тому и будет привязывать, будь то windows или linux или твоя собственная ОС. простите, но С это синтаксис и никаких функций в нем нет. ну щас могут вылезти некоторые умные товарищи и начать тыкать носом в стандарт, но это не суть важно - я хочу сказать то, что реализация CRT платформозависима, в то время как сам язык - нет. для твой собственной ОС придется писать свою CRT. конечно, реализация sprintf и atoi вряд ли будет отличаться, но fopen или system уже будут зависеть от функций ввода-вывода ТВОЕЙ ОС. прямой дисковый ввод-вывод через порты. учимся программировать стандартные контроллеры FDC и жесткого диска =) по стандартному IDE контроллеру есть дока на васме, по Floppy Disk Controller можно легко нагуглить (я так сделал), а так же можно посмотреть исходники linux-1.0, там много интересного на эту тему и не только
Ну, я считал, что настройка SEH и информация о версии компилятор в ядре не обязательны.. Привязывать мне ни к чему не нужно. Нужен "голый" PE, без "лишней" информации и без каких бы то ни было ссылок. Это даже не ОС, а некое подобие ее.. Это PE - и будет всей ОС (если не считать загрузчик). Как я понял из вашей реплики, компилятор и линкер можно брать почти любой - нужно только правильно указать параметры для генерации PE. А вот что именно? Какой вы использовали? Какие параметры указывали? И верхом наглости было бы просить пример вывода Hello world на C в PM. Или хотя бы ссылку на статью. Никак не могу понять, как проецировать эти секции PE на подготовленные загрузчиком страницы.. Там же нужно как-то адреса корретировать, в PE, насколько я помню, записаны только относительные смещения.. Надеюсь этот вопрос последний. В любом случае спасибо
simnet_ Читайти спецификации. Вы не понимаете что такое сегметы, что такое страничная адресация, что такое линейный адресс. И с чем работает программа. Есть линейный адресс 4Гб есть таблица страниц которая производит сопоставление физичсеких адрессов с линеным. Есть GDT,LDT - таблица сегментов. Сегментная адресация - это лагический адресация. Сегмент задается как база(линейный адресс) и лимит Cи код работает с 3 сегментами, может и больше. Но сейчас все расчитано на то что есть сегмен кода, сегмент данных, сегмент стека. Так вот все адресса и обращения к коду и данным задаются через сегмет т.е ввиде смещение от базы сегмента. Так что сишному коду всеравно что ты там накрутишь с GDT и страничной адресацией. Главное соблюсти ряд правел. От ASM кода требуется только следующее вещи: - перейти в защищенный режим - проинициировать сегментые регистры. - загрузить Си код в память - заполнить нулями секцию не инициированных данных если такая имеется - передать управление на точку входа. - передать служебную информацию если нужно Обычно этим занимается линкер. После линковки нужные адресса раставленны. Есть еще таблица релоков которая позволяет подправить эти адресса, тем самым переместить код. Да можно есть ключик отключить системные библиотеки. Писать свои функции =) Это решает програмист что использовать что не использовать. Есть еще режим FlatMode(BIG Mem) - Реальный режим со снятыми ограничениями на сегметы так что доступны все 4ГБ и прерывания реального режима. Есть еще виртуальный режим. А вообще надо писать свои драйвера. Разумеется все чтение и запись секторов идет через порты.
На asm'е пока получалось использовать все эти режимы. Ну, по крайнер мере, на уровне статей о PM на wasm'е ориентируюсь.. Кажется Вы о С? Да, с этим проблемы Вы, наверное, хотели сказать, секции? Или именно сегменты, те самые, которые во flat-защищенке накладываются друг на друга (база 0, лимит 4 Гб)? Большое спасибо за расписывание по пунктам. Вот только с загрузкой С кода в память... Нельзя же брать PE-файл и грузить его посекторно в ОЗУ (кстати, куда именно? Эта инфорация есть в PE-заголовке?) Так ведь? Или, наоборот, нужно? И какое минимальное число страниц нужно описывать в таблицах страниц? Судя по тому, что адреса расставляет линкер, то ровно столько, чтоб они покрыли 4 Гб памяти? Не скажете, какой именно?
Нет, секции тут не при чем. Речь про сегменты. Читай про работу процессора в защищенном режиме. Можно... главное секции правильно расставить. А если собрать такой бинарник, чтобы RVA Секции и VA совпадали (как я у себя и сделал), то вообще шикарно. Достаточно просто прочитать файл в память по нужному виртуальному адресу (IMAGE_OPTIONAL_HEADER::IMageBase) и передать управление на AddressOfEntryPoint У всех компиляторов по-разному. У мс это /NODEFAULTLIB Microsoft Visual Studio 2008. Генерит вполне нормальное ядро, мне нравится. Ключик я уже сказал - /NODEFAULTLIB для отключения лишних библиотек. Ну + еще ключики некоторые чтобы навести порядок
simnet_ Есть там информация о расположении секций. Столько чтобы все секции были загруженны в память. Плюс нужные для системных нужд. Можешь и больше. А остальные страницы уже по требованию будешь выделять. Ты вначале с компилятором определись.
Юношеский максимализм Только так и никак иначе. Релоцировать ядро при загрузке это изврат, чтобы там не говорили о пользе такого подхода для большей гибкости системы. Загрузить бинарник проще, сделать бинарник из того же PE при правильной настройке секций тоже несложно. Мое мнение, что ELF- или PE-файл обладает избыточной информацией при использовании в качестве файла ядра.
Добрый день. Я где-то 5 месяцев назад столкнулся с примерно с такими же проблемами, главной из которых, всё-таки, являлась проблема поиска границы между асмемблером и C. Также была необходимость полного контроля генерируемого компилятором C кода, поэтому в рамках научной работы в универе сделал компилятор С. В нем пока что не реализованы те процессорные инструкции, которые требуются для работы в защищенном режиме со страничной адресацией. Тем не менее есть возможность задать точку генерирования программы (например 7С00). Ну и главное теперь более-менее ясно, как что устроено в компиляторах Си.. Также нет никаких идеологических и лицензионных привязок, которые возникают при работе с продуктами GNU. У них есть подобные разработки, в том числе и для генерации сырого бинарного кода из под компилятора C. Но лично я особо не поддерживаю тех идей, на которых строится Open Source. Здесь вы можете скачать результат работы (компилятор, примеры и статья на английском). http://ifolder.ru/6860291 Если у вас появятся вопросы, критика, предложения, буду рад общению. с уважением, Шарипов Наиль, МГТУ им. Баумана