запустил шелл, предварительно удалив из него сканф и кучу другой фигни. работает, но почемуто не пишет подказку sh#.
Что-то с флушем наверное.
Знаешь.. Мне кажется, что твоя ненависть к инверсии бит - это уже проблема более медецины, чем техники:)
Да. Вот.
Инструкция:
1. Взять флешь и создать ДВА раздела.
- Раздел 1 основной - FAT32.
- Раздел 2 основной - Linux. Обязательно НЕ-FAT32!
2. Скопировать ядро и загрузчик на раздел 1 (fusix-boot.$C fuzix.bin)
3. Залить на раздел 2 ФС FUZIX. Например, если флешка - устройство /dev/sdb, то делаем это так:
sudo dd if=fuzix.img of=/dev/sdb2 bs=512
Все.
Далее втыкаем флешь во пентеву и запускаем fusix-boot.$C
Жмём:
bootdev: 0
login:root
ssh# printenv (это пример, печатает переменные окружения)
многие команды ещё не работают (типа ls)
Цитата:
Команды, которые уже есть:
basename cat chmod cp date du false init ll mkdir more od printenv pwd rmdir ssh sync tr uue which
bd chgrp chown cut dirname echo id kill ln mknod mv patchcpm prtroot rm sleep su touch true wc whoami
Короче - надо разработать модульные драйвера. Иначе памяти не будет.
Просто у меня есть полный драйвер PS2 клавы. С поддержкой режимов и раскладок. но там таблиц много. Только отдельная страница спасёт.
Затаив дыхание слежу за темой. Но до конца пока не могу понять, сможет оно в итоге полноценно взлететь на стандартной конфигурации (128k+TR-DOS) или нет?
Это ж С. Там "Hello world" компилируется в несколько килобайт (если без шаманства). Поэтому для стандартного 128к оно хотя и будет, но с окном 16к (с ограничением 16к на процесс) - это не жизнь. На клонах с окном 48к..64к оно уже может быть полноценной ОС (одним окном или несколько окон по 16к - не суть), где портируя код с "больших систем" не надо будет выкидывать все printf и scanf.
Саму инфраструктуру разрабатывать гемор, конечно. Но для единичного случая же все очень просто-
Перемещаешь devtty куда-нибудь ниже #C000.
Выкидываешь весь код опроса спектрумской клавы, пишешь переключение банки и вызываешь свой.
...
Профит!
---------- Post added at 14:10 ---------- Previous post was at 14:09 ----------
Видится реальным выкинуть либу в отдельную страницу(-цы).
Что-то типа shared lib с поздним связыванием?
Или либа-wrapper с функциями-пустышками, единственная цель которых сделать вызов в другую страницу странслировав туда параметры, а оттуда - код завершения. Можно, накладные расходы правда будут как на переключение, так и на обслуживание указателей на массив оставшийся в странице процесса (для тогоже sscanf), но не такие критичные в сравнении с тормозными п\п вывода на экран.
Если получится, то это будет полезно и для реализаций с 48..64к страницами.
Никого не смущает, что обработка прерывания сейчас занимает примерно 30% процессорного времени? Если забить ret по адресу 38h, система начинает работать гораздо шустрее :)
Я к тому, что надо бы как-то оптимизировать это. Хотя бы клаву. Сделать процедуру опроса порта клавиатуры на асме (чтение 8 байт и сравнение с предыдущим состоянием), а если уж что-то изменилось, то запускать сишную процедуру опроса.
---------- Post added at 18:40 ---------- Previous post was at 18:35 ----------
У меня сложилось впечатление, что кто-то где-то портит случайные байты. По крайней мере я уже не первый раз замечаю изменение сегмента кода в процессе работы init. Отследить это у меня не получается, сегмент пересекается с сегментом данных ядра, простая ловушка на запись в память мало помогает.
да там ещё сырое всё как пиндрец
ой. я не тот загрузчик залил. нужен fuzix-boot-sd
---------- Post added at 22:58 ---------- Previous post was at 22:27 ----------
Перезалил http://zx-pk.ru/showpost.php?p=757566&postcount=243
Я считаю, это просто издевательство :)
Рожицу я не добавлял, оно само. Это символ с кодом 01, который и пишется чаще всего по случайному адресу.
Бывает, если случайно записываемый символ попадёт в процедуру разбора строки из passwd. Запусти заново, иногда этот символ попадает в некритичную область, тогда выглядит так, как будто всё работает.
мда. глюков там ещё мульён. у меня тоже иногда не пускает..
а ещё - не всегда читает корректно с флешки.
писать пока толком не пишет никак
А у меня вылазит хрень в аттрибутах, если во время скролла активно жать клаву. Пытаюсь побороть.
отсюда - https://plus.google.com/+AlanCoxLinux/posts/MtXvM1WUDPEЦитата:
Сообщение от Alan Cox
Планы жесть, конечно :)
Ребята извращаются)
48к со свапом... ААААААААААААААААААААААААА ААААААААААААААААА!!!!!
Муторное это дело: либы пилить. Муторно потом и тестить, а надо.
Потому предлагаю пересобирать FUSIX по мере поступления переписанных функций - так можно оперативней выявлять ошибки (а они будут).
Eltaron, SfS, не поленитесь, парни!
Вот fputc, уменьшил на 114 байт (195 против 309).
Код:/* z80 rewriting by Amixgris/RT 19-11-2014, Russia */
#include "stdio-l.h"
int fputc(int ch, FILE * fp) __naked
{ ch, fp;
__asm
pop af
pop de ; ch
pop bc ; fp
push bc
push de
push af
ld (2$),de ; save ch
ld hl,#0x000c ; fp->mode
call 3$
ld (1$),hl
and a,#0x40 ; & __MODE_READING ???
jr z,00102$
push bc
push bc
call _fflush
pop af
pop bc
ld a,h
or a,l
jr z,00102$
;fputc.c:10: return EOF;
00152$:
ld hl,#0xFFFF
ret
00102$:
ld a,h
and a,#0x03
jr NZ,00152$ ; lower byte <> 0
ld a,l
and a,#0x020
jr NZ,00152$
00105$:
ex de,hl
ld hl,#0x0008 ; deflate = bufend
call 3$
ex de,hl
ld h,b ; deflate = bufpos
ld l,c
call 3$
or a,a
sbc hl,de
jr c,00107$
push bc
push bc
call _fflush
pop af
pop bc
ld a,h
or a,l
jr NZ,00152$
00107$:
;fputc.c:18: *(fp->bufpos++) = ch;
ld h,b ; deflate = bufpos
ld l,c
call 3$
ld a,(2$)
ld (hl),a ; write out ch
inc hl
ld d,b
ld e,c
ex de,hl
ld (hl),e
inc hl
ld (hl),d
;fputc.c:19: fp->mode |= __MODE_WRITING;
ld hl,#1$
set 7,(hl)
;fputc.c:22: if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF)) && fflush(fp))
inc hl
inc hl
ld a,#0x0a
cp (hl)
jr NZ,00112$
inc hl
xor a,a
cp (hl)
jr NZ,00112$
dec hl
dec hl
bit 0,(hl)
jr NZ,00113$
00112$:
bit 1,(hl)
jr Z,00110$
00113$:
push bc
push bc
call _fflush
pop af
pop bc
ld a,h
or a,l
jr NZ,00152$ ; exit eof
00110$:
;fputc.c:26: fp->bufwrite = fp->bufstart; /* Nope */
ld hl,#0x0004
add hl,bc
ex de,hl
;fputc.c:25: if (v & (__MODE_IOTRAN | _IOLBF | _IONBF))
ld a,(1$)
and a, #0x03
jr Z,00115$
ld hl,#0x0006
jr 00116$
00115$:
;fputc.c:28: fp->bufwrite = fp->bufend; /* Yup */
ld hl,#0x0008
00116$:
;fputc.c:30: return (unsigned char) ch;
add hl, bc
ldi
ldi
ld hl,(2$)
ld h,#0x00
ret
1$: .dw 0
2$: .dw 0
; in: hl = struct member deflate
; de = struct base
; out: hl = member content
3$: add hl,bc
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
ret
__endasm;
}
Можешь зайти сюда.
https://github.com/salextpuru/FUZIX
Склонировать всё. И сам добавить что надо. Пропатчены либы для того чтобы с long-long работать и SDCC-3.4.0
Чё печалиться, когда можно просто самому попробовать? :)
---------- Post added at 21:23 ---------- Previous post was at 19:44 ----------
Eltaron, а утебя чтение-запись с диска не глючат? Не знаю - то ли драйвер кривоват то ли что.
Загружается шелл через раз. Иногда почемуто пишет "login incorrect".
или это может драйвер tty?
Кажется я нашёл, почему. В библиотеке crt.s весьма странно запускает процедуру main. Нафига подменять адрес возврата, да ещё выше аргументов - непонятно. Я сделал стандартно:
Тут кстати видно, что из стека достаётся адрес переменных среды, однако в syscall_exec.c для нового процесса в стек кладётся только argc,argv. Я добавил ещё и их:Код:pop hl ; environ
ld (_environ), hl
call _main
jp _exit
После этих изменений логин у меня работает как и задумывалось.Код:// Shove argc and the address of argv just below envp
uputw((uint16_t) nargv, nenvp - 1);
uputw((uint16_t) argc, nenvp - 2);
uputw((uint16_t) nenvp, nenvp - 3);
// Set stack pointer for the program
udata.u_isp = nenvp - 3;
---------- Post added at 20:41 ---------- Previous post was at 20:38 ----------
Вот только рожица всё ещё появляется :) А если не появляется - всё опять рушится...
---------- Post added at 21:13 ---------- Previous post was at 20:41 ----------
Можно и не менять syscall_exec.c, только адрес переменных вот так считать:
Код:ld hl, #4 ; environ
add hl,sp
ld (_environ), hl
call _main
jp _exit
Спасибо. А ты на гитхабе есть? может закоммитишь это все туда?
На гитхаб я пока не пойду :)
---------- Post added at 21:43 ---------- Previous post was at 21:42 ----------
Вот интересно, в библиотеке есть putenv.c и setenv.c, обе хранят в статической переменной (каждая в своей) предыдущий выделенный блок памяти. И как это работает?
у меня этот вариант и есть. хренатотам.. через раз пускается(
---------- Post added at 22:57 ---------- Previous post was at 22:55 ----------
кстати, третьим параметром в main() в твоём варианте envp не передать..
---------- Post added at 23:01 ---------- Previous post was at 22:57 ----------
лучше так:
тогда main( int argc, char* argv[], env** env); можно писать.Цитата:
ld hl, #6
add hl, sp
ld (_environ), hl
ld hl, #_exit ; return vector
push hl
jp _main ; go
---------- Post added at 23:44 ---------- Previous post was at 23:01 ----------
если у тебя всё работает и не глючит - дай исходники, коли не жалко. я просто сравню какие файлы у меня менялись. и окончательно решу - где собака зарыта.
Не взлетит. В environ попадут не те данные.
И потом, что за хрень с адресом возврата, чем тебе не нравится call _main / jp _exit?
Никак не могу поймать, кто пишет 01 по случайному адресу. Проблема с login-ом чаще всего из-за этого.
---------- Post added at 00:23 ---------- Previous post was at 00:17 ----------
Я думал, это из-за неправильной environ, но сейчас там правильный адрес, но всё равно глючит.
Кстати, putenv не дублирует входящую строку, эта процедура лишь накапливает адреса, смысла передавать туда локальный buf нет никакого.
---------- Post added at 00:33 ---------- Previous post was at 00:23 ----------
Ого, поставил бряк на начало программы, и записал в файл, что загрузилось. Сравнил с оригинальным init - 7 байт забиты числом 01! Стоят достаточно далеко друг от друга. Т.е. загрузка файла глючит! Понятно теперь, почему иногда рожица выскакивает в сообщении из issue :)
---------- Post added at 00:39 ---------- Previous post was at 00:33 ----------
Отключил прерывания - работает идеально. Надо копать прерывания в момент загрузки файла.
---------- Post added at 00:41 ---------- Previous post was at 00:39 ----------
Нахрена козе баян. envp сохраняется во вполне доступной статической переменной environ.
Кто, понятно - обработчик прерывания. Непонятно, каким образом это ему удаётся, что никто не видит :)
Я и раньше пробовал отключать прерывания, но всё равно глючило. Но это было из-за неправильного адреса переменных среды. А теперь, если прерывания отключить, то загруженный init в точности совпадает с оригиналом.
Да, спасибо за наводку, разобрался.
Глючат функции переключения банок - map_*. В паре мест там есть вероятность, что если в процессе работы произойдет прерывание, то предыдущее (временно сохраненное) значение аккумулятора пропадет. А т.к. эти функции дергаются кучу раз в цикле, то вероятность крайне велика.
Можно добавить DI везде в начале всех map_*. А можно более радикально - я переписал всё обратно на использование стека. Делал на переменных с тем, чтобы однажды перекинуть UDATA в банкуемую область, но ну нафиг, хоть бы сначала то, что есть, отладить :)
Сейчас логин всегда проходит и шелл всегда стартует. Но при попытке что-нибудь запустить всё гарантированно виснет. Надо дальше ковырять.
Кажется я понял, как всё глючит.
Глюк происходит внутри цикла __uput. В теории, прерывания в этот момент должны быть запрещены, но switch_bank подло разрешает их перед возвратом. В итоге, если прерывания возникает между ld (place_for_a),a в map_process_always и запрещением прерывания в switch_bank, то place_for_a портится несколько раз, и в конце концов вызовом map_restore. К этому моменту в регистре А находится флаг _kernel_flag, равный еденице.
Короче, надо switch_bank фиксить, как там в комментарии сказано.
---------- Post added at 15:30 ---------- Previous post was at 15:29 ----------
Опоздал :)