Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> vm86 
:(
    Опции темы
wladF
Дата 6.11.2010, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 2.6.2009

Репутация: нет
Всего: нет



Привет, есть задача исполнить 16 битный код, прерывания биоса и т.п. в Линуксе.
Получится ли правильно слинковать 32-битный код гцц с 16-битной реализацией асмвоской ф-и, которая будет находиться в отдельном файле ?
Т.е. имеем следующее
Код

.code16
.section .text
.globl int10h
.type int10h, @function
.align 16
int10h:
    xor %ax, %ax
    int $0x10
...

и C файл, в котором ф-я int10h используется вызовом vm86
сборка:
gcc main.c main.s
PM MAIL   Вверх
bsa
Дата 12.11.2010, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 16
Всего: 196



wladF, даже если и получится слинковать, работать все равно не будет. Так как операция int вызовет исключение общей защиты, что будет отработано ядром и послан сигнал SIGSEGV твоей проге.
Если хочешь запускать подобный код используй dosbox. Нативно в современных ОС это делать нельзя.
PM   Вверх
wladF
Дата 13.11.2010, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 2.6.2009

Репутация: нет
Всего: нет



Т.е. прерывания не получится использовать в режиме эмуляции 8086? для которого существует сис. вызов vm86.

Это сообщение отредактировал(а) wladF - 13.11.2010, 12:46
PM MAIL   Вверх
bsa
Дата 13.11.2010, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 16
Всего: 196



Код
#include <stdio.h>        // for printf(), perror() 
#include <fcntl.h>        // for open() 
#include <stdlib.h>        // for exit() 
#include <unistd.h>        // for lseek(), read() 
#include <sys/mman.h>        // for mmap()
#include <asm/vm86.h>        // for struct vm86_struct
#include <linux/linkage.h>    // for asmlinkage attribute

#define ELF_LOAD_ADDRESS 0x08048000    // where Linux puts this 

asmlinkage void blue( void );        // no C++ "name-mangling"   
asm("    .code16            ");    // generate 16-bit codes
asm("    .align    16        ");    // "paragraph" alignment
asm("blue:            ");    // label procedure entry
asm("    movw    $0xB800, %ax    ");    // address screen memory
asm("    movw    %ax, %es    ");    //   using ES register
asm("    xorw    %di, %di    ");    // point es:di to screen
asm("    movb    $0x17, %al    ");    // white-upon-blue color
asm("    movw    $0x4000, %cx    ");    // number of screen elts 
asm("nxpel:            ");    // main loop begins here
asm("    movb    %al, %es:1(%di)    ");    // write color attribute
asm("    addw    $2, %di        ");    // point to next element
asm("    loop    nxpel        ");    // process entire screen
asm("    hlt            ");    // exit Virtual8086 mode   
asm("    .code32            ");    // generate 32-bit codes

int vm86( struct vm86_struct *vm )
{
    int    retval;
    asm(" movl $113, %eax ");    // system-call ID-number
    asm(" movl %0, %%ebx " : : "m" (vm) );    // struct address
    asm(" int $0x80    ");        // enter the Linux kernel
    asm(" movl %%eax, %0 " : "=m" (retval) ); // store retval 
    return    retval;            // return function status
}


struct vm86_struct    vm;        // virtual machine struct


int main( int argc, char **argv )
{
    int    fd, prot, flag;
    
    // setup a memory-mapping for accessing video display memory    
    void    *vram = (void*)0x000B8000;   // address of 32KB window
    prot = PROT_READ | PROT_WRITE;    // read-write access is needed
       flag = MAP_FIXED | MAP_SHARED;    // with a fixed-shared mapping 
    if ( ( fd = open( "/dev/mem", O_RDWR ) ) < 0 )
        { perror( "open /dev/mem" ); exit(1); }
    if ( mmap( vram, 0x8000, prot, flag, fd, (int)vram ) == MAP_FAILED )    
        { perror( "mmap /dev/mem" ); exit(1); }

    // setup 64KB memory-mapping for access to VM86 code and stack    
    void    *prog = (void*)0x00010000;   // address of 64KB region
    prot = PROT_READ | PROT_WRITE;    // read-write access is needed
       flag = MAP_FIXED | MAP_SHARED;    // with a fixed-shared mapping 
    if ( ( fd = open( "/dev/zero", O_RDWR ) ) < 0 )
        { perror( "open /dev/zero" ); exit(1); }
    if ( mmap( prog, 0x10000, prot, flag, fd, 0 ) == MAP_FAILED )    
        { perror( "mmap /dev/zero" ); exit(1); }

    // now "load" our program code into this memory-mapped region  
    if ( ( fd = open( argv[0], O_RDONLY ) ) < 0 ) 
        { perror( argv[0] ); exit(1); }
    int    progsize = lseek( fd, 0, SEEK_END );
    if ( lseek( fd, 0, SEEK_SET ) != 0 ) { perror( "lseek" ); exit(1); }
    if ( read( fd, prog, progsize ) != progsize ) 
        { perror( "read" ); exit(1); }
    
    // compute offset-address for the 16-bit code's entry-point
    int    initial_IP = (int)blue - ELF_LOAD_ADDRESS;
    int    initial_CS = ((int)prog) >> 4;    // segment-address
    
    // initialize data-structure for entering to Virtual-8086 Mode
    vm.regs.eip = initial_IP;    // initial instruction offset 
    vm.regs.cs = initial_CS;    // segment-address for code
    vm.regs.eflags = (1<<9);    // IF=1, IOPL=0
    vm.regs.ss = initial_CS;    // segment-address for stack
    vm.regs.esp = 0x10000;        // initial stacktop offset
    vm.cpu_type = CPU_386;        // specify required processor

    // execute in Virtual-8086 Mode (until 'hlt' is encountered)
    vm86( &vm );            // execute the 'blue' routine    
    printf( "\nReturned successfully from Virtual-8086 Mode\n\n" );
}
Код взят отсюда: http://www.linux.org.ru/forum/development/...comment-1517991
Человек говорит, что программа в любом случае завершается сегфолтом.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0442 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.